Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Comment: | Initial commit of ScintillaTk The code here includes Scintilla 3.3.0 |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | descendants | trunk |
Files: | files | file ages | folders |
SHA1: | e150c20c6070c71cdf577a0fcd86ded04589262d |
User & Date: | devnull@localhost 2013-06-27 02:24:49 |
2013-09-16
| ||
01:56 | Initial check-in is version 0.26 check-in: f646ef686b user: briang42@easystreet.net tags: trunk | |
2013-06-27
| ||
02:24 | Initial commit of ScintillaTk The code here includes Scintilla 3.3.0 check-in: e150c20c60 user: devnull@localhost tags: trunk | |
Added License.txt.
> > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
License for Scintilla and SciTE Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
Added README.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
README for building of Scintilla and SciTE Scintilla can be built by itself. To build SciTE, Scintilla must first be built. *** GTK+/Linux version *** You must first have GTK+ 2.0 or later and GCC (4.1 or better) installed. GTK+ 1.x will not work. Other C++ compilers may work but may require tweaking the make file. To build Scintilla, use the makefile located in the scintilla/gtk directory cd scintilla/gtk make cd ../.. To build and install SciTE, use the makefile located in the scite/gtk directory cd scite/gtk make make install This installs SciTE into $prefix/bin. The value of $prefix is determined from the location of Gnome if it is installed. This is usually /usr if installed with Linux or /usr/local if built from source. If Gnome is not installed /usr/bin is used as the prefix. The prefix can be overridden on the command line like "make prefix=/opt" but the same value should be used for both make and make install as this location is compiled into the executable. The global properties file is installed at $prefix/share/scite/SciTEGlobal.properties. The language specific properties files are also installed into this directory. To remove SciTE make uninstall To clean the object files which may be needed to change $prefix make clean The current make file only supports static linking between SciTE and Scintilla. *** Windows version *** A C++ compiler is required. Visual Studio .NET 2010 is the development system used for most development although TDM Mingw32 4.4.1 is also supported. To build Scintilla, make in the scintilla/win32 directory cd scintilla\win32 GCC: mingw32-make VS .NET: nmake -f scintilla.mak cd ..\.. To build SciTE, use the makefiles located in the scite/win32 directory cd scite\win32 GCC: mingw32-make VS .NET: nmake -f scite.mak An executable SciTE will now be in scite\bin. The Visual C++ 6.0 project (.dsp) and make files are no longer supported but are left in the download for people that are prepared to update them. *** GTK+/Windows version *** Mingw32 is known to work. Other compilers will probably not work. Only Scintilla will build with GTK+ on Windows. SciTE will not work. To build Scintilla, make in the scintilla/gtk directory cd scintilla\gtk mingw32-make |
Added cocoa/Framework.mk.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
### start defines ### include common.mk INST_NAME=-install_name \ @executable_path/../Frameworks/Sci.framework/Versions/A/Sci LD=gcc $(ARCH) -dynamiclib -framework Cocoa $(INST_NAME) LEXOBJS:=$(addsuffix .o,$(basename $(notdir $(wildcard ../lexers/Lex*.cxx)))) SCI_LEXERS=$(LEXOBJS) \ LexerBase.o LexerModule.o LexerSimple.o Accessor.o SCI_OBJ=AutoComplete.o CallTip.o CellBuffer.o CharClassify.o \ ContractionState.o Decoration.o Document.o Editor.o \ ExternalLexer.o Indicator.o KeyMap.o LineMarker.o PerLine.o \ PositionCache.o PropSetSimple.o RESearch.o RunStyles.o ScintillaBase.o Style.o \ StyleContext.o UniConversion.o ViewStyle.o XPM.o WordList.o \ Selection.o CharacterSet.o Catalogue.o $(SCI_LEXERS) WAH_OBJ=DocumentAccessor.o KeyWords.o WindowAccessor.o COC_OBJ=PlatCocoa.o ScintillaCocoa.o ScintillaView.o InfoBar.o OBJ=$(SCI_OBJ) $(UNUSED_OBJ) $(COC_OBJ) OBJS=$(addprefix $(FRM_BLD)/,$(OBJ)) TARG=$(APP)/Versions/A/Sci APP=$(FRM_BLD)/Sci.framework ### end defines ### ### start targets ### all: $(FRM_BLD) $(TARG) cleanfrm: -rm -rf $(FRM_BLD) $(APP): $(FRM_BLD) -rm -rf $(APP) -mkdir $(APP) -mkdir $(APP)/Versions -mkdir $(APP)/Versions/A -mkdir $(APP)/Versions/A/Headers -mkdir $(APP)/Versions/A/Resources -ln -sf `pwd`/$(APP)/Versions/A `pwd`/$(APP)/Versions/Current -ln -sf `pwd`/$(APP)/Versions/A/Headers `pwd`/$(APP)/Headers -ln -sf `pwd`/$(APP)/Versions/A/Resources `pwd`/$(APP)/Resources -cp *.h $(APP)/Headers/ -cp ../src/*.h $(APP)/Headers/ -cp ../include/*.h $(APP)/Headers/ -cp -R ScintillaFramework/English.lproj $(APP)/Resources -cp res/*.png $(APP)/Resources -cp ScintillaFramework/Info.plist $(APP)/Resources $(TARG) : $(OBJS) $(APP) $(LD) $(OBJS) $(gDEFs) -o $(TARG) -lstdc++ -ln `pwd`/$(TARG) `pwd`/$(APP)/Sci $(FRM_BLD): -mkdir $(BLD) -mkdir $(FRM_BLD) ### get around to filling out the real dependencies later ### #$(FRM_BLD)/AutoComplete.o : ../src/AutoComplete.cxx ../src/AutoComplete.h \ # ../include/Platform.h #$(FRM_BLD)/CallTip.o : ../src/CallTip.cxx ../src/CallTip.h \ # ../include/Platform.h ### end targets ### |
Added cocoa/InfoBar.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
/** * Scintilla source code edit control * InfoBar.h - Implements special info bar with zoom info, caret position etc. to be used with * ScintillaView. * * Mike Lischke <mlischke@sun.com> * * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). */ #import <Cocoa/Cocoa.h> #import "InfoBarCommunicator.h" /** * Extended text cell for vertically aligned text. */ @interface VerticallyCenteredTextFieldCell : NSTextFieldCell { BOOL mIsEditingOrSelecting; } @end @interface InfoBar : NSView <InfoBarCommunicator> { @private NSImage* mBackground; IBDisplay mDisplayMask; float mScaleFactor; NSPopUpButton* mZoomPopup; int mCurrentCaretX; int mCurrentCaretY; NSTextField* mCaretPositionLabel; NSTextField* mStatusTextLabel; id <InfoBarCommunicator> mCallback; } - (void) notify: (NotificationType) type message: (NSString*) message location: (NSPoint) location value: (float) value; - (void) setCallback: (id <InfoBarCommunicator>) callback; - (void) createItems; - (void) positionSubViews; - (void) setDisplay: (IBDisplay) display; - (void) zoomItemAction: (id) sender; - (void) setScaleFactor: (float) newScaleFactor adjustPopup: (BOOL) flag; - (void) setCaretPosition: (NSPoint) position; - (void) sizeToFit; @end |
Added cocoa/InfoBar.mm.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 |
/** * Scintilla source code edit control * InfoBar.mm - Implements special info bar with zoom info, caret position etc. to be used with * ScintillaView. * * Mike Lischke <mlischke@sun.com> * * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). */ #import "InfoBar.h" //-------------------------------------------------------------------------------------------------- @implementation VerticallyCenteredTextFieldCell // Inspired by code from Daniel Jalkut, Red Sweater Software. - (NSRect) drawingRectForBounds: (NSRect) theRect { // Get the parent's idea of where we should draw NSRect newRect = [super drawingRectForBounds: theRect]; // When the text field is being edited or selected, we have to turn off the magic because it // screws up the configuration of the field editor. We sneak around this by intercepting // selectWithFrame and editWithFrame and sneaking a reduced, centered rect in at the last minute. if (mIsEditingOrSelecting == NO) { // Get our ideal size for current text NSSize textSize = [self cellSizeForBounds: theRect]; // Center that in the proposed rect float heightDelta = newRect.size.height - textSize.height; if (heightDelta > 0) { newRect.size.height -= heightDelta; newRect.origin.y += ceil(heightDelta / 2); } } return newRect; } //-------------------------------------------------------------------------------------------------- - (void) selectWithFrame: (NSRect) aRect inView: (NSView*) controlView editor: (NSText*) textObj delegate:(id) anObject start: (NSInteger) selStart length: (NSInteger) selLength { aRect = [self drawingRectForBounds: aRect]; mIsEditingOrSelecting = YES; [super selectWithFrame: aRect inView: controlView editor: textObj delegate: anObject start: selStart length: selLength]; mIsEditingOrSelecting = NO; } //-------------------------------------------------------------------------------------------------- - (void) editWithFrame: (NSRect) aRect inView: (NSView*) controlView editor: (NSText*) textObj delegate: (id) anObject event: (NSEvent*) theEvent { aRect = [self drawingRectForBounds: aRect]; mIsEditingOrSelecting = YES; [super editWithFrame: aRect inView: controlView editor: textObj delegate: anObject event: theEvent]; mIsEditingOrSelecting = NO; } @end //-------------------------------------------------------------------------------------------------- @implementation InfoBar - (id) initWithFrame: (NSRect) frame { self = [super initWithFrame: frame]; if (self) { NSBundle* bundle = [NSBundle bundleForClass: [InfoBar class]]; NSString* path = [bundle pathForResource: @"info_bar_bg" ofType: @"png" inDirectory: nil]; mBackground = [[NSImage alloc] initWithContentsOfFile: path]; if (![mBackground isValid]) NSLog(@"Background image for info bar is invalid."); mScaleFactor = 1.0; mCurrentCaretX = 0; mCurrentCaretY = 0; [self createItems]; } return self; } //-------------------------------------------------------------------------------------------------- /** * Called by a connected compontent (usually the info bar) if something changed there. * * @param type The type of the notification. * @param message Carries the new status message if the type is a status message change. * @param location Carries the new location (e.g. caret) if the type is a caret change or similar type. * @param location Carries the new zoom value if the type is a zoom change. */ - (void) notify: (NotificationType) type message: (NSString*) message location: (NSPoint) location value: (float) value { switch (type) { case IBNZoomChanged: [self setScaleFactor: value adjustPopup: YES]; break; case IBNCaretChanged: [self setCaretPosition: location]; break; case IBNStatusChanged: [mStatusTextLabel setStringValue: message]; break; } } //-------------------------------------------------------------------------------------------------- /** * Used to set a protocol object we can use to send change notifications to. */ - (void) setCallback: (id <InfoBarCommunicator>) callback { mCallback = callback; } //-------------------------------------------------------------------------------------------------- static NSString *DefaultScaleMenuLabels[] = { @"20%", @"30%", @"50%", @"75%", @"100%", @"130%", @"160%", @"200%", @"250%", @"300%" }; static float DefaultScaleMenuFactors[] = { 0.2, 0.3, 0.5, 0.75, 1.0, 1.3, 1.6, 2.0, 2.5, 3.0 }; static unsigned DefaultScaleMenuSelectedItemIndex = 4; static float BarFontSize = 10.0; - (void) createItems { // 1) The zoom popup. unsigned numberOfDefaultItems = sizeof(DefaultScaleMenuLabels) / sizeof(NSString *); // Create the popup button. mZoomPopup = [[NSPopUpButton allocWithZone:[self zone]] initWithFrame: NSMakeRect(0.0, 0.0, 1.0, 1.0) pullsDown: NO]; // No border or background please. [[mZoomPopup cell] setBordered: NO]; [[mZoomPopup cell] setArrowPosition: NSPopUpArrowAtBottom]; // Fill it. for (unsigned count = 0; count < numberOfDefaultItems; count++) { [mZoomPopup addItemWithTitle: NSLocalizedStringFromTable(DefaultScaleMenuLabels[count], @"ZoomValues", nil)]; id currentItem = [mZoomPopup itemAtIndex: count]; if (DefaultScaleMenuFactors[count] != 0.0) [currentItem setRepresentedObject: [NSNumber numberWithFloat: DefaultScaleMenuFactors[count]]]; } [mZoomPopup selectItemAtIndex: DefaultScaleMenuSelectedItemIndex]; // Hook it up. [mZoomPopup setTarget: self]; [mZoomPopup setAction: @selector(zoomItemAction:)]; // Set a suitable font. [mZoomPopup setFont: [NSFont menuBarFontOfSize: BarFontSize]]; // Make sure the popup is big enough to fit the cells. [mZoomPopup sizeToFit]; // Don't let it become first responder [mZoomPopup setRefusesFirstResponder: YES]; // put it in the scrollview. [self addSubview: mZoomPopup]; [mZoomPopup release]; // 2) The caret position label. Class oldCellClass = [NSTextField cellClass]; [NSTextField setCellClass: [VerticallyCenteredTextFieldCell class]]; mCaretPositionLabel = [[NSTextField alloc] initWithFrame: NSMakeRect(0.0, 0.0, 50.0, 1.0)]; [mCaretPositionLabel setBezeled: NO]; [mCaretPositionLabel setBordered: NO]; [mCaretPositionLabel setEditable: NO]; [mCaretPositionLabel setSelectable: NO]; [mCaretPositionLabel setDrawsBackground: NO]; [mCaretPositionLabel setFont: [NSFont menuBarFontOfSize: BarFontSize]]; NSTextFieldCell* cell = [mCaretPositionLabel cell]; [cell setPlaceholderString: @"0:0"]; [cell setAlignment: NSCenterTextAlignment]; [self addSubview: mCaretPositionLabel]; [mCaretPositionLabel release]; // 3) The status text. mStatusTextLabel = [[NSTextField alloc] initWithFrame: NSMakeRect(0.0, 0.0, 1.0, 1.0)]; [mStatusTextLabel setBezeled: NO]; [mStatusTextLabel setBordered: NO]; [mStatusTextLabel setEditable: NO]; [mStatusTextLabel setSelectable: NO]; [mStatusTextLabel setDrawsBackground: NO]; [mStatusTextLabel setFont: [NSFont menuBarFontOfSize: BarFontSize]]; cell = [mStatusTextLabel cell]; [cell setPlaceholderString: @""]; [self addSubview: mStatusTextLabel]; [mStatusTextLabel release]; // Restore original cell class so that everything else doesn't get broken [NSTextField setCellClass: oldCellClass]; } //-------------------------------------------------------------------------------------------------- - (void) dealloc { [mBackground release]; [super dealloc]; } //-------------------------------------------------------------------------------------------------- /** * Fill the background. */ - (void) drawRect: (NSRect) rect { // Since the background is seamless, we don't need to take care for the proper offset. // Simply tile the background over the invalid rectangle. NSPoint target = {rect.origin.x, 0}; while (target.x < rect.origin.x + rect.size.width) { [mBackground drawAtPoint: target fromRect: NSZeroRect operation: NSCompositeCopy fraction: 1]; target.x += mBackground.size.width; } // Draw separator lines between items. NSRect verticalLineRect; float component = 190.0 / 255.0; NSColor* lineColor = [NSColor colorWithDeviceRed: component green: component blue: component alpha: 1]; if (mDisplayMask & IBShowZoom) { verticalLineRect = [mZoomPopup frame]; verticalLineRect.origin.x += verticalLineRect.size.width + 1.0; verticalLineRect.size.width = 1.0; if (NSIntersectsRect(rect, verticalLineRect)) { [lineColor set]; NSRectFill(verticalLineRect); } } if (mDisplayMask & IBShowCaretPosition) { verticalLineRect = [mCaretPositionLabel frame]; verticalLineRect.origin.x += verticalLineRect.size.width + 1.0; verticalLineRect.size.width = 1.0; if (NSIntersectsRect(rect, verticalLineRect)) { [lineColor set]; NSRectFill(verticalLineRect); } } } //-------------------------------------------------------------------------------------------------- - (BOOL) isOpaque { return YES; } //-------------------------------------------------------------------------------------------------- /** * Used to reposition our content depending on the size of the view. */ - (void) setFrame: (NSRect) newFrame { [super setFrame: newFrame]; [self positionSubViews]; } //-------------------------------------------------------------------------------------------------- - (void) positionSubViews { NSRect currentBounds = {0, 0, 0, [self frame].size.height}; if (mDisplayMask & IBShowZoom) { [mZoomPopup setHidden: NO]; currentBounds.size.width = [mZoomPopup frame].size.width; [mZoomPopup setFrame: currentBounds]; currentBounds.origin.x += currentBounds.size.width + 1; // Add 1 for the separator. } else [mZoomPopup setHidden: YES]; if (mDisplayMask & IBShowCaretPosition) { [mCaretPositionLabel setHidden: NO]; currentBounds.size.width = [mCaretPositionLabel frame].size.width; [mCaretPositionLabel setFrame: currentBounds]; currentBounds.origin.x += currentBounds.size.width + 1; } else [mCaretPositionLabel setHidden: YES]; if (mDisplayMask & IBShowStatusText) { // The status text always takes the rest of the available space. [mStatusTextLabel setHidden: NO]; currentBounds.size.width = [self frame].size.width - currentBounds.origin.x; [mStatusTextLabel setFrame: currentBounds]; } else [mStatusTextLabel setHidden: YES]; } //-------------------------------------------------------------------------------------------------- /** * Used to switch the visible parts of the info bar. * * @param display Bitwise ORed IBDisplay values which determine what to show on the bar. */ - (void) setDisplay: (IBDisplay) display { if (mDisplayMask != display) { mDisplayMask = display; [self positionSubViews]; [self needsDisplay]; } } //-------------------------------------------------------------------------------------------------- /** * Handler for selection changes in the zoom menu. */ - (void) zoomItemAction: (id) sender { NSNumber* selectedFactorObject = [[sender selectedCell] representedObject]; if (selectedFactorObject == nil) { NSLog(@"Scale popup action: setting arbitrary zoom factors is not yet supported."); return; } else { [self setScaleFactor: [selectedFactorObject floatValue] adjustPopup: NO]; } } //-------------------------------------------------------------------------------------------------- - (void) setScaleFactor: (float) newScaleFactor adjustPopup: (BOOL) flag { if (mScaleFactor != newScaleFactor) { mScaleFactor = newScaleFactor; if (flag) { unsigned count = 0; unsigned numberOfDefaultItems = sizeof(DefaultScaleMenuFactors) / sizeof(float); // We only work with some preset zoom values. If the given value does not correspond // to one then show no selection. while (count < numberOfDefaultItems && (fabs(newScaleFactor - DefaultScaleMenuFactors[count]) > 0.07)) count++; if (count == numberOfDefaultItems) [mZoomPopup selectItemAtIndex: -1]; else { [mZoomPopup selectItemAtIndex: count]; // Set scale factor to found preset value if it comes close. mScaleFactor = DefaultScaleMenuFactors[count]; } } else { // Internally set. Notify owner. [mCallback notify: IBNZoomChanged message: nil location: NSZeroPoint value: newScaleFactor]; } } } //-------------------------------------------------------------------------------------------------- /** * Called from the notification method to update the caret position display. */ - (void) setCaretPosition: (NSPoint) position { // Make the position one-based. int newX = (int) position.x + 1; int newY = (int) position.y + 1; if (mCurrentCaretX != newX || mCurrentCaretY != newY) { mCurrentCaretX = newX; mCurrentCaretY = newY; [mCaretPositionLabel setStringValue: [NSString stringWithFormat: @"%d:%d", newX, newY]]; } } //-------------------------------------------------------------------------------------------------- /** * Makes the bar resize to the smallest width that can accomodate the currently enabled items. */ - (void) sizeToFit { NSRect frame = [self frame]; frame.size.width = 0; if (mDisplayMask & IBShowZoom) frame.size.width += [mZoomPopup frame].size.width; if (mDisplayMask & IBShowCaretPosition) frame.size.width += [mCaretPositionLabel frame].size.width; if (mDisplayMask & IBShowStatusText) frame.size.width += [mStatusTextLabel frame].size.width; [self setFrame: frame]; } @end |
Added cocoa/InfoBarCommunicator.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
/* * InfoBarCommunicator.h - Definitions of a communication protocol and other data types used for * the info bar implementation. * * Mike Lischke <mlischke@sun.com> * * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). */ enum IBDisplay { IBShowZoom = 0x01, IBShowCaretPosition = 0x02, IBShowStatusText = 0x04, IBShowAll = 0xFF }; /** * The info bar communicator protocol is used for communication between ScintillaView and its * information bar component. Using this protocol decouples any potential info target from the main * ScintillaView implementation. The protocol is used two-way. */ enum NotificationType { IBNZoomChanged, // The user selected another zoom value. IBNCaretChanged, // The caret in the editor changed. IBNStatusChanged, // The application set a new status message. }; @protocol InfoBarCommunicator - (void) notify: (NotificationType) type message: (NSString*) message location: (NSPoint) location value: (float) value; - (void) setCallback: (id <InfoBarCommunicator>) callback; @end |
Added cocoa/PlatCocoa.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
/** * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). */ #ifndef PLATCOCOA_H #define PLATCOCOA_H #include <cstring> #include <cstdio> #include <cstdlib> #include <assert.h> #include <sys/time.h> #include <Cocoa/Cocoa.h> #include "QuartzTextLayout.h" #include "Platform.h" #include "Scintilla.h" NSRect PRectangleToNSRect(Scintilla::PRectangle& rc); Scintilla::PRectangle NSRectToPRectangle(NSRect& rc); CFStringEncoding EncodingFromCharacterSet(bool unicode, int characterSet); @interface ScintillaContextMenu : NSMenu { Scintilla::ScintillaCocoa* owner; } - (void) handleCommand: (NSMenuItem*) sender; - (void) setOwner: (Scintilla::ScintillaCocoa*) newOwner; @end namespace Scintilla { // A class to do the actual text rendering for us using Quartz 2D. class SurfaceImpl : public Surface { private: bool unicodeMode; float x; float y; CGContextRef gc; /** The text layout instance */ QuartzTextLayout* textLayout; int codePage; int verticalDeviceResolution; /** If the surface is a bitmap context, contains a reference to the bitmap data. */ uint8_t* bitmapData; /** If the surface is a bitmap context, stores the dimensions of the bitmap. */ int bitmapWidth; int bitmapHeight; /** Set the CGContext's fill colour to the specified desired colour. */ void FillColour( const ColourDesired& back ); // 24-bit RGB+A bitmap data constants static const int BITS_PER_COMPONENT = 8; static const int BITS_PER_PIXEL = BITS_PER_COMPONENT * 4; static const int BYTES_PER_PIXEL = BITS_PER_PIXEL / 8; public: SurfaceImpl(); ~SurfaceImpl(); void Init(WindowID wid); void Init(SurfaceID sid, WindowID wid); void InitPixMap(int width, int height, Surface *surface_, WindowID wid); CGContextRef GetContext() { return gc; } void Release(); bool Initialised(); void PenColour(ColourDesired fore); /** Returns a CGImageRef that represents the surface. Returns NULL if this is not possible. */ CGImageRef GetImage(); void CopyImageRectangle(Surface &surfaceSource, PRectangle srcRect, PRectangle dstRect); int LogPixelsY(); int DeviceHeightFont(int points); void MoveTo(int x_, int y_); void LineTo(int x_, int y_); void Polygon(Scintilla::Point *pts, int npts, ColourDesired fore, ColourDesired back); void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back); void FillRectangle(PRectangle rc, ColourDesired back); void FillRectangle(PRectangle rc, Surface &surfacePattern); void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back); void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, ColourDesired outline, int alphaOutline, int flags); void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage); void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back); void Copy(PRectangle rc, Scintilla::Point from, Surface &surfaceSource); void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back); void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back); void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore); void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions); XYPOSITION WidthText(Font &font_, const char *s, int len); XYPOSITION WidthChar(Font &font_, char ch); XYPOSITION Ascent(Font &font_); XYPOSITION Descent(Font &font_); XYPOSITION InternalLeading(Font &font_); XYPOSITION ExternalLeading(Font &font_); XYPOSITION Height(Font &font_); XYPOSITION AverageCharWidth(Font &font_); void SetClip(PRectangle rc); void FlushCachedState(); void SetUnicodeMode(bool unicodeMode_); void SetDBCSMode(int codePage_); }; // SurfaceImpl class } // Scintilla namespace #endif |
Added cocoa/PlatCocoa.mm.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 |
/** * Scintilla source code edit control * PlatCocoa.mm - implementation of platform facilities on MacOS X/Cocoa * * Written by Mike Lischke * Based on PlatMacOSX.cxx * Based on work by Evan Jones (c) 2002 <ejones@uwaterloo.ca> * Based on PlatGTK.cxx Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> * The License.txt file describes the conditions under which this software may be distributed. * * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). */ #import <ScintillaView.h> #include "PlatCocoa.h" #include <cstring> #include <cstdio> #include <cstdlib> #include <assert.h> #include <sys/time.h> #include <stdexcept> #include <map> #include "XPM.h" #import <Foundation/NSGeometry.h> using namespace Scintilla; extern sptr_t scintilla_send_message(void* sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam); //-------------------------------------------------------------------------------------------------- /** * Converts a PRectangle as used by Scintilla to standard Obj-C NSRect structure . */ NSRect PRectangleToNSRect(PRectangle& rc) { return NSMakeRect(rc.left, rc.top, rc.Width(), rc.Height()); } //-------------------------------------------------------------------------------------------------- /** * Converts an NSRect as used by the system to a native Scintilla rectangle. */ PRectangle NSRectToPRectangle(NSRect& rc) { return PRectangle(rc.origin.x, rc.origin.y, rc.size.width + rc.origin.x, rc.size.height + rc.origin.y); } //-------------------------------------------------------------------------------------------------- /** * Converts a PRctangle as used by Scintilla to a Quartz-style rectangle. */ inline CGRect PRectangleToCGRect(PRectangle& rc) { return CGRectMake(rc.left, rc.top, rc.Width(), rc.Height()); } //-------------------------------------------------------------------------------------------------- /** * Converts a Quartz-style rectangle to a PRectangle structure as used by Scintilla. */ inline PRectangle CGRectToPRectangle(const CGRect& rect) { PRectangle rc; rc.left = (int)(rect.origin.x + 0.5); rc.top = (int)(rect.origin.y + 0.5); rc.right = (int)(rect.origin.x + rect.size.width + 0.5); rc.bottom = (int)(rect.origin.y + rect.size.height + 0.5); return rc; } //----------------- Point -------------------------------------------------------------------------- /** * Converts a point given as a long into a native Point structure. */ Scintilla::Point Scintilla::Point::FromLong(long lpoint) { return Scintilla::Point( Platform::LowShortFromLong(lpoint), Platform::HighShortFromLong(lpoint) ); } //----------------- Font --------------------------------------------------------------------------- Font::Font(): fid(0) { } //-------------------------------------------------------------------------------------------------- Font::~Font() { Release(); } //-------------------------------------------------------------------------------------------------- static int FontCharacterSet(Font &f) { return reinterpret_cast<QuartzTextStyle *>(f.GetID())->getCharacterSet(); } /** * Creates a CTFontRef with the given properties. */ void Font::Create(const FontParameters &fp) { Release(); QuartzTextStyle* style = new QuartzTextStyle(); fid = style; // Create the font with attributes QuartzFont font(fp.faceName, strlen(fp.faceName), fp.size, fp.weight, fp.italic); CTFontRef fontRef = font.getFontID(); style->setFontRef(fontRef, fp.characterSet); } //-------------------------------------------------------------------------------------------------- void Font::Release() { if (fid) delete reinterpret_cast<QuartzTextStyle*>( fid ); fid = 0; } //----------------- SurfaceImpl -------------------------------------------------------------------- SurfaceImpl::SurfaceImpl() { unicodeMode = true; x = 0; y = 0; gc = NULL; textLayout = new QuartzTextLayout(NULL); codePage = 0; verticalDeviceResolution = 0; bitmapData = NULL; // Release will try and delete bitmapData if != NULL bitmapWidth = 0; bitmapHeight = 0; Release(); } //-------------------------------------------------------------------------------------------------- SurfaceImpl::~SurfaceImpl() { Release(); delete textLayout; } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::Release() { textLayout->setContext (NULL); if ( bitmapData != NULL ) { delete[] bitmapData; // We only "own" the graphics context if we are a bitmap context if (gc != NULL) CGContextRelease(gc); } bitmapData = NULL; gc = NULL; bitmapWidth = 0; bitmapHeight = 0; x = 0; y = 0; } //-------------------------------------------------------------------------------------------------- bool SurfaceImpl::Initialised() { // We are initalised if the graphics context is not null return gc != NULL;// || port != NULL; } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::Init(WindowID) { // To be able to draw, the surface must get a CGContext handle. We save the graphics port, // then aquire/release the context on an as-need basis (see above). // XXX Docs on QDBeginCGContext are light, a better way to do this would be good. // AFAIK we should not hold onto a context retrieved this way, thus the need for // aquire/release of the context. Release(); } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::Init(SurfaceID sid, WindowID) { Release(); gc = reinterpret_cast<CGContextRef>(sid); CGContextSetLineWidth(gc, 1.0); textLayout->setContext(gc); } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::InitPixMap(int width, int height, Surface* /* surface_ */, WindowID /* wid */) { Release(); // Create a new bitmap context, along with the RAM for the bitmap itself bitmapWidth = width; bitmapHeight = height; const int bitmapBytesPerRow = (width * BYTES_PER_PIXEL); const int bitmapByteCount = (bitmapBytesPerRow * height); // Create an RGB color space. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); if (colorSpace == NULL) return; // Create the bitmap. bitmapData = new uint8_t[bitmapByteCount]; if (bitmapData != NULL) { // create the context gc = CGBitmapContextCreate(bitmapData, width, height, BITS_PER_COMPONENT, bitmapBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast); if (gc == NULL) { // the context couldn't be created for some reason, // and we have no use for the bitmap without the context delete[] bitmapData; bitmapData = NULL; } textLayout->setContext (gc); } // the context retains the color space, so we can release it CGColorSpaceRelease(colorSpace); if (gc != NULL && bitmapData != NULL) { // "Erase" to white. CGContextClearRect( gc, CGRectMake( 0, 0, width, height ) ); CGContextSetRGBFillColor( gc, 1.0, 1.0, 1.0, 1.0 ); CGContextFillRect( gc, CGRectMake( 0, 0, width, height ) ); } } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::PenColour(ColourDesired fore) { if (gc) { ColourDesired colour(fore.AsLong()); // Set the Stroke color to match CGContextSetRGBStrokeColor(gc, colour.GetRed() / 255.0, colour.GetGreen() / 255.0, colour.GetBlue() / 255.0, 1.0 ); } } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::FillColour(const ColourDesired& back) { if (gc) { ColourDesired colour(back.AsLong()); // Set the Fill color to match CGContextSetRGBFillColor(gc, colour.GetRed() / 255.0, colour.GetGreen() / 255.0, colour.GetBlue() / 255.0, 1.0 ); } } //-------------------------------------------------------------------------------------------------- CGImageRef SurfaceImpl::GetImage() { // For now, assume that GetImage can only be called on PixMap surfaces. if (bitmapData == NULL) return NULL; CGContextFlush(gc); // Create an RGB color space. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); if( colorSpace == NULL ) return NULL; const int bitmapBytesPerRow = ((int) bitmapWidth * BYTES_PER_PIXEL); const int bitmapByteCount = (bitmapBytesPerRow * (int) bitmapHeight); // Make a copy of the bitmap data for the image creation and divorce it // From the SurfaceImpl lifetime CFDataRef dataRef = CFDataCreate(kCFAllocatorDefault, bitmapData, bitmapByteCount); // Create a data provider. CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData(dataRef); CGImageRef image = NULL; if (dataProvider != NULL) { // Create the CGImage. image = CGImageCreate(bitmapWidth, bitmapHeight, BITS_PER_COMPONENT, BITS_PER_PIXEL, bitmapBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast, dataProvider, NULL, 0, kCGRenderingIntentDefault); } // The image retains the color space, so we can release it. CGColorSpaceRelease(colorSpace); colorSpace = NULL; // Done with the data provider. CGDataProviderRelease(dataProvider); dataProvider = NULL; // Done with the data provider. CFRelease(dataRef); return image; } //-------------------------------------------------------------------------------------------------- /** * Returns the vertical logical device resolution of the main monitor. * This is no longer called. * For Cocoa, all screens are treated as 72 DPI, even retina displays. */ int SurfaceImpl::LogPixelsY() { return 72; } //-------------------------------------------------------------------------------------------------- /** * Converts the logical font height in points into a device height. * For Cocoa, points are always used for the result even on retina displays. */ int SurfaceImpl::DeviceHeightFont(int points) { return points; } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::MoveTo(int x_, int y_) { x = x_; y = y_; } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::LineTo(int x_, int y_) { CGContextBeginPath( gc ); // Because Quartz is based on floating point, lines are drawn with half their colour // on each side of the line. Integer coordinates specify the INTERSECTION of the pixel // divison lines. If you specify exact pixel values, you get a line that // is twice as thick but half as intense. To get pixel aligned rendering, // we render the "middle" of the pixels by adding 0.5 to the coordinates. CGContextMoveToPoint( gc, x + 0.5, y + 0.5 ); CGContextAddLineToPoint( gc, x_ + 0.5, y_ + 0.5 ); CGContextStrokePath( gc ); x = x_; y = y_; } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::Polygon(Scintilla::Point *pts, int npts, ColourDesired fore, ColourDesired back) { // Allocate memory for the array of points. CGPoint *points = new CGPoint[npts]; for (int i = 0;i < npts;i++) { // Quartz floating point issues: plot the MIDDLE of the pixels points[i].x = pts[i].x + 0.5; points[i].y = pts[i].y + 0.5; } CGContextBeginPath(gc); // Set colours FillColour(back); PenColour(fore); // Draw the polygon CGContextAddLines(gc, points, npts); // Explicitly close the path, so it is closed for stroking AND filling (implicit close = filling only) CGContextClosePath( gc ); CGContextDrawPath( gc, kCGPathFillStroke ); // Deallocate memory. delete points; points = NULL; } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) { if (gc) { CGContextBeginPath( gc ); FillColour(back); PenColour(fore); // Quartz integer -> float point conversion fun (see comment in SurfaceImpl::LineTo) // We subtract 1 from the Width() and Height() so that all our drawing is within the area defined // by the PRectangle. Otherwise, we draw one pixel too far to the right and bottom. CGContextAddRect( gc, CGRectMake( rc.left + 0.5, rc.top + 0.5, rc.Width() - 1, rc.Height() - 1 ) ); CGContextDrawPath( gc, kCGPathFillStroke ); } } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::FillRectangle(PRectangle rc, ColourDesired back) { if (gc) { FillColour(back); // Snap rectangle boundaries to nearest int rc.left = lround(rc.left); rc.right = lround(rc.right); CGRect rect = PRectangleToCGRect(rc); CGContextFillRect(gc, rect); } } //-------------------------------------------------------------------------------------------------- void drawImageRefCallback(CGImageRef pattern, CGContextRef gc) { CGContextDrawImage(gc, CGRectMake(0, 0, CGImageGetWidth(pattern), CGImageGetHeight(pattern)), pattern); } //-------------------------------------------------------------------------------------------------- void releaseImageRefCallback(CGImageRef pattern) { CGImageRelease(pattern); } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) { SurfaceImpl& patternSurface = static_cast<SurfaceImpl &>(surfacePattern); // For now, assume that copy can only be called on PixMap surfaces. Shows up black. CGImageRef image = patternSurface.GetImage(); if (image == NULL) { FillRectangle(rc, ColourDesired(0)); return; } const CGPatternCallbacks drawImageCallbacks = { 0, reinterpret_cast<CGPatternDrawPatternCallback>(drawImageRefCallback), reinterpret_cast<CGPatternReleaseInfoCallback>(releaseImageRefCallback) }; CGPatternRef pattern = CGPatternCreate(image, CGRectMake(0, 0, patternSurface.bitmapWidth, patternSurface.bitmapHeight), CGAffineTransformIdentity, patternSurface.bitmapWidth, patternSurface.bitmapHeight, kCGPatternTilingNoDistortion, true, &drawImageCallbacks ); if (pattern != NULL) { // Create a pattern color space CGColorSpaceRef colorSpace = CGColorSpaceCreatePattern( NULL ); if( colorSpace != NULL ) { CGContextSaveGState( gc ); CGContextSetFillColorSpace( gc, colorSpace ); // Unlike the documentation, you MUST pass in a "components" parameter: // For coloured patterns it is the alpha value. const CGFloat alpha = 1.0; CGContextSetFillPattern( gc, pattern, &alpha ); CGContextFillRect( gc, PRectangleToCGRect( rc ) ); CGContextRestoreGState( gc ); // Free the color space, the pattern and image CGColorSpaceRelease( colorSpace ); } /* colorSpace != NULL */ colorSpace = NULL; CGPatternRelease( pattern ); pattern = NULL; } /* pattern != NULL */ } void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back) { // This is only called from the margin marker drawing code for SC_MARK_ROUNDRECT // The Win32 version does // ::RoundRect(hdc, rc.left + 1, rc.top, rc.right - 1, rc.bottom, 8, 8 ); // which is a rectangle with rounded corners each having a radius of 4 pixels. // It would be almost as good just cutting off the corners with lines at // 45 degrees as is done on GTK+. // Create a rectangle with semicircles at the corners const int MAX_RADIUS = 4; int radius = Platform::Minimum( MAX_RADIUS, rc.Height()/2 ); radius = Platform::Minimum( radius, rc.Width()/2 ); // Points go clockwise, starting from just below the top left // Corners are kept together, so we can easily create arcs to connect them CGPoint corners[4][3] = { { { rc.left, rc.top + radius }, { rc.left, rc.top }, { rc.left + radius, rc.top }, }, { { rc.right - radius - 1, rc.top }, { rc.right - 1, rc.top }, { rc.right - 1, rc.top + radius }, }, { { rc.right - 1, rc.bottom - radius - 1 }, { rc.right - 1, rc.bottom - 1 }, { rc.right - radius - 1, rc.bottom - 1 }, }, { { rc.left + radius, rc.bottom - 1 }, { rc.left, rc.bottom - 1 }, { rc.left, rc.bottom - radius - 1 }, }, }; // Align the points in the middle of the pixels for( int i = 0; i < 4; ++ i ) { for( int j = 0; j < 3; ++ j ) { corners[i][j].x += 0.5; corners[i][j].y += 0.5; } } PenColour( fore ); FillColour( back ); // Move to the last point to begin the path CGContextBeginPath( gc ); CGContextMoveToPoint( gc, corners[3][2].x, corners[3][2].y ); for ( int i = 0; i < 4; ++ i ) { CGContextAddLineToPoint( gc, corners[i][0].x, corners[i][0].y ); CGContextAddArcToPoint( gc, corners[i][1].x, corners[i][1].y, corners[i][2].x, corners[i][2].y, radius ); } // Close the path to enclose it for stroking and for filling, then draw it CGContextClosePath( gc ); CGContextDrawPath( gc, kCGPathFillStroke ); } void Scintilla::SurfaceImpl::AlphaRectangle(PRectangle rc, int /*cornerSize*/, ColourDesired fill, int alphaFill, ColourDesired /*outline*/, int /*alphaOutline*/, int /*flags*/) { if ( gc ) { ColourDesired colour( fill.AsLong() ); // Snap rectangle boundaries to nearest int rc.left = lround(rc.left); rc.right = lround(rc.right); // Set the Fill color to match CGContextSetRGBFillColor( gc, colour.GetRed() / 255.0, colour.GetGreen() / 255.0, colour.GetBlue() / 255.0, alphaFill / 255.0 ); CGRect rect = PRectangleToCGRect( rc ); CGContextFillRect( gc, rect ); } } static void ProviderReleaseData(void *, const void *data, size_t) { const unsigned char *pixels = reinterpret_cast<const unsigned char *>(data); delete []pixels; } static CGImageRef ImageCreateFromRGBA(int width, int height, const unsigned char *pixelsImage, bool invert) { CGImageRef image = 0; // Create an RGB color space. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); if (colorSpace) { const int bitmapBytesPerRow = ((int) width * 4); const int bitmapByteCount = (bitmapBytesPerRow * (int) height); // Create a data provider. CGDataProviderRef dataProvider = 0; if (invert) { unsigned char *pixelsUpsideDown = new unsigned char[bitmapByteCount]; for (int y=0; y<height; y++) { int yInverse = height - y - 1; memcpy(pixelsUpsideDown + y * bitmapBytesPerRow, pixelsImage + yInverse * bitmapBytesPerRow, bitmapBytesPerRow); } dataProvider = CGDataProviderCreateWithData( NULL, pixelsUpsideDown, bitmapByteCount, ProviderReleaseData); } else { dataProvider = CGDataProviderCreateWithData( NULL, pixelsImage, bitmapByteCount, NULL); } if (dataProvider) { // Create the CGImage. image = CGImageCreate(width, height, 8, 8 * 4, bitmapBytesPerRow, colorSpace, kCGImageAlphaLast, dataProvider, NULL, 0, kCGRenderingIntentDefault); CGDataProviderRelease(dataProvider); } // The image retains the color space, so we can release it. CGColorSpaceRelease(colorSpace); } return image; } void SurfaceImpl::DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) { CGImageRef image = ImageCreateFromRGBA(width, height, pixelsImage, true); if (image) { CGRect drawRect = CGRectMake(rc.left, rc.top, rc.Width(), rc.Height()); CGContextDrawImage(gc, drawRect, image); CGImageRelease(image); } } void SurfaceImpl::Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) { // Drawing an ellipse with bezier curves. Code modified from: // http://www.codeguru.com/gdi/ellipse.shtml // MAGICAL CONSTANT to map ellipse to beziers 2/3*(sqrt(2)-1) const double EToBConst = 0.2761423749154; CGSize offset = CGSizeMake((int)(rc.Width() * EToBConst), (int)(rc.Height() * EToBConst)); CGPoint centre = CGPointMake((rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2); // The control point array CGPoint cCtlPt[13]; // Assign values to all the control points cCtlPt[0].x = cCtlPt[1].x = cCtlPt[11].x = cCtlPt[12].x = rc.left + 0.5; cCtlPt[5].x = cCtlPt[6].x = cCtlPt[7].x = rc.right - 0.5; cCtlPt[2].x = cCtlPt[10].x = centre.x - offset.width + 0.5; cCtlPt[4].x = cCtlPt[8].x = centre.x + offset.width + 0.5; cCtlPt[3].x = cCtlPt[9].x = centre.x + 0.5; cCtlPt[2].y = cCtlPt[3].y = cCtlPt[4].y = rc.top + 0.5; cCtlPt[8].y = cCtlPt[9].y = cCtlPt[10].y = rc.bottom - 0.5; cCtlPt[7].y = cCtlPt[11].y = centre.y + offset.height + 0.5; cCtlPt[1].y = cCtlPt[5].y = centre.y - offset.height + 0.5; cCtlPt[0].y = cCtlPt[12].y = cCtlPt[6].y = centre.y + 0.5; FillColour(back); PenColour(fore); CGContextBeginPath( gc ); CGContextMoveToPoint( gc, cCtlPt[0].x, cCtlPt[0].y ); for ( int i = 1; i < 13; i += 3 ) { CGContextAddCurveToPoint( gc, cCtlPt[i].x, cCtlPt[i].y, cCtlPt[i+1].x, cCtlPt[i+1].y, cCtlPt[i+2].x, cCtlPt[i+2].y ); } // Close the path to enclose it for stroking and for filling, then draw it CGContextClosePath( gc ); CGContextDrawPath( gc, kCGPathFillStroke ); } void SurfaceImpl::CopyImageRectangle(Surface &surfaceSource, PRectangle srcRect, PRectangle dstRect) { SurfaceImpl& source = static_cast<SurfaceImpl &>(surfaceSource); CGImageRef image = source.GetImage(); CGRect src = PRectangleToCGRect(srcRect); CGRect dst = PRectangleToCGRect(dstRect); /* source from QuickDrawToQuartz2D.pdf on developer.apple.com */ float w = (float) CGImageGetWidth(image); float h = (float) CGImageGetHeight(image); CGRect drawRect = CGRectMake (0, 0, w, h); if (!CGRectEqualToRect (src, dst)) { float sx = CGRectGetWidth(dst) / CGRectGetWidth(src); float sy = CGRectGetHeight(dst) / CGRectGetHeight(src); float dx = CGRectGetMinX(dst) - (CGRectGetMinX(src) * sx); float dy = CGRectGetMinY(dst) - (CGRectGetMinY(src) * sy); drawRect = CGRectMake (dx, dy, w*sx, h*sy); } CGContextSaveGState (gc); CGContextClipToRect (gc, dst); CGContextDrawImage (gc, drawRect, image); CGContextRestoreGState (gc); CGImageRelease(image); } void SurfaceImpl::Copy(PRectangle rc, Scintilla::Point from, Surface &surfaceSource) { // Maybe we have to make the Surface two contexts: // a bitmap context which we do all the drawing on, and then a "real" context // which we copy the output to when we call "Synchronize". Ugh! Gross and slow! // For now, assume that copy can only be called on PixMap surfaces SurfaceImpl& source = static_cast<SurfaceImpl &>(surfaceSource); // Get the CGImageRef CGImageRef image = source.GetImage(); // If we could not get an image reference, fill the rectangle black if ( image == NULL ) { FillRectangle( rc, ColourDesired( 0 ) ); return; } // Now draw the image on the surface // Some fancy clipping work is required here: draw only inside of rc CGContextSaveGState( gc ); CGContextClipToRect( gc, PRectangleToCGRect( rc ) ); //Platform::DebugPrintf(stderr, "Copy: CGContextDrawImage: (%d, %d) - (%d X %d)\n", rc.left - from.x, rc.top - from.y, source.bitmapWidth, source.bitmapHeight ); CGContextDrawImage( gc, CGRectMake( rc.left - from.x, rc.top - from.y, source.bitmapWidth, source.bitmapHeight ), image ); // Undo the clipping fun CGContextRestoreGState( gc ); // Done with the image CGImageRelease( image ); image = NULL; } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) { FillRectangle(rc, back); DrawTextTransparent(rc, font_, ybase, s, len, fore); } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) { CGContextSaveGState(gc); CGContextClipToRect(gc, PRectangleToCGRect(rc)); DrawTextNoClip(rc, font_, ybase, s, len, fore, back); CGContextRestoreGState(gc); } //-------------------------------------------------------------------------------------------------- CFStringEncoding EncodingFromCharacterSet(bool unicode, int characterSet) { if (unicode) return kCFStringEncodingUTF8; // Unsupported -> Latin1 as reasonably safe enum { notSupported = kCFStringEncodingISOLatin1}; switch (characterSet) { case SC_CHARSET_ANSI: return kCFStringEncodingISOLatin1; case SC_CHARSET_DEFAULT: return kCFStringEncodingISOLatin1; case SC_CHARSET_BALTIC: return kCFStringEncodingWindowsBalticRim; case SC_CHARSET_CHINESEBIG5: return kCFStringEncodingBig5; case SC_CHARSET_EASTEUROPE: return kCFStringEncodingWindowsLatin2; case SC_CHARSET_GB2312: return kCFStringEncodingGB_18030_2000; case SC_CHARSET_GREEK: return kCFStringEncodingWindowsGreek; case SC_CHARSET_HANGUL: return kCFStringEncodingEUC_KR; case SC_CHARSET_MAC: return kCFStringEncodingMacRoman; case SC_CHARSET_OEM: return kCFStringEncodingISOLatin1; case SC_CHARSET_RUSSIAN: return kCFStringEncodingKOI8_R; case SC_CHARSET_CYRILLIC: return kCFStringEncodingWindowsCyrillic; case SC_CHARSET_SHIFTJIS: return kCFStringEncodingShiftJIS; case SC_CHARSET_SYMBOL: return kCFStringEncodingMacSymbol; case SC_CHARSET_TURKISH: return kCFStringEncodingWindowsLatin5; case SC_CHARSET_JOHAB: return kCFStringEncodingWindowsKoreanJohab; case SC_CHARSET_HEBREW: return kCFStringEncodingWindowsHebrew; case SC_CHARSET_ARABIC: return kCFStringEncodingWindowsArabic; case SC_CHARSET_VIETNAMESE: return kCFStringEncodingWindowsVietnamese; case SC_CHARSET_THAI: return kCFStringEncodingISOLatinThai; case SC_CHARSET_8859_15: return kCFStringEncodingISOLatin1; default: return notSupported; } } void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore) { CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, FontCharacterSet(font_)); ColourDesired colour(fore.AsLong()); CGColorRef color = CGColorCreateGenericRGB(colour.GetRed()/255.0,colour.GetGreen()/255.0,colour.GetBlue()/255.0,1.0); QuartzTextStyle* style = reinterpret_cast<QuartzTextStyle*>(font_.GetID()); style->setCTStyleColor(color); CGColorRelease(color); textLayout->setText (reinterpret_cast<const UInt8*>(s), len, encoding, *reinterpret_cast<QuartzTextStyle*>(font_.GetID())); textLayout->draw(rc.left, ybase); } static size_t utf8LengthFromLead(unsigned char uch) { if (uch >= (0x80 + 0x40 + 0x20 + 0x10)) { return 4; } else if (uch >= (0x80 + 0x40 + 0x20)) { return 3; } else if (uch >= (0x80)) { return 2; } else { return 1; } } //-------------------------------------------------------------------------------------------------- void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) { CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, FontCharacterSet(font_)); textLayout->setText (reinterpret_cast<const UInt8*>(s), len, encoding, *reinterpret_cast<QuartzTextStyle*>(font_.GetID())); CTLineRef mLine = textLayout->getCTLine(); assert(mLine != NULL); if (unicodeMode) { // Map the widths given for UTF-16 characters back onto the UTF-8 input string CFIndex fit = textLayout->getStringLength(); int ui=0; const unsigned char *us = reinterpret_cast<const unsigned char *>(s); int i=0; while (ui<fit) { size_t lenChar = utf8LengthFromLead(us[i]); size_t codeUnits = (lenChar < 4) ? 1 : 2; CGFloat xPosition = CTLineGetOffsetForStringIndex(mLine, ui+1, NULL); for (unsigned int bytePos=0; (bytePos<lenChar) && (i<len); bytePos++) { positions[i++] = xPosition; } ui += codeUnits; } int lastPos = 0; if (i > 0) lastPos = positions[i-1]; while (i<len) { positions[i++] = lastPos; } } else if (codePage) { int ui = 0; for (int i=0;i<len;) { size_t lenChar = Platform::IsDBCSLeadByte(codePage, s[i]) ? 2 : 1; CGFloat xPosition = CTLineGetOffsetForStringIndex(mLine, ui+1, NULL); for (unsigned int bytePos=0; (bytePos<lenChar) && (i<len); bytePos++) { positions[i++] = xPosition; } ui++; } } else { // Single byte encoding for (int i=0;i<len;i++) { CGFloat xPosition = CTLineGetOffsetForStringIndex(mLine, i+1, NULL); positions[i] = xPosition; } } } XYPOSITION SurfaceImpl::WidthText(Font &font_, const char *s, int len) { if (font_.GetID()) { CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, FontCharacterSet(font_)); textLayout->setText (reinterpret_cast<const UInt8*>(s), len, encoding, *reinterpret_cast<QuartzTextStyle*>(font_.GetID())); return textLayout->MeasureStringWidth(); } return 1; } XYPOSITION SurfaceImpl::WidthChar(Font &font_, char ch) { char str[2] = { ch, '\0' }; if (font_.GetID()) { CFStringEncoding encoding = EncodingFromCharacterSet(unicodeMode, FontCharacterSet(font_)); textLayout->setText (reinterpret_cast<const UInt8*>(str), 1, encoding, *reinterpret_cast<QuartzTextStyle*>(font_.GetID())); return textLayout->MeasureStringWidth(); } else return 1; } // This string contains a good range of characters to test for size. const char sizeString[] = "`~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890" "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; XYPOSITION SurfaceImpl::Ascent(Font &font_) { if (!font_.GetID()) return 1; float ascent = reinterpret_cast<QuartzTextStyle*>( font_.GetID() )->getAscent(); return ascent + 0.5; } XYPOSITION SurfaceImpl::Descent(Font &font_) { if (!font_.GetID()) return 1; float descent = reinterpret_cast<QuartzTextStyle*>( font_.GetID() )->getDescent(); return descent + 0.5; } XYPOSITION SurfaceImpl::InternalLeading(Font &) { return 0; } XYPOSITION SurfaceImpl::ExternalLeading(Font &font_) { if (!font_.GetID()) return 1; float leading = reinterpret_cast<QuartzTextStyle*>( font_.GetID() )->getLeading(); return leading + 0.5; } XYPOSITION SurfaceImpl::Height(Font &font_) { int ht = Ascent(font_) + Descent(font_); return ht; } XYPOSITION SurfaceImpl::AverageCharWidth(Font &font_) { if (!font_.GetID()) return 1; const int sizeStringLength = (sizeof( sizeString ) / sizeof( sizeString[0] ) - 1); int width = WidthText( font_, sizeString, sizeStringLength ); return (int) ((width / (float) sizeStringLength) + 0.5); } void SurfaceImpl::SetClip(PRectangle rc) { CGContextClipToRect( gc, PRectangleToCGRect( rc ) ); } void SurfaceImpl::FlushCachedState() { CGContextSynchronize( gc ); } void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) { unicodeMode = unicodeMode_; } void SurfaceImpl::SetDBCSMode(int codePage_) { if (codePage_ && (codePage_ != SC_CP_UTF8)) codePage = codePage_; } Surface *Surface::Allocate(int) { return new SurfaceImpl(); } //----------------- Window ------------------------------------------------------------------------- // Cocoa uses different types for windows and views, so a Window may // be either an NSWindow or NSView and the code will check the type // before performing an action. Window::~Window() { } //-------------------------------------------------------------------------------------------------- void Window::Destroy() { if (wid) { id idWin = reinterpret_cast<id>(wid); if ([idWin isKindOfClass: [NSWindow class]]) { NSWindow* win = reinterpret_cast<NSWindow*>(idWin); [win release]; } } wid = 0; } //-------------------------------------------------------------------------------------------------- bool Window::HasFocus() { NSView* container = reinterpret_cast<NSView*>(wid); return [[container window] firstResponder] == container; } //-------------------------------------------------------------------------------------------------- static int ScreenMax(NSWindow* win) { NSScreen* screen = [win screen]; NSRect frame = [screen frame]; return frame.origin.y + frame.size.height; } PRectangle Window::GetPosition() { if (wid) { NSRect rect; id idWin = reinterpret_cast<id>(wid); NSWindow* win; if ([idWin isKindOfClass: [NSView class]]) { // NSView NSView* view = reinterpret_cast<NSView*>(idWin); win = [view window]; rect = [view convertRect: [view bounds] toView: nil]; rect.origin = [win convertBaseToScreen:rect.origin]; } else { // NSWindow win = reinterpret_cast<NSWindow*>(idWin); rect = [win frame]; } int screenHeight = ScreenMax(win); // Invert screen positions to match Scintilla return PRectangle( NSMinX(rect), screenHeight - NSMaxY(rect), NSMaxX(rect), screenHeight - NSMinY(rect)); } else { return PRectangle(0, 0, 1, 1); } } //-------------------------------------------------------------------------------------------------- void Window::SetPosition(PRectangle rc) { if (wid) { id idWin = reinterpret_cast<id>(wid); if ([idWin isKindOfClass: [NSView class]]) { // NSView // Moves this view inside the parent view NSRect nsrc = NSMakeRect(rc.left, rc.bottom, rc.Width(), rc.Height()); NSView* view = reinterpret_cast<NSView*>(idWin); nsrc.origin = [[view window] convertScreenToBase:nsrc.origin]; [view setFrame: nsrc]; } else { // NSWindow NSWindow* win = reinterpret_cast<NSWindow*>(idWin); int screenHeight = ScreenMax(win); NSRect nsrc = NSMakeRect(rc.left, screenHeight - rc.bottom, rc.Width(), rc.Height()); [win setFrame: nsrc display:YES]; } } } //-------------------------------------------------------------------------------------------------- void Window::SetPositionRelative(PRectangle rc, Window window) { PRectangle rcOther = window.GetPosition(); rc.left += rcOther.left; rc.right += rcOther.left; rc.top += rcOther.top; rc.bottom += rcOther.top; SetPosition(rc); } //-------------------------------------------------------------------------------------------------- PRectangle Window::GetClientPosition() { // This means, in MacOS X terms, get the "frame bounds". Call GetPosition, just like on Win32. return GetPosition(); } //-------------------------------------------------------------------------------------------------- void Window::Show(bool show) { if (wid) { id idWin = reinterpret_cast<id>(wid); if ([idWin isKindOfClass: [NSWindow class]]) { NSWindow* win = reinterpret_cast<NSWindow*>(idWin); if (show) { [win orderFront:nil]; } else { [win orderOut:nil]; } } } } //-------------------------------------------------------------------------------------------------- /** * Invalidates the entire window or view so it is completely redrawn. */ void Window::InvalidateAll() { if (wid) { id idWin = reinterpret_cast<id>(wid); NSView* container; if ([idWin isKindOfClass: [NSView class]]) { container = reinterpret_cast<NSView*>(idWin); } else { // NSWindow NSWindow* win = reinterpret_cast<NSWindow*>(idWin); container = reinterpret_cast<NSView*>([win contentView]); container.needsDisplay = YES; } container.needsDisplay = YES; } } //-------------------------------------------------------------------------------------------------- /** * Invalidates part of the window or view so only this part redrawn. */ void Window::InvalidateRectangle(PRectangle rc) { if (wid) { id idWin = reinterpret_cast<id>(wid); NSView* container; if ([idWin isKindOfClass: [NSView class]]) { container = reinterpret_cast<NSView*>(idWin); } else { // NSWindow NSWindow* win = reinterpret_cast<NSWindow*>(idWin); container = reinterpret_cast<NSView*>([win contentView]); } [container setNeedsDisplayInRect: PRectangleToNSRect(rc)]; } } //-------------------------------------------------------------------------------------------------- void Window::SetFont(Font&) { // Implemented on list subclass on Cocoa. } //-------------------------------------------------------------------------------------------------- /** * Converts the Scintilla cursor enum into an NSCursor and stores it in the associated NSView, * which then will take care to set up a new mouse tracking rectangle. */ void Window::SetCursor(Cursor curs) { if (wid) { id idWin = reinterpret_cast<id>(wid); if ([idWin isMemberOfClass: [InnerView class]]) { InnerView* container = reinterpret_cast<InnerView*>(idWin); [container setCursor: curs]; } } } //-------------------------------------------------------------------------------------------------- void Window::SetTitle(const char* s) { if (wid) { id idWin = reinterpret_cast<id>(wid); if ([idWin isKindOfClass: [NSWindow class]]) { NSWindow* win = reinterpret_cast<NSWindow*>(idWin); NSString* sTitle = [NSString stringWithUTF8String:s]; [win setTitle:sTitle]; } } } //-------------------------------------------------------------------------------------------------- PRectangle Window::GetMonitorRect(Point) { if (wid) { id idWin = reinterpret_cast<id>(wid); if ([idWin isKindOfClass: [NSWindow class]]) { NSWindow* win = reinterpret_cast<NSWindow*>(idWin); NSScreen* screen = [win screen]; NSRect rect = [screen frame]; int screenHeight = rect.origin.y + rect.size.height; // Invert screen positions to match Scintilla return PRectangle( NSMinX(rect), screenHeight - NSMaxY(rect), NSMaxX(rect), screenHeight - NSMinY(rect)); } } return PRectangle(); } //----------------- ImageFromXPM ------------------------------------------------------------------- // Convert an XPM image into an NSImage for use with Cocoa static NSImage* ImageFromXPM(XPM* pxpm) { NSImage* img = nil; if (pxpm) { const int width = pxpm->GetWidth(); const int height = pxpm->GetHeight(); PRectangle rcxpm(0, 0, width, height); Surface* surfaceXPM = Surface::Allocate(SC_TECHNOLOGY_DEFAULT); if (surfaceXPM) { surfaceXPM->InitPixMap(width, height, NULL, NULL); SurfaceImpl* surfaceIXPM = static_cast<SurfaceImpl*>(surfaceXPM); CGContextClearRect(surfaceIXPM->GetContext(), CGRectMake(0, 0, width, height)); pxpm->Draw(surfaceXPM, rcxpm); img = [[[NSImage alloc] initWithSize:NSZeroSize] autorelease]; CGImageRef imageRef = surfaceIXPM->GetImage(); NSBitmapImageRep *bitmapRep = [[NSBitmapImageRep alloc] initWithCGImage: imageRef]; [img addRepresentation: bitmapRep]; [bitmapRep release]; CGImageRelease(imageRef); delete surfaceXPM; } } return img; } //----------------- ListBox and related classes ---------------------------------------------------- namespace { // unnamed namespace hides IListBox interface class IListBox { public: virtual int Rows() = 0; virtual NSImage* ImageForRow(NSInteger row) = 0; virtual NSString* TextForRow(NSInteger row) = 0; virtual void DoubleClick() = 0; }; } // unnamed namespace //----------------- AutoCompletionDataSource ------------------------------------------------------- @interface AutoCompletionDataSource : NSObject #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 <NSTableViewDataSource> #endif { IListBox* box; } @property IListBox* box; @end @implementation AutoCompletionDataSource @synthesize box; - (void) doubleClick: (id) sender { #pragma unused(sender) if (box) { box->DoubleClick(); } } - (id)tableView: (NSTableView*)aTableView objectValueForTableColumn: (NSTableColumn*)aTableColumn row: (NSInteger)rowIndex { #pragma unused(aTableView) if (!box) return nil; if ([(NSString*)[aTableColumn identifier] isEqualToString: @"icon"]) { return box->ImageForRow(rowIndex); } else { return box->TextForRow(rowIndex); } } - (void)tableView: (NSTableView*)aTableView setObjectValue: anObject forTableColumn: (NSTableColumn*)aTableColumn row: (NSInteger)rowIndex { #pragma unused(aTableView) #pragma unused(anObject) #pragma unused(aTableColumn) #pragma unused(rowIndex) } - (NSInteger)numberOfRowsInTableView: (NSTableView*)aTableView { #pragma unused(aTableView) if (!box) return 0; return box->Rows(); } @end //----------------- ListBoxImpl -------------------------------------------------------------------- namespace { // unnamed namespace hides ListBoxImpl and associated classes struct RowData { int type; std::string text; RowData(int type_, const char* text_) : type(type_), text(text_) { } }; class LinesData { std::vector<RowData> lines; public: LinesData() { } ~LinesData() { } int Length() const { return static_cast<int>(lines.size()); } void Clear() { lines.clear(); } void Add(int /* index */, int type, char* str) { lines.push_back(RowData(type, str)); } int GetType(size_t index) const { if (index < lines.size()) { return lines[index].type; } else { return 0; } } const char* GetString(size_t index) const { if (index < lines.size()) { return lines[index].text.c_str(); } else { return 0; } } }; // Map from icon type to an NSImage* typedef std::map<NSInteger, NSImage*> ImageMap; class ListBoxImpl : public ListBox, IListBox { private: ImageMap images; int lineHeight; bool unicodeMode; int desiredVisibleRows; unsigned int maxItemWidth; unsigned int aveCharWidth; unsigned int maxIconWidth; Font font; int maxWidth; NSTableView* table; NSScrollView* scroller; NSTableColumn* colIcon; NSTableColumn* colText; AutoCompletionDataSource* ds; LinesData ld; CallBackAction doubleClickAction; void* doubleClickActionData; public: ListBoxImpl() : lineHeight(10), unicodeMode(false), desiredVisibleRows(5), maxItemWidth(0), aveCharWidth(8), maxIconWidth(0), doubleClickAction(NULL), doubleClickActionData(NULL) { } ~ListBoxImpl() {} // ListBox methods void SetFont(Font& font); void Create(Window& parent, int ctrlID, Scintilla::Point pt, int lineHeight_, bool unicodeMode_, int technology_); void SetAverageCharWidth(int width); void SetVisibleRows(int rows); int GetVisibleRows() const; PRectangle GetDesiredRect(); int CaretFromEdge(); void Clear(); void Append(char* s, int type = -1); int Length(); void Select(int n); int GetSelection(); int Find(const char* prefix); void GetValue(int n, char* value, int len); void RegisterImage(int type, const char* xpm_data); void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage); void ClearRegisteredImages(); void SetDoubleClickAction(CallBackAction action, void* data) { doubleClickAction = action; doubleClickActionData = data; } void SetList(const char* list, char separator, char typesep); // For access from AutoCompletionDataSource implement IListBox int Rows(); NSImage* ImageForRow(NSInteger row); NSString* TextForRow(NSInteger row); void DoubleClick(); }; void ListBoxImpl::Create(Window& /*parent*/, int /*ctrlID*/, Scintilla::Point pt, int lineHeight_, bool unicodeMode_, int) { lineHeight = lineHeight_; unicodeMode = unicodeMode_; maxWidth = 2000; NSRect lbRect = NSMakeRect(pt.x,pt.y, 120, lineHeight * desiredVisibleRows); NSWindow* winLB = [[NSWindow alloc] initWithContentRect: lbRect styleMask: NSBorderlessWindowMask backing: NSBackingStoreBuffered defer: NO]; [winLB setLevel:NSFloatingWindowLevel]; [winLB setHasShadow:YES]; scroller = [NSScrollView alloc]; NSRect scRect = NSMakeRect(0, 0, lbRect.size.width, lbRect.size.height); [scroller initWithFrame: scRect]; [scroller setHasVerticalScroller:YES]; table = [[NSTableView alloc] initWithFrame: scRect]; [table setHeaderView:nil]; [scroller setDocumentView: table]; colIcon = [[NSTableColumn alloc] initWithIdentifier:@"icon"]; [colIcon setWidth: 20]; [colIcon setEditable:NO]; [colIcon setHidden:YES]; NSImageCell* imCell = [[[NSImageCell alloc] init] autorelease]; [colIcon setDataCell:imCell]; [table addTableColumn:colIcon]; colText = [[NSTableColumn alloc] initWithIdentifier:@"name"]; [colText setResizingMask:NSTableColumnAutoresizingMask]; [colText setEditable:NO]; [table addTableColumn:colText]; ds = [[AutoCompletionDataSource alloc] init]; [ds setBox:this]; [table setDataSource: ds]; // Weak reference [scroller setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; [[winLB contentView] addSubview: scroller]; [table setTarget:ds]; [table setDoubleAction:@selector(doubleClick:)]; wid = winLB; } void ListBoxImpl::SetFont(Font& font_) { // NSCell setFont takes an NSFont* rather than a CTFontRef but they // are the same thing toll-free bridged. QuartzTextStyle* style = reinterpret_cast<QuartzTextStyle*>(font_.GetID()); font.Release(); font.SetID(new QuartzTextStyle(*style)); NSFont *pfont = (NSFont *)style->getFontRef(); [[colText dataCell] setFont: pfont]; CGFloat itemHeight = ceil([pfont boundingRectForFont].size.height); [table setRowHeight:itemHeight]; } void ListBoxImpl::SetAverageCharWidth(int width) { aveCharWidth = width; } void ListBoxImpl::SetVisibleRows(int rows) { desiredVisibleRows = rows; } int ListBoxImpl::GetVisibleRows() const { return desiredVisibleRows; } PRectangle ListBoxImpl::GetDesiredRect() { PRectangle rcDesired; rcDesired = GetPosition(); // There appears to be an extra pixel above and below the row contents int itemHeight = [table rowHeight] + 2; int rows = Length(); if ((rows == 0) || (rows > desiredVisibleRows)) rows = desiredVisibleRows; rcDesired.bottom = rcDesired.top + itemHeight * rows; rcDesired.right = rcDesired.left + maxItemWidth + aveCharWidth; if (Length() > rows) { [scroller setHasVerticalScroller:YES]; rcDesired.right += [NSScroller scrollerWidth]; } else { [scroller setHasVerticalScroller:NO]; } rcDesired.right += maxIconWidth; rcDesired.right += 6; return rcDesired; } int ListBoxImpl::CaretFromEdge() { if ([colIcon isHidden]) return 3; else return 6 + [colIcon width]; } void ListBoxImpl::Clear() { maxItemWidth = 0; maxIconWidth = 0; ld.Clear(); } void ListBoxImpl::Append(char* s, int type) { int count = Length(); ld.Add(count, type, s); Scintilla::SurfaceImpl surface; unsigned int width = surface.WidthText(font, s, static_cast<int>(strlen(s))); if (width > maxItemWidth) { maxItemWidth = width; [colText setWidth: maxItemWidth]; } ImageMap::iterator it = images.find(type); if (it != images.end()) { NSImage* img = it->second; if (img) { unsigned int widthIcon = img.size.width; if (widthIcon > maxIconWidth) { [colIcon setHidden: NO]; maxIconWidth = widthIcon; [colIcon setWidth: maxIconWidth]; } } } } void ListBoxImpl::SetList(const char* list, char separator, char typesep) { Clear(); size_t count = strlen(list) + 1; char* words = new char[count]; if (words) { memcpy(words, list, count); char* startword = words; char* numword = NULL; int i = 0; for (; words[i]; i++) { if (words[i] == separator) { words[i] = '\0'; if (numword) *numword = '\0'; Append(startword, numword?atoi(numword + 1):-1); startword = words + i + 1; numword = NULL; } else if (words[i] == typesep) { numword = words + i; } } if (startword) { if (numword) *numword = '\0'; Append(startword, numword?atoi(numword + 1):-1); } delete []words; } [table reloadData]; } int ListBoxImpl::Length() { return ld.Length(); } void ListBoxImpl::Select(int n) { [table selectRowIndexes:[NSIndexSet indexSetWithIndex:n] byExtendingSelection:NO]; [table scrollRowToVisible:n]; } int ListBoxImpl::GetSelection() { return static_cast<int>([table selectedRow]); } int ListBoxImpl::Find(const char* prefix) { int count = Length(); for (int i = 0; i < count; i++) { const char* s = ld.GetString(i); if (s && (s[0] != '\0') && (0 == strncmp(prefix, s, strlen(prefix)))) { return i; } } return - 1; } void ListBoxImpl::GetValue(int n, char* value, int len) { const char* textString = ld.GetString(n); if (textString == NULL) { value[0] = '\0'; return; } strncpy(value, textString, len); value[len - 1] = '\0'; } void ListBoxImpl::RegisterImage(int type, const char* xpm_data) { XPM xpm(xpm_data); NSImage* img = ImageFromXPM(&xpm); [img retain]; ImageMap::iterator it=images.find(type); if (it == images.end()) { images[type] = img; } else { [it->second release]; it->second = img; } } void ListBoxImpl::RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) { CGImageRef imageRef = ImageCreateFromRGBA(width, height, pixelsImage, false); NSSize sz = {static_cast<CGFloat>(width), static_cast<CGFloat>(height)}; NSImage *img = [[[NSImage alloc] initWithSize: sz] autorelease]; NSBitmapImageRep *bitmapRep = [[NSBitmapImageRep alloc] initWithCGImage: imageRef]; [img addRepresentation: bitmapRep]; [bitmapRep release]; CGImageRelease(imageRef); [img retain]; ImageMap::iterator it=images.find(type); if (it == images.end()) { images[type] = img; } else { [it->second release]; it->second = img; } } void ListBoxImpl::ClearRegisteredImages() { for (ImageMap::iterator it=images.begin(); it != images.end(); ++it) { [it->second release]; it->second = nil; } images.clear(); } int ListBoxImpl::Rows() { return ld.Length(); } NSImage* ListBoxImpl::ImageForRow(NSInteger row) { ImageMap::iterator it = images.find(ld.GetType(row)); if (it != images.end()) { NSImage* img = it->second; return img; } else { return nil; } } NSString* ListBoxImpl::TextForRow(NSInteger row) { const char* textString = ld.GetString(row); NSString* sTitle; if (unicodeMode) sTitle = [NSString stringWithUTF8String:textString]; else sTitle = [NSString stringWithCString:textString encoding:NSWindowsCP1252StringEncoding]; return sTitle; } void ListBoxImpl::DoubleClick() { if (doubleClickAction) { doubleClickAction(doubleClickActionData); } } } // unnamed namespace //----------------- ListBox ------------------------------------------------------------------------ ListBox::ListBox() { } ListBox::~ListBox() { } ListBox* ListBox::Allocate() { ListBoxImpl* lb = new ListBoxImpl(); return lb; } //----------------- ScintillaContextMenu ----------------------------------------------------------- @implementation ScintillaContextMenu : NSMenu // This NSMenu subclass serves also as target for menu commands and forwards them as // notfication messages to the front end. - (void) handleCommand: (NSMenuItem*) sender { owner->HandleCommand([sender tag]); } //-------------------------------------------------------------------------------------------------- - (void) setOwner: (Scintilla::ScintillaCocoa*) newOwner { owner = newOwner; } @end //----------------- Menu --------------------------------------------------------------------------- Menu::Menu() : mid(0) { } //-------------------------------------------------------------------------------------------------- void Menu::CreatePopUp() { Destroy(); mid = [[ScintillaContextMenu alloc] initWithTitle: @""]; } //-------------------------------------------------------------------------------------------------- void Menu::Destroy() { ScintillaContextMenu* menu = reinterpret_cast<ScintillaContextMenu*>(mid); [menu release]; mid = NULL; } //-------------------------------------------------------------------------------------------------- void Menu::Show(Point, Window &) { // Cocoa menus are handled a bit differently. We only create the menu. The framework // takes care to show it properly. } //----------------- ElapsedTime -------------------------------------------------------------------- // ElapsedTime is used for precise performance measurements during development // and not for anything a user sees. ElapsedTime::ElapsedTime() { struct timeval curTime; gettimeofday( &curTime, NULL ); bigBit = curTime.tv_sec; littleBit = curTime.tv_usec; } double ElapsedTime::Duration(bool reset) { struct timeval curTime; gettimeofday( &curTime, NULL ); long endBigBit = curTime.tv_sec; long endLittleBit = curTime.tv_usec; double result = 1000000.0 * (endBigBit - bigBit); result += endLittleBit - littleBit; result /= 1000000.0; if (reset) { bigBit = endBigBit; littleBit = endLittleBit; } return result; } //----------------- Platform ----------------------------------------------------------------------- ColourDesired Platform::Chrome() { return ColourDesired(0xE0, 0xE0, 0xE0); } //-------------------------------------------------------------------------------------------------- ColourDesired Platform::ChromeHighlight() { return ColourDesired(0xFF, 0xFF, 0xFF); } //-------------------------------------------------------------------------------------------------- /** * Returns the currently set system font for the user. */ const char *Platform::DefaultFont() { NSString* name = [[NSUserDefaults standardUserDefaults] stringForKey: @"NSFixedPitchFont"]; return [name UTF8String]; } //-------------------------------------------------------------------------------------------------- /** * Returns the currently set system font size for the user. */ int Platform::DefaultFontSize() { return static_cast<int>([[NSUserDefaults standardUserDefaults] integerForKey: @"NSFixedPitchFontSize"]); } //-------------------------------------------------------------------------------------------------- /** * Returns the time span in which two consequtive mouse clicks must occur to be considered as * double click. * * @return */ unsigned int Platform::DoubleClickTime() { float threshold = [[NSUserDefaults standardUserDefaults] floatForKey: @"com.apple.mouse.doubleClickThreshold"]; if (threshold == 0) threshold = 0.5; return static_cast<unsigned int>(threshold * 1000.0); } //-------------------------------------------------------------------------------------------------- bool Platform::MouseButtonBounce() { return false; } //-------------------------------------------------------------------------------------------------- /** * Helper method for the backend to reach through to the scintilla window. */ long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, long lParam) { return scintilla_send_message(w, msg, wParam, lParam); } //-------------------------------------------------------------------------------------------------- /** * Helper method for the backend to reach through to the scintilla window. */ long Platform::SendScintillaPointer(WindowID w, unsigned int msg, unsigned long wParam, void *lParam) { return scintilla_send_message(w, msg, wParam, (long) lParam); } //-------------------------------------------------------------------------------------------------- bool Platform::IsDBCSLeadByte(int codePage, char ch) { // Byte ranges found in Wikipedia articles with relevant search strings in each case unsigned char uch = static_cast<unsigned char>(ch); switch (codePage) { case 932: // Shift_jis return ((uch >= 0x81) && (uch <= 0x9F)) || ((uch >= 0xE0) && (uch <= 0xFC)); // Lead bytes F0 to FC may be a Microsoft addition. case 936: // GBK return (uch >= 0x81) && (uch <= 0xFE); case 949: // Korean Wansung KS C-5601-1987 return (uch >= 0x81) && (uch <= 0xFE); case 950: // Big5 return (uch >= 0x81) && (uch <= 0xFE); case 1361: // Korean Johab KS C-5601-1992 return ((uch >= 0x84) && (uch <= 0xD3)) || ((uch >= 0xD8) && (uch <= 0xDE)) || ((uch >= 0xE0) && (uch <= 0xF9)); } return false; } //-------------------------------------------------------------------------------------------------- int Platform::DBCSCharLength(int /* codePage */, const char* /* s */) { // DBCS no longer uses this. return 1; } //-------------------------------------------------------------------------------------------------- int Platform::DBCSCharMaxLength() { return 2; } //-------------------------------------------------------------------------------------------------- int Platform::Minimum(int a, int b) { return (a < b) ? a : b; } //-------------------------------------------------------------------------------------------------- int Platform::Maximum(int a, int b) { return (a > b) ? a : b; } //-------------------------------------------------------------------------------------------------- //#define TRACE #ifdef TRACE void Platform::DebugDisplay(const char *s) { fprintf( stderr, "%s", s ); } //-------------------------------------------------------------------------------------------------- void Platform::DebugPrintf(const char *format, ...) { const int BUF_SIZE = 2000; char buffer[BUF_SIZE]; va_list pArguments; va_start(pArguments, format); vsnprintf(buffer, BUF_SIZE, format, pArguments); va_end(pArguments); Platform::DebugDisplay(buffer); } #else void Platform::DebugDisplay(const char *) {} void Platform::DebugPrintf(const char *, ...) {} #endif //-------------------------------------------------------------------------------------------------- static bool assertionPopUps = true; bool Platform::ShowAssertionPopUps(bool assertionPopUps_) { bool ret = assertionPopUps; assertionPopUps = assertionPopUps_; return ret; } //-------------------------------------------------------------------------------------------------- void Platform::Assert(const char *c, const char *file, int line) { char buffer[2000]; sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line); strcat(buffer, "\r\n"); Platform::DebugDisplay(buffer); #ifdef DEBUG // Jump into debugger in assert on Mac (CL269835) ::Debugger(); #endif } //-------------------------------------------------------------------------------------------------- int Platform::Clamp(int val, int minVal, int maxVal) { if (val > maxVal) val = maxVal; if (val < minVal) val = minVal; return val; } //----------------- DynamicLibrary ----------------------------------------------------------------- /** * Implements the platform specific part of library loading. * * @param modulePath The path to the module to load. * @return A library instance or NULL if the module could not be found or another problem occured. */ DynamicLibrary* DynamicLibrary::Load(const char* /* modulePath */) { // Not implemented. return NULL; } //-------------------------------------------------------------------------------------------------- |
Added cocoa/QuartzTextLayout.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
/* * QuartzTextLayout.h * * Original Code by Evan Jones on Wed Oct 02 2002. * Contributors: * Shane Caraveo, ActiveState * Bernd Paradies, Adobe * */ #ifndef _QUARTZ_TEXT_LAYOUT_H #define _QUARTZ_TEXT_LAYOUT_H #include <Cocoa/Cocoa.h> #include "QuartzTextStyle.h" class QuartzTextLayout { public: /** Create a text layout for drawing on the specified context. */ QuartzTextLayout( CGContextRef context ) { mString = NULL; mLine = NULL; stringLength = 0; setContext(context); } ~QuartzTextLayout() { if ( mString != NULL ) { CFRelease(mString); mString = NULL; } if ( mLine != NULL ) { CFRelease(mLine); mLine = NULL; } } inline void setText( const UInt8* buffer, size_t byteLength, CFStringEncoding encoding, const QuartzTextStyle& r ) { CFStringRef str = CFStringCreateWithBytes( NULL, buffer, byteLength, encoding, false ); if (!str) return; stringLength = CFStringGetLength(str); CFMutableDictionaryRef stringAttribs = r.getCTStyle(); if (mString != NULL) CFRelease(mString); mString = ::CFAttributedStringCreate(NULL, str, stringAttribs); if (mLine != NULL) CFRelease(mLine); mLine = ::CTLineCreateWithAttributedString(mString); CFRelease( str ); } /** Draw the text layout into the current CGContext at the specified position. * @param x The x axis position to draw the baseline in the current CGContext. * @param y The y axis position to draw the baseline in the current CGContext. */ void draw( float x, float y ) { if (mLine == NULL) return; ::CGContextSetTextMatrix(gc, CGAffineTransformMakeScale(1.0, -1.0)); // Set the text drawing position. ::CGContextSetTextPosition(gc, x, y); // And finally, draw! ::CTLineDraw(mLine, gc); } float MeasureStringWidth() { if (mLine == NULL) return 0.0f; return ::CTLineGetTypographicBounds(mLine, NULL, NULL, NULL); } CTLineRef getCTLine() { return mLine; } CFIndex getStringLength() { return stringLength; } inline void setContext (CGContextRef context) { gc = context; } private: CGContextRef gc; CFAttributedStringRef mString; CTLineRef mLine; CFIndex stringLength; }; #endif |
Added cocoa/QuartzTextStyle.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
/* * QuartzTextStyle.h * * Created by Evan Jones on Wed Oct 02 2002. * */ #ifndef _QUARTZ_TEXT_STYLE_H #define _QUARTZ_TEXT_STYLE_H #include "QuartzTextStyleAttribute.h" class QuartzTextStyle { public: QuartzTextStyle() { fontRef = NULL; styleDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); characterSet = 0; } QuartzTextStyle(const QuartzTextStyle &other) { // Does not copy font colour attribute fontRef = static_cast<CTFontRef>(CFRetain(other.fontRef)); styleDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionaryAddValue(styleDict, kCTFontAttributeName, fontRef); characterSet = other.characterSet; } ~QuartzTextStyle() { if (styleDict != NULL) { CFRelease(styleDict); styleDict = NULL; } if (fontRef) { CFRelease(fontRef); fontRef = NULL; } } CFMutableDictionaryRef getCTStyle() const { return styleDict; } void setCTStyleColor(CGColor *inColor) { CFDictionarySetValue(styleDict, kCTForegroundColorAttributeName, inColor); } float getAscent() const { return ::CTFontGetAscent(fontRef); } float getDescent() const { return ::CTFontGetDescent(fontRef); } float getLeading() const { return ::CTFontGetLeading(fontRef); } void setFontRef(CTFontRef inRef, int characterSet_) { fontRef = inRef; characterSet = characterSet_; if (styleDict != NULL) CFRelease(styleDict); styleDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionaryAddValue(styleDict, kCTFontAttributeName, fontRef); } CTFontRef getFontRef() { return fontRef; } int getCharacterSet() { return characterSet; } private: CFMutableDictionaryRef styleDict; CTFontRef fontRef; int characterSet; }; #endif |
Added cocoa/QuartzTextStyleAttribute.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
/** * QuartzTextStyleAttribute.h * * Original Code by Evan Jones on Wed Oct 02 2002. * Contributors: * Shane Caraveo, ActiveState * Bernd Paradies, Adobe * */ #ifndef _QUARTZ_TEXT_STYLE_ATTRIBUTE_H #define _QUARTZ_TEXT_STYLE_ATTRIBUTE_H class QuartzFont { public: /** Create a font style from a name. */ QuartzFont( const char* name, size_t length, float size, int weight, bool italic ) { assert( name != NULL && length > 0 && name[length] == '\0' ); CFStringRef fontName = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingMacRoman); assert(fontName != NULL); bool bold = weight > SC_WEIGHT_NORMAL; if (bold || italic) { CTFontSymbolicTraits desiredTrait = 0; CTFontSymbolicTraits traitMask = 0; // if bold was specified, add the trait if (bold) { desiredTrait |= kCTFontBoldTrait; traitMask |= kCTFontBoldTrait; } // if italic was specified, add the trait if (italic) { desiredTrait |= kCTFontItalicTrait; traitMask |= kCTFontItalicTrait; } // create a font and then a copy of it with the sym traits CTFontRef iFont = ::CTFontCreateWithName(fontName, size, NULL); fontid = ::CTFontCreateCopyWithSymbolicTraits(iFont, size, NULL, desiredTrait, traitMask); if (fontid) { CFRelease(iFont); } else { // Traits failed so use base font fontid = iFont; } } else { // create the font, no traits fontid = ::CTFontCreateWithName(fontName, size, NULL); } if (!fontid) { // Failed to create requested font so use font always present fontid = ::CTFontCreateWithName((CFStringRef)@"Monaco", size, NULL); } CFRelease(fontName); } CTFontRef getFontID() { return fontid; } private: CTFontRef fontid; }; #endif |
Added cocoa/SciTest.mk.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
### start defines ### include common.mk NAME=Demo LD=gcc $(ARCH) -framework Cocoa TARG=$(APP)/Contents/MacOS/$(NAME) APP=$(APP_BLD)/$(NAME).app all: $(APP_BLD) $(TARG) $(APP): -rm -rf $(APP) -mkdir $(APP) -mkdir $(APP)/Contents/ -mkdir $(APP)/Contents/Frameworks/ -mkdir $(APP)/Contents/MacOS/ -mkdir $(APP)/Contents/Resources/ -cp ScintillaTest/Info.plist $(APP)/Contents/Info.plist.bak -sed "s/\$${EXECUTABLE_NAME}/$(NAME)/g" < $(APP)/Contents/Info.plist.bak > $(APP)/Contents/Info.plist.bak2 -sed "s/\$${PRODUCT_NAME}/$(NAME)/g" < $(APP)/Contents/Info.plist.bak2 > $(APP)/Contents/Info.plist -rm $(APP)/Contents/Info.plist.bak $(APP)/Contents/Info.plist.bak2 -cp -r ScintillaTest/English.lproj $(APP)/Contents/Resources/ /Developer/usr/bin/ibtool --errors --warnings --notices --output-format human-readable-text \ --compile $(APP)/Contents/Resources/English.lproj/MainMenu.nib ScintillaTest/English.lproj/MainMenu.xib -cp ScintillaTest/TestData.sql $(APP)/Contents/Resources/ -make -f Framework.mk all $(TARG) : $(APP_BLD)/main.o $(APP_BLD)/AppController.o $(APP) -cp -R $(FRM_BLD)/Sci.framework $(APP)/Contents/Frameworks/ $(LD) $(APP_BLD)/main.o $(APP_BLD)/AppController.o $(APP)/Contents/Frameworks/Sci.framework/Sci -o $(TARG) -lstdc++ $(APP_BLD) : -mkdir $(BLD) -mkdir $(APP_BLD) |
Added cocoa/ScintillaCocoa.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
/* * ScintillaCocoa.h * * Mike Lischke <mlischke@sun.com> * * Based on ScintillaMacOSX.h * Original code by Evan Jones on Sun Sep 01 2002. * Contributors: * Shane Caraveo, ActiveState * Bernd Paradies, Adobe * * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). */ #include <stdlib.h> #include <string> #include <stdio.h> #include <ctype.h> #include <time.h> #include <vector> #include <map> #include "ILexer.h" #ifdef SCI_LEXER #include "SciLexer.h" #include "PropSetSimple.h" #endif #include "SVector.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" #include "ContractionState.h" #include "CellBuffer.h" #include "CallTip.h" #include "KeyMap.h" #include "Indicator.h" #include "XPM.h" #include "LineMarker.h" #include "Style.h" #include "AutoComplete.h" #include "ViewStyle.h" #include "CharClassify.h" #include "Decoration.h" #include "Document.h" #include "Selection.h" #include "PositionCache.h" #include "Editor.h" #include "ScintillaBase.h" extern "C" NSString* ScintillaRecPboardType; @class InnerView; @class MarginView; @class ScintillaView; @class FindHighlightLayer; /** * Helper class to be used as timer target (NSTimer). */ @interface TimerTarget : NSObject { void* mTarget; NSNotificationQueue* notificationQueue; } - (id) init: (void*) target; - (void) timerFired: (NSTimer*) timer; - (void) idleTimerFired: (NSTimer*) timer; - (void) idleTriggered: (NSNotification*) notification; @end namespace Scintilla { /** * On the Mac, there is no WM_COMMAND or WM_NOTIFY message that can be sent * back to the parent. Therefore, there must be a callback handler that acts * like a Windows WndProc, where Scintilla can send notifications to. Use * ScintillaCocoa::RegisterNotifyHandler() to register such a handler. * Message format is: * <br> * WM_COMMAND: HIWORD (wParam) = notification code, LOWORD (wParam) = 0 (no control ID), lParam = ScintillaCocoa* * <br> * WM_NOTIFY: wParam = 0 (no control ID), lParam = ptr to SCNotification structure, with hwndFrom set to ScintillaCocoa* */ typedef void(*SciNotifyFunc) (intptr_t windowid, unsigned int iMessage, uintptr_t wParam, uintptr_t lParam); /** * Scintilla sends these two messages to the nofity handler. Please refer * to the Windows API doc for details about the message format. */ #define WM_COMMAND 1001 #define WM_NOTIFY 1002 /** * Main scintilla class, implemented for OS X (Cocoa). */ class ScintillaCocoa : public ScintillaBase { private: TimerTarget* timerTarget; NSEvent* lastMouseEvent; SciNotifyFunc notifyProc; intptr_t notifyObj; bool capturedMouse; bool enteredSetScrollingSize; // Private so ScintillaCocoa objects can not be copied ScintillaCocoa(const ScintillaCocoa &) : ScintillaBase() {} ScintillaCocoa &operator=(const ScintillaCocoa &) { return * this; } bool GetPasteboardData(NSPasteboard* board, SelectionText* selectedText); void SetPasteboardData(NSPasteboard* board, const SelectionText& selectedText); int scrollSpeed; int scrollTicks; NSTimer* tickTimer; NSTimer* idleTimer; CFRunLoopObserverRef observer; FindHighlightLayer *layerFindIndicator; protected: Point GetVisibleOriginInMain(); PRectangle GetClientRectangle(); Point ConvertPoint(NSPoint point); virtual void Initialise(); virtual void Finalise(); virtual CaseFolder *CaseFolderForEncoding(); virtual std::string CaseMapString(const std::string &s, int caseMapping); virtual void CancelModes(); public: ScintillaCocoa(InnerView* view, MarginView* viewMargin); virtual ~ScintillaCocoa(); void RegisterNotifyCallback(intptr_t windowid, SciNotifyFunc callback); sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); ScintillaView* TopContainer(); NSScrollView* ScrollContainer(); InnerView* ContentView(); bool SyncPaint(void* gc, PRectangle rc); bool Draw(NSRect rect, CGContextRef gc); void PaintMargin(NSRect aRect); virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); void SetTicking(bool on); bool SetIdle(bool on); void SetMouseCapture(bool on); bool HaveMouseCapture(); void ScrollText(int linesToMove); void SetVerticalScrollPos(); void SetHorizontalScrollPos(); bool ModifyScrollBars(int nMax, int nPage); bool SetScrollingSize(void); void Resize(); void UpdateForScroll(); // Notifications for the owner. void NotifyChange(); void NotifyFocus(bool focus); void NotifyParent(SCNotification scn); void NotifyURIDropped(const char *uri); bool HasSelection(); bool CanUndo(); bool CanRedo(); virtual void CopyToClipboard(const SelectionText &selectedText); virtual void Copy(); virtual bool CanPaste(); virtual void Paste(); virtual void Paste(bool rectangular); void CTPaint(void* gc, NSRect rc); void CallTipMouseDown(NSPoint pt); virtual void CreateCallTipWindow(PRectangle rc); virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true); virtual void ClaimSelection(); NSPoint GetCaretPosition(); static sptr_t DirectFunction(ScintillaCocoa *sciThis, unsigned int iMessage, uptr_t wParam, sptr_t lParam); void TimerFired(NSTimer* timer); void IdleTimerFired(); static void UpdateObserver(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *sci); void ObserverAdd(); void ObserverRemove(); virtual void IdleWork(); virtual void QueueIdleWork(WorkNeeded::workItems items, int upTo); int InsertText(NSString* input); bool KeyboardInput(NSEvent* event); void MouseDown(NSEvent* event); void MouseMove(NSEvent* event); void MouseUp(NSEvent* event); void MouseEntered(NSEvent* event); void MouseExited(NSEvent* event); void MouseWheel(NSEvent* event); // Drag and drop void StartDrag(); bool GetDragData(id <NSDraggingInfo> info, NSPasteboard &pasteBoard, SelectionText* selectedText); NSDragOperation DraggingEntered(id <NSDraggingInfo> info); NSDragOperation DraggingUpdated(id <NSDraggingInfo> info); void DraggingExited(id <NSDraggingInfo> info); bool PerformDragOperation(id <NSDraggingInfo> info); void DragScroll(); // Promote some methods needed for NSResponder actions. virtual void SelectAll(); void DeleteBackward(); virtual void Cut(); virtual void Undo(); virtual void Redo(); virtual NSMenu* CreateContextMenu(NSEvent* event); void HandleCommand(NSInteger command); virtual void ActiveStateChanged(bool isActive); // Find indicator void ShowFindIndicatorForRange(NSRange charRange, BOOL retaining); void MoveFindIndicatorWithBounce(BOOL bounce); void HideFindIndicator(); }; } |
Added cocoa/ScintillaCocoa.mm.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 |
/** * Scintilla source code edit control * ScintillaCocoa.mm - Cocoa subclass of ScintillaBase * * Written by Mike Lischke <mlischke@sun.com> * * Loosely based on ScintillaMacOSX.cxx. * Copyright 2003 by Evan Jones <ejones@uwaterloo.ca> * Based on ScintillaGTK.cxx Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> * The License.txt file describes the conditions under which this software may be distributed. * * Copyright (c) 2009, 2010 Sun Microsystems, Inc. All rights reserved. * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). */ #import <Cocoa/Cocoa.h> #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 #import <QuartzCore/CAGradientLayer.h> #endif #import <QuartzCore/CAAnimation.h> #import <QuartzCore/CATransaction.h> #include "ScintillaView.h" #include "PlatCocoa.h" using namespace Scintilla; #ifndef WM_UNICHAR #define WM_UNICHAR 0x0109 #endif NSString* ScintillaRecPboardType = @"com.scintilla.utf16-plain-text.rectangular"; //-------------------------------------------------------------------------------------------------- // Define keyboard shortcuts (equivalents) the Mac way. #define SCI_CMD ( SCI_CTRL) #define SCI_SCMD ( SCI_CMD | SCI_SHIFT) #define SCI_SMETA ( SCI_META | SCI_SHIFT) static const KeyToCommand macMapDefault[] = { // OS X specific {SCK_DOWN, SCI_CTRL, SCI_DOCUMENTEND}, {SCK_DOWN, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND}, {SCK_UP, SCI_CTRL, SCI_DOCUMENTSTART}, {SCK_UP, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND}, {SCK_LEFT, SCI_CTRL, SCI_VCHOME}, {SCK_LEFT, SCI_CSHIFT, SCI_VCHOMEEXTEND}, {SCK_RIGHT, SCI_CTRL, SCI_LINEEND}, {SCK_RIGHT, SCI_CSHIFT, SCI_LINEENDEXTEND}, // Similar to Windows and GTK+ // Where equivalent clashes with OS X standard, use Meta instead {SCK_DOWN, SCI_NORM, SCI_LINEDOWN}, {SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND}, {SCK_DOWN, SCI_META, SCI_LINESCROLLDOWN}, {SCK_DOWN, SCI_ASHIFT, SCI_LINEDOWNRECTEXTEND}, {SCK_UP, SCI_NORM, SCI_LINEUP}, {SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND}, {SCK_UP, SCI_META, SCI_LINESCROLLUP}, {SCK_UP, SCI_ASHIFT, SCI_LINEUPRECTEXTEND}, {'[', SCI_CTRL, SCI_PARAUP}, {'[', SCI_CSHIFT, SCI_PARAUPEXTEND}, {']', SCI_CTRL, SCI_PARADOWN}, {']', SCI_CSHIFT, SCI_PARADOWNEXTEND}, {SCK_LEFT, SCI_NORM, SCI_CHARLEFT}, {SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND}, {SCK_LEFT, SCI_ALT, SCI_WORDLEFT}, {SCK_LEFT, SCI_META, SCI_WORDLEFT}, {SCK_LEFT, SCI_SMETA, SCI_WORDLEFTEXTEND}, {SCK_LEFT, SCI_ASHIFT, SCI_CHARLEFTRECTEXTEND}, {SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT}, {SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND}, {SCK_RIGHT, SCI_ALT, SCI_WORDRIGHT}, {SCK_RIGHT, SCI_META, SCI_WORDRIGHT}, {SCK_RIGHT, SCI_SMETA, SCI_WORDRIGHTEXTEND}, {SCK_RIGHT, SCI_ASHIFT, SCI_CHARRIGHTRECTEXTEND}, {'/', SCI_CTRL, SCI_WORDPARTLEFT}, {'/', SCI_CSHIFT, SCI_WORDPARTLEFTEXTEND}, {'\\', SCI_CTRL, SCI_WORDPARTRIGHT}, {'\\', SCI_CSHIFT, SCI_WORDPARTRIGHTEXTEND}, {SCK_HOME, SCI_NORM, SCI_VCHOME}, {SCK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND}, {SCK_HOME, SCI_CTRL, SCI_DOCUMENTSTART}, {SCK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND}, {SCK_HOME, SCI_ALT, SCI_HOMEDISPLAY}, {SCK_HOME, SCI_ASHIFT, SCI_VCHOMERECTEXTEND}, {SCK_END, SCI_NORM, SCI_LINEEND}, {SCK_END, SCI_SHIFT, SCI_LINEENDEXTEND}, {SCK_END, SCI_CTRL, SCI_DOCUMENTEND}, {SCK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND}, {SCK_END, SCI_ALT, SCI_LINEENDDISPLAY}, {SCK_END, SCI_ASHIFT, SCI_LINEENDRECTEXTEND}, {SCK_PRIOR, SCI_NORM, SCI_PAGEUP}, {SCK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND}, {SCK_PRIOR, SCI_ASHIFT, SCI_PAGEUPRECTEXTEND}, {SCK_NEXT, SCI_NORM, SCI_PAGEDOWN}, {SCK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND}, {SCK_NEXT, SCI_ASHIFT, SCI_PAGEDOWNRECTEXTEND}, {SCK_DELETE, SCI_NORM, SCI_CLEAR}, {SCK_DELETE, SCI_SHIFT, SCI_CUT}, {SCK_DELETE, SCI_CTRL, SCI_DELWORDRIGHT}, {SCK_DELETE, SCI_CSHIFT, SCI_DELLINERIGHT}, {SCK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE}, {SCK_INSERT, SCI_SHIFT, SCI_PASTE}, {SCK_INSERT, SCI_CTRL, SCI_COPY}, {SCK_ESCAPE, SCI_NORM, SCI_CANCEL}, {SCK_BACK, SCI_NORM, SCI_DELETEBACK}, {SCK_BACK, SCI_SHIFT, SCI_DELETEBACK}, {SCK_BACK, SCI_CTRL, SCI_DELWORDLEFT}, {SCK_BACK, SCI_ALT, SCI_DELWORDLEFT}, {SCK_BACK, SCI_CSHIFT, SCI_DELLINELEFT}, {'z', SCI_CMD, SCI_UNDO}, {'z', SCI_SCMD, SCI_REDO}, {'x', SCI_CMD, SCI_CUT}, {'c', SCI_CMD, SCI_COPY}, {'v', SCI_CMD, SCI_PASTE}, {'a', SCI_CMD, SCI_SELECTALL}, {SCK_TAB, SCI_NORM, SCI_TAB}, {SCK_TAB, SCI_SHIFT, SCI_BACKTAB}, {SCK_RETURN, SCI_NORM, SCI_NEWLINE}, {SCK_RETURN, SCI_SHIFT, SCI_NEWLINE}, {SCK_ADD, SCI_CMD, SCI_ZOOMIN}, {SCK_SUBTRACT, SCI_CMD, SCI_ZOOMOUT}, {SCK_DIVIDE, SCI_CMD, SCI_SETZOOM}, {'l', SCI_CMD, SCI_LINECUT}, {'l', SCI_CSHIFT, SCI_LINEDELETE}, {'t', SCI_CSHIFT, SCI_LINECOPY}, {'t', SCI_CTRL, SCI_LINETRANSPOSE}, {'d', SCI_CTRL, SCI_SELECTIONDUPLICATE}, {'u', SCI_CTRL, SCI_LOWERCASE}, {'u', SCI_CSHIFT, SCI_UPPERCASE}, {0, 0, 0}, }; //-------------------------------------------------------------------------------------------------- #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 // Only implement FindHighlightLayer on OS X 10.6+ /** * Class to display the animated gold roundrect used on OS X for matches. */ @interface FindHighlightLayer : CAGradientLayer { @private NSString *sFind; int positionFind; BOOL retaining; CGFloat widthText; CGFloat heightLine; NSString *sFont; CGFloat fontSize; } @property (copy) NSString *sFind; @property (assign) int positionFind; @property (assign) BOOL retaining; @property (assign) CGFloat widthText; @property (assign) CGFloat heightLine; @property (copy) NSString *sFont; @property (assign) CGFloat fontSize; - (void) animateMatch: (CGPoint)ptText bounce:(BOOL)bounce; - (void) hideMatch; @end //-------------------------------------------------------------------------------------------------- @implementation FindHighlightLayer @synthesize sFind, positionFind, retaining, widthText, heightLine, sFont, fontSize; -(id) init { if (self = [super init]) { [self setNeedsDisplayOnBoundsChange: YES]; // A gold to slightly redder gradient to match other applications CGColorRef colGold = CGColorCreateGenericRGB(1.0, 1.0, 0, 1.0); CGColorRef colGoldRed = CGColorCreateGenericRGB(1.0, 0.8, 0, 1.0); self.colors = [NSArray arrayWithObjects:(id)colGoldRed, (id)colGold, nil]; CGColorRelease(colGoldRed); CGColorRelease(colGold); CGColorRef colGreyBorder = CGColorCreateGenericGray(0.756f, 0.5f); self.borderColor = colGreyBorder; CGColorRelease(colGreyBorder); self.borderWidth = 1.0; self.cornerRadius = 5.0f; self.shadowRadius = 1.0f; self.shadowOpacity = 0.9f; self.shadowOffset = CGSizeMake(0.0f, -2.0f); self.anchorPoint = CGPointMake(0.5, 0.5); } return self; } const CGFloat paddingHighlightX = 4; const CGFloat paddingHighlightY = 2; -(void) drawInContext:(CGContextRef)context { if (!sFind || !sFont) return; CFStringRef str = CFStringRef(sFind); CFMutableDictionaryRef styleDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CGColorRef color = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 1.0); CFDictionarySetValue(styleDict, kCTForegroundColorAttributeName, color); CTFontRef fontRef = ::CTFontCreateWithName((CFStringRef)sFont, fontSize, NULL); CFDictionaryAddValue(styleDict, kCTFontAttributeName, fontRef); CFAttributedStringRef attrString = ::CFAttributedStringCreate(NULL, str, styleDict); CTLineRef textLine = ::CTLineCreateWithAttributedString(attrString); // Indent from corner of bounds CGContextSetTextPosition(context, paddingHighlightX, 3 + paddingHighlightY); CTLineDraw(textLine, context); CFRelease(textLine); CFRelease(attrString); CFRelease(fontRef); CGColorRelease(color); CFRelease(styleDict); } - (void) animateMatch: (CGPoint)ptText bounce:(BOOL)bounce { if (!self.sFind || ![self.sFind length]) { [self hideMatch]; return; } CGFloat width = self.widthText + paddingHighlightX * 2; CGFloat height = self.heightLine + paddingHighlightY * 2; CGFloat flipper = self.geometryFlipped ? -1.0 : 1.0; // Adjust for padding ptText.x -= paddingHighlightX; ptText.y += flipper * paddingHighlightY; // Shift point to centre as expanding about centre ptText.x += width / 2.0; ptText.y -= flipper * height / 2.0; [CATransaction begin]; [CATransaction setValue:[NSNumber numberWithFloat:0.0] forKey:kCATransactionAnimationDuration]; self.bounds = CGRectMake(0,0, width, height); self.position = ptText; if (bounce) { // Do not reset visibility when just moving self.hidden = NO; self.opacity = 1.0; } [self setNeedsDisplay]; [CATransaction commit]; if (bounce) { CABasicAnimation *animBounce = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; animBounce.duration = 0.15; animBounce.autoreverses = YES; animBounce.removedOnCompletion = NO; animBounce.fromValue = [NSNumber numberWithFloat: 1.0]; animBounce.toValue = [NSNumber numberWithFloat: 1.25]; if (self.retaining) { [self addAnimation: animBounce forKey:@"animateFound"]; } else { CABasicAnimation *animFade = [CABasicAnimation animationWithKeyPath:@"opacity"]; animFade.duration = 0.1; animFade.beginTime = 0.4; animFade.removedOnCompletion = NO; animFade.fromValue = [NSNumber numberWithFloat: 1.0]; animFade.toValue = [NSNumber numberWithFloat: 0.0]; CAAnimationGroup *group = [CAAnimationGroup animation]; [group setDuration:0.5]; group.removedOnCompletion = NO; group.fillMode = kCAFillModeForwards; [group setAnimations:[NSArray arrayWithObjects:animBounce, animFade, nil]]; [self addAnimation:group forKey:@"animateFound"]; } } } - (void) hideMatch { self.sFind = @""; self.positionFind = INVALID_POSITION; self.hidden = YES; } @end #endif //-------------------------------------------------------------------------------------------------- @implementation TimerTarget - (id) init: (void*) target { self = [super init]; if (self != nil) { mTarget = target; // Get the default notification queue for the thread which created the instance (usually the // main thread). We need that later for idle event processing. NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; notificationQueue = [[NSNotificationQueue alloc] initWithNotificationCenter: center]; [center addObserver: self selector: @selector(idleTriggered:) name: @"Idle" object: nil]; } return self; } //-------------------------------------------------------------------------------------------------- - (void) dealloc { NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; [center removeObserver:self]; [notificationQueue release]; [super dealloc]; } //-------------------------------------------------------------------------------------------------- /** * Method called by a timer installed by ScintillaCocoa. This two step approach is needed because * a native Obj-C class is required as target for the timer. */ - (void) timerFired: (NSTimer*) timer { reinterpret_cast<ScintillaCocoa*>(mTarget)->TimerFired(timer); } //-------------------------------------------------------------------------------------------------- /** * Another timer callback for the idle timer. */ - (void) idleTimerFired: (NSTimer*) timer { #pragma unused(timer) // Idle timer event. // Post a new idle notification, which gets executed when the run loop is idle. // Since we are coalescing on name and sender there will always be only one actual notification // even for multiple requests. NSNotification *notification = [NSNotification notificationWithName: @"Idle" object: self]; [notificationQueue enqueueNotification: notification postingStyle: NSPostWhenIdle coalesceMask: (NSNotificationCoalescingOnName | NSNotificationCoalescingOnSender) forModes: nil]; } //-------------------------------------------------------------------------------------------------- /** * Another step for idle events. The timer (for idle events) simply requests a notification on * idle time. Only when this notification is send we actually call back the editor. */ - (void) idleTriggered: (NSNotification*) notification { #pragma unused(notification) reinterpret_cast<ScintillaCocoa*>(mTarget)->IdleTimerFired(); } @end //----------------- ScintillaCocoa ----------------------------------------------------------------- ScintillaCocoa::ScintillaCocoa(InnerView* view, MarginView* viewMargin) { vs.marginInside = false; wMain = view; // Don't retain since we're owned by view, which would cause a cycle wMargin = viewMargin; timerTarget = [[TimerTarget alloc] init: this]; lastMouseEvent = NULL; notifyObj = NULL; notifyProc = NULL; capturedMouse = false; enteredSetScrollingSize = false; scrollSpeed = 1; scrollTicks = 2000; tickTimer = NULL; idleTimer = NULL; observer = NULL; layerFindIndicator = NULL; Initialise(); } //-------------------------------------------------------------------------------------------------- ScintillaCocoa::~ScintillaCocoa() { SetTicking(false); [timerTarget release]; } //-------------------------------------------------------------------------------------------------- /** * Core initialization of the control. Everything that needs to be set up happens here. */ void ScintillaCocoa::Initialise() { Scintilla_LinkLexers(); // Tell Scintilla not to buffer: Quartz buffers drawing for us. WndProc(SCI_SETBUFFEREDDRAW, 0, 0); // We are working with Unicode exclusively. WndProc(SCI_SETCODEPAGE, SC_CP_UTF8, 0); // Add Mac specific key bindings. for (int i = 0; macMapDefault[i].key; i++) kmap.AssignCmdKey(macMapDefault[i].key, macMapDefault[i].modifiers, macMapDefault[i].msg); } //-------------------------------------------------------------------------------------------------- /** * We need some clean up. Do it here. */ void ScintillaCocoa::Finalise() { ObserverRemove(); SetTicking(false); ScintillaBase::Finalise(); } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::UpdateObserver(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) { ScintillaCocoa* sci = reinterpret_cast<ScintillaCocoa*>(info); sci->IdleWork(); } //-------------------------------------------------------------------------------------------------- /** * Add an observer to the run loop to perform styling as high-priority idle task. */ void ScintillaCocoa::ObserverAdd() { if (!observer) { CFRunLoopObserverContext context; context.version = 0; context.info = this; context.retain = NULL; context.release = NULL; context.copyDescription = NULL; CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); observer = CFRunLoopObserverCreate(NULL, kCFRunLoopEntry | kCFRunLoopBeforeWaiting, true, 0, UpdateObserver, &context); CFRunLoopAddObserver(mainRunLoop, observer, kCFRunLoopCommonModes); } } //-------------------------------------------------------------------------------------------------- /** * Remove the run loop observer. */ void ScintillaCocoa::ObserverRemove() { if (observer) { CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); CFRunLoopRemoveObserver(mainRunLoop, observer, kCFRunLoopCommonModes); CFRelease(observer); } observer = NULL; } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::IdleWork() { Editor::IdleWork(); ObserverRemove(); } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::QueueIdleWork(WorkNeeded::workItems items, int upTo) { Editor::QueueIdleWork(items, upTo); ObserverAdd(); } //-------------------------------------------------------------------------------------------------- /** * Convert a core foundation string into an array of bytes in a particular encoding */ static char *EncodedBytes(CFStringRef cfsRef, CFStringEncoding encoding) { CFRange rangeAll = {0, CFStringGetLength(cfsRef)}; CFIndex usedLen = 0; CFStringGetBytes(cfsRef, rangeAll, encoding, '?', false, NULL, 0, &usedLen); char *buffer = new char[usedLen+1]; CFStringGetBytes(cfsRef, rangeAll, encoding, '?', false, (UInt8 *)buffer,usedLen, NULL); buffer[usedLen] = '\0'; return buffer; } //-------------------------------------------------------------------------------------------------- /** * Case folders. */ class CaseFolderUTF8 : public CaseFolderTable { public: CaseFolderUTF8() { StandardASCII(); } virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) { if ((lenMixed == 1) && (sizeFolded > 0)) { folded[0] = mapping[static_cast<unsigned char>(mixed[0])]; return 1; } else { CFStringRef cfsVal = CFStringCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(mixed), lenMixed, kCFStringEncodingUTF8, false); NSString *sMapped = [(NSString *)cfsVal stringByFoldingWithOptions:NSCaseInsensitiveSearch locale:[NSLocale currentLocale]]; const char *cpMapped = [sMapped UTF8String]; size_t lenMapped = cpMapped ? strlen(cpMapped) : 0; if (lenMapped < sizeFolded) { memcpy(folded, cpMapped, lenMapped); } else { lenMapped = 0; } if (cfsVal) CFRelease(cfsVal); return lenMapped; } } }; class CaseFolderDBCS : public CaseFolderTable { CFStringEncoding encoding; public: CaseFolderDBCS(CFStringEncoding encoding_) : encoding(encoding_) { StandardASCII(); } virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) { if ((lenMixed == 1) && (sizeFolded > 0)) { folded[0] = mapping[static_cast<unsigned char>(mixed[0])]; return 1; } else { CFStringRef cfsVal = CFStringCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(mixed), lenMixed, encoding, false); NSString *sMapped = [(NSString *)cfsVal stringByFoldingWithOptions:NSCaseInsensitiveSearch locale:[NSLocale currentLocale]]; char *encoded = EncodedBytes((CFStringRef)sMapped, encoding); size_t lenMapped = strlen(encoded); if (lenMapped < sizeFolded) { memcpy(folded, encoded, lenMapped); } else { folded[0] = '\0'; lenMapped = 1; } delete []encoded; CFRelease(cfsVal); return lenMapped; } // Something failed so return a single NUL byte folded[0] = '\0'; return 1; } }; CaseFolder *ScintillaCocoa::CaseFolderForEncoding() { if (pdoc->dbcsCodePage == SC_CP_UTF8) { return new CaseFolderUTF8(); } else { CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), vs.styles[STYLE_DEFAULT].characterSet); if (pdoc->dbcsCodePage == 0) { CaseFolderTable *pcf = new CaseFolderTable(); pcf->StandardASCII(); // Only for single byte encodings for (int i=0x80; i<0x100; i++) { char sCharacter[2] = "A"; sCharacter[0] = i; CFStringRef cfsVal = CFStringCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(sCharacter), 1, encoding, false); NSString *sMapped = [(NSString *)cfsVal stringByFoldingWithOptions:NSCaseInsensitiveSearch locale:[NSLocale currentLocale]]; char *encoded = EncodedBytes((CFStringRef)sMapped, encoding); if (strlen(encoded) == 1) { pcf->SetTranslation(sCharacter[0], encoded[0]); } delete []encoded; CFRelease(cfsVal); } return pcf; } else { return new CaseFolderDBCS(encoding); } return 0; } } //-------------------------------------------------------------------------------------------------- /** * Case-fold the given string depending on the specified case mapping type. */ std::string ScintillaCocoa::CaseMapString(const std::string &s, int caseMapping) { CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), vs.styles[STYLE_DEFAULT].characterSet); CFStringRef cfsVal = CFStringCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(s.c_str()), s.length(), encoding, false); NSString *sMapped; switch (caseMapping) { case cmUpper: sMapped = [(NSString *)cfsVal uppercaseString]; break; case cmLower: sMapped = [(NSString *)cfsVal lowercaseString]; break; default: sMapped = (NSString *)cfsVal; } // Back to encoding char *encoded = EncodedBytes((CFStringRef)sMapped, encoding); std::string result(encoded); delete []encoded; CFRelease(cfsVal); return result; } //-------------------------------------------------------------------------------------------------- /** * Cancel all modes, both for base class and any find indicator. */ void ScintillaCocoa::CancelModes() { ScintillaBase::CancelModes(); HideFindIndicator(); } //-------------------------------------------------------------------------------------------------- /** * Helper function to get the outer container which represents the Scintilla editor on application side. */ ScintillaView* ScintillaCocoa::TopContainer() { NSView* container = static_cast<NSView*>(wMain.GetID()); return static_cast<ScintillaView*>([[[container superview] superview] superview]); } //-------------------------------------------------------------------------------------------------- /** * Helper function to get the scrolling view. */ NSScrollView* ScintillaCocoa::ScrollContainer() { NSView* container = static_cast<NSView*>(wMain.GetID()); return static_cast<NSScrollView*>([[container superview] superview]); } //-------------------------------------------------------------------------------------------------- /** * Helper function to get the inner container which represents the actual "canvas" we work with. */ InnerView* ScintillaCocoa::ContentView() { return static_cast<InnerView*>(wMain.GetID()); } //-------------------------------------------------------------------------------------------------- /** * Return the top left visible point relative to the origin point of the whole document. */ Scintilla::Point ScintillaCocoa::GetVisibleOriginInMain() { NSScrollView *scrollView = ScrollContainer(); NSRect contentRect = [[scrollView contentView] bounds]; return Point(contentRect.origin.x, contentRect.origin.y); } //-------------------------------------------------------------------------------------------------- /** * Instead of returning the size of the inner view we have to return the visible part of it * in order to make scrolling working properly. * The returned value is in document coordinates. */ PRectangle ScintillaCocoa::GetClientRectangle() { NSView* host = ContentView(); NSSize size = [[host superview] frame].size; Point origin = GetVisibleOriginInMain(); return PRectangle(origin.x, origin.y, origin.x+size.width, origin.y + size.height); } //-------------------------------------------------------------------------------------------------- /** * Converts the given point from base coordinates to local coordinates and at the same time into * a native Point structure. Base coordinates are used for the top window used in the view hierarchy. * Returned value is in view coordinates. */ Scintilla::Point ScintillaCocoa::ConvertPoint(NSPoint point) { NSView* container = ContentView(); NSPoint result = [container convertPoint: point fromView: nil]; Scintilla::Point ptOrigin = GetVisibleOriginInMain(); return Point(result.x - ptOrigin.x, result.y - ptOrigin.y); } //-------------------------------------------------------------------------------------------------- /** * A function to directly execute code that would usually go the long way via window messages. * However this is a Windows metapher and not used here, hence we just call our fake * window proc. The given parameters directly reflect the message parameters used on Windows. * * @param sciThis The target which is to be called. * @param iMessage A code that indicates which message was sent. * @param wParam One of the two free parameters for the message. Traditionally a word sized parameter * (hence the w prefix). * @param lParam The other of the two free parameters. A signed long. */ sptr_t ScintillaCocoa::DirectFunction(ScintillaCocoa *sciThis, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return sciThis->WndProc(iMessage, wParam, lParam); } //-------------------------------------------------------------------------------------------------- /** * This method is very similar to DirectFunction. On Windows it sends a message (not in the Obj-C sense) * to the target window. Here we simply call our fake window proc. */ sptr_t scintilla_send_message(void* sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { ScintillaView *control = reinterpret_cast<ScintillaView*>(sci); ScintillaCocoa* scintilla = [control backend]; return scintilla->WndProc(iMessage, wParam, lParam); } //-------------------------------------------------------------------------------------------------- /** * That's our fake window procedure. On Windows each window has a dedicated procedure to handle * commands (also used to synchronize UI and background threads), which is not the case in Cocoa. * * Messages handled here are almost solely for special commands of the backend. Everything which * would be sytem messages on Windows (e.g. for key down, mouse move etc.) are handled by * directly calling appropriate handlers. */ sptr_t ScintillaCocoa::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { switch (iMessage) { case SCI_GETDIRECTFUNCTION: return reinterpret_cast<sptr_t>(DirectFunction); case SCI_GETDIRECTPOINTER: return reinterpret_cast<sptr_t>(this); case SCI_GRABFOCUS: [[ContentView() window] makeFirstResponder:ContentView()]; break; case SCI_SETBUFFEREDDRAW: // Buffered drawing not supported on Cocoa bufferedDraw = false; break; case SCI_FINDINDICATORSHOW: ShowFindIndicatorForRange(NSMakeRange(wParam, lParam-wParam), YES); return 0; case SCI_FINDINDICATORFLASH: ShowFindIndicatorForRange(NSMakeRange(wParam, lParam-wParam), NO); return 0; case SCI_FINDINDICATORHIDE: HideFindIndicator(); return 0; case WM_UNICHAR: // Special case not used normally. Characters passed in this way will be inserted // regardless of their value or modifier states. That means no command interpretation is // performed. if (IsUnicodeMode()) { NSString* input = [NSString stringWithCharacters: (const unichar*) &wParam length: 1]; const char* utf8 = [input UTF8String]; AddCharUTF((char*) utf8, static_cast<unsigned int>(strlen(utf8)), false); return 1; } return 0; default: sptr_t r = ScintillaBase::WndProc(iMessage, wParam, lParam); return r; } return 0l; } //-------------------------------------------------------------------------------------------------- /** * In Windows lingo this is the handler which handles anything that wasn't handled in the normal * window proc which would usually send the message back to generic window proc that Windows uses. */ sptr_t ScintillaCocoa::DefWndProc(unsigned int, uptr_t, sptr_t) { return 0; } //-------------------------------------------------------------------------------------------------- /** * Enables or disables a timer that can trigger background processing at a regular interval, like * drag scrolling or caret blinking. */ void ScintillaCocoa::SetTicking(bool on) { if (timer.ticking != on) { timer.ticking = on; if (timer.ticking) { // Scintilla ticks = milliseconds tickTimer = [NSTimer scheduledTimerWithTimeInterval: timer.tickSize / 1000.0 target: timerTarget selector: @selector(timerFired:) userInfo: nil repeats: YES]; timer.tickerID = reinterpret_cast<TickerID>(tickTimer); } else if (timer.tickerID != NULL) { [reinterpret_cast<NSTimer*>(timer.tickerID) invalidate]; timer.tickerID = 0; } } timer.ticksToWait = caret.period; } //-------------------------------------------------------------------------------------------------- bool ScintillaCocoa::SetIdle(bool on) { if (idler.state != on) { idler.state = on; if (idler.state) { // Scintilla ticks = milliseconds idleTimer = [NSTimer scheduledTimerWithTimeInterval: timer.tickSize / 1000.0 target: timerTarget selector: @selector(idleTimerFired:) userInfo: nil repeats: YES]; idler.idlerID = reinterpret_cast<IdlerID>(idleTimer); } else if (idler.idlerID != NULL) { [reinterpret_cast<NSTimer*>(idler.idlerID) invalidate]; idler.idlerID = 0; } } return true; } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::CopyToClipboard(const SelectionText &selectedText) { SetPasteboardData([NSPasteboard generalPasteboard], selectedText); } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::Copy() { if (!sel.Empty()) { SelectionText selectedText; CopySelectionRange(&selectedText); CopyToClipboard(selectedText); } } //-------------------------------------------------------------------------------------------------- bool ScintillaCocoa::CanPaste() { if (!Editor::CanPaste()) return false; return GetPasteboardData([NSPasteboard generalPasteboard], NULL); } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::Paste() { Paste(false); } //-------------------------------------------------------------------------------------------------- /** * Pastes data from the paste board into the editor. */ void ScintillaCocoa::Paste(bool forceRectangular) { SelectionText selectedText; bool ok = GetPasteboardData([NSPasteboard generalPasteboard], &selectedText); if (forceRectangular) selectedText.rectangular = forceRectangular; if (!ok || !selectedText.s) // No data or no flavor we support. return; pdoc->BeginUndoAction(); ClearSelection(false); int length = selectedText.len - 1; // One less to avoid inserting the terminating 0 character. if (selectedText.rectangular) { SelectionPosition selStart = sel.RangeMain().Start(); PasteRectangular(selStart, selectedText.s, length); } else if (pdoc->InsertString(sel.RangeMain().caret.Position(), selectedText.s, length)) SetEmptySelection(sel.RangeMain().caret.Position() + length); pdoc->EndUndoAction(); Redraw(); EnsureCaretVisible(); } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::CTPaint(void* gc, NSRect rc) { #pragma unused(rc) Surface *surfaceWindow = Surface::Allocate(SC_TECHNOLOGY_DEFAULT); if (surfaceWindow) { surfaceWindow->Init(gc, wMain.GetID()); surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == ct.codePage); surfaceWindow->SetDBCSMode(ct.codePage); ct.PaintCT(surfaceWindow); surfaceWindow->Release(); delete surfaceWindow; } } @interface CallTipView : NSControl { ScintillaCocoa *sci; } @end @implementation CallTipView - (NSView*) initWithFrame: (NSRect) frame { self = [super initWithFrame: frame]; if (self) { sci = NULL; } return self; } - (void) dealloc { [super dealloc]; } - (BOOL) isFlipped { return YES; } - (void) setSci: (ScintillaCocoa *) sci_ { sci = sci_; } - (void) drawRect: (NSRect) needsDisplayInRect { if (sci) { CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; sci->CTPaint(context, needsDisplayInRect); } } - (void) mouseDown: (NSEvent *) event { if (sci) { sci->CallTipMouseDown([event locationInWindow]); } } // On OS X, only the key view should modify the cursor so the calltip can't. // This view does not become key so resetCursorRects never called. - (void) resetCursorRects { //[super resetCursorRects]; //[self addCursorRect: [self bounds] cursor: [NSCursor arrowCursor]]; } @end void ScintillaCocoa::CallTipMouseDown(NSPoint pt) { NSRect rectBounds = [(NSView *)(ct.wDraw.GetID()) bounds]; Point location(pt.x, rectBounds.size.height - pt.y); ct.MouseClick(location); CallTipClick(); } void ScintillaCocoa::CreateCallTipWindow(PRectangle rc) { if (!ct.wCallTip.Created()) { NSRect ctRect = NSMakeRect(rc.top,rc.bottom, rc.Width(), rc.Height()); NSWindow *callTip = [[NSWindow alloc] initWithContentRect: ctRect styleMask: NSBorderlessWindowMask backing: NSBackingStoreBuffered defer: NO]; [callTip setLevel:NSFloatingWindowLevel]; [callTip setHasShadow:YES]; NSRect ctContent = NSMakeRect(0,0, rc.Width(), rc.Height()); CallTipView *caption = [[CallTipView alloc] initWithFrame: ctContent]; [caption setAutoresizingMask: NSViewWidthSizable | NSViewMaxYMargin]; [caption setSci: this]; [[callTip contentView] addSubview: caption]; [callTip orderFront:caption]; ct.wCallTip = callTip; ct.wDraw = caption; } } void ScintillaCocoa::AddToPopUp(const char *label, int cmd, bool enabled) { NSMenuItem* item; ScintillaContextMenu *menu= reinterpret_cast<ScintillaContextMenu*>(popup.GetID()); [menu setOwner: this]; [menu setAutoenablesItems: NO]; if (cmd == 0) { item = [NSMenuItem separatorItem]; } else { item = [[[NSMenuItem alloc] init] autorelease]; [item setTitle: [NSString stringWithUTF8String: label]]; } [item setTarget: menu]; [item setAction: @selector(handleCommand:)]; [item setTag: cmd]; [item setEnabled: enabled]; [menu addItem: item]; } // ------------------------------------------------------------------------------------------------- void ScintillaCocoa::ClaimSelection() { // Mac OS X does not have a primary selection. } // ------------------------------------------------------------------------------------------------- /** * Returns the current caret position (which is tracked as an offset into the entire text string) * as a row:column pair. The result is zero-based. */ NSPoint ScintillaCocoa::GetCaretPosition() { NSPoint result; result.y = pdoc->LineFromPosition(sel.RangeMain().caret.Position()); result.x = sel.RangeMain().caret.Position() - pdoc->LineStart(result.y); return result; } // ------------------------------------------------------------------------------------------------- #pragma mark Drag /** * Triggered by the tick timer on a regular basis to scroll the content during a drag operation. */ void ScintillaCocoa::DragScroll() { if (!posDrag.IsValid()) { scrollSpeed = 1; scrollTicks = 2000; return; } // TODO: does not work for wrapped lines, fix it. int line = pdoc->LineFromPosition(posDrag.Position()); int currentVisibleLine = cs.DisplayFromDoc(line); int lastVisibleLine = Platform::Minimum(topLine + LinesOnScreen(), cs.LinesDisplayed()) - 2; if (currentVisibleLine <= topLine && topLine > 0) ScrollTo(topLine - scrollSpeed); else if (currentVisibleLine >= lastVisibleLine) ScrollTo(topLine + scrollSpeed); else { scrollSpeed = 1; scrollTicks = 2000; return; } // TODO: also handle horizontal scrolling. if (scrollSpeed == 1) { scrollTicks -= timer.tickSize; if (scrollTicks <= 0) { scrollSpeed = 5; scrollTicks = 2000; } } } //-------------------------------------------------------------------------------------------------- /** * Called when a drag operation was initiated from within Scintilla. */ void ScintillaCocoa::StartDrag() { if (sel.Empty()) return; // Put the data to be dragged on the drag pasteboard. SelectionText selectedText; NSPasteboard* pasteboard = [NSPasteboard pasteboardWithName: NSDragPboard]; CopySelectionRange(&selectedText); SetPasteboardData(pasteboard, selectedText); // calculate the bounds of the selection PRectangle client = GetTextRectangle(); int selStart = sel.RangeMain().Start().Position(); int selEnd = sel.RangeMain().End().Position(); int startLine = pdoc->LineFromPosition(selStart); int endLine = pdoc->LineFromPosition(selEnd); Point pt; long startPos, endPos, ep; Rect rcSel; if (startLine==endLine && WndProc(SCI_GETWRAPMODE, 0, 0) != SC_WRAP_NONE) { // Komodo bug http://bugs.activestate.com/show_bug.cgi?id=87571 // Scintilla bug https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3040200&group_id=2439 // If the width on a wrapped-line selection is negative, // find a better bounding rectangle. Point ptStart, ptEnd; startPos = WndProc(SCI_GETLINESELSTARTPOSITION, startLine, 0); endPos = WndProc(SCI_GETLINESELENDPOSITION, startLine, 0); // step back a position if we're counting the newline ep = WndProc(SCI_GETLINEENDPOSITION, startLine, 0); if (endPos > ep) endPos = ep; ptStart = LocationFromPosition(static_cast<int>(startPos)); ptEnd = LocationFromPosition(static_cast<int>(endPos)); if (ptStart.y == ptEnd.y) { // We're just selecting part of one visible line rcSel.left = ptStart.x; rcSel.right = ptEnd.x < client.right ? ptEnd.x : client.right; } else { // Find the bounding box. startPos = WndProc(SCI_POSITIONFROMLINE, startLine, 0); rcSel.left = LocationFromPosition(static_cast<int>(startPos)).x; rcSel.right = client.right; } rcSel.top = ptStart.y; rcSel.bottom = ptEnd.y + vs.lineHeight; if (rcSel.bottom > client.bottom) { rcSel.bottom = client.bottom; } } else { rcSel.top = rcSel.bottom = rcSel.right = rcSel.left = -1; for (int l = startLine; l <= endLine; l++) { startPos = WndProc(SCI_GETLINESELSTARTPOSITION, l, 0); endPos = WndProc(SCI_GETLINESELENDPOSITION, l, 0); if (endPos == startPos) continue; // step back a position if we're counting the newline ep = WndProc(SCI_GETLINEENDPOSITION, l, 0); if (endPos > ep) endPos = ep; pt = LocationFromPosition(static_cast<int>(startPos)); // top left of line selection if (pt.x < rcSel.left || rcSel.left < 0) rcSel.left = pt.x; if (pt.y < rcSel.top || rcSel.top < 0) rcSel.top = pt.y; pt = LocationFromPosition(static_cast<int>(endPos)); // top right of line selection pt.y += vs.lineHeight; // get to the bottom of the line if (pt.x > rcSel.right || rcSel.right < 0) { if (pt.x > client.right) rcSel.right = client.right; else rcSel.right = pt.x; } if (pt.y > rcSel.bottom || rcSel.bottom < 0) { if (pt.y > client.bottom) rcSel.bottom = client.bottom; else rcSel.bottom = pt.y; } } } // must convert to global coordinates for drag regions, but also save the // image rectangle for further calculations and copy operations PRectangle localRectangle = PRectangle(rcSel.left, rcSel.top, rcSel.right, rcSel.bottom); // Prepare drag image. NSRect selectionRectangle = PRectangleToNSRect(localRectangle); NSView* content = ContentView(); #if 1 // To get a bitmap of the text we're dragging, we just use Paint on a pixmap surface. SurfaceImpl *sw = new SurfaceImpl(); SurfaceImpl *pixmap = NULL; bool lastHideSelection = hideSelection; hideSelection = true; if (sw) { pixmap = new SurfaceImpl(); if (pixmap) { PRectangle imageRect = NSRectToPRectangle(selectionRectangle); paintState = painting; sw->InitPixMap(client.Width(), client.Height(), NULL, NULL); paintingAllText = true; // Have to create a new context and make current as text drawing goes // to the current context, not a passed context. CGContextRef gcsw = sw->GetContext(); NSGraphicsContext *nsgc = [NSGraphicsContext graphicsContextWithGraphicsPort: gcsw flipped: YES]; [NSGraphicsContext setCurrentContext:nsgc]; Paint(sw, client); paintState = notPainting; pixmap->InitPixMap(imageRect.Width(), imageRect.Height(), NULL, NULL); CGContextRef gc = pixmap->GetContext(); // To make Paint() work on a bitmap, we have to flip our coordinates and translate the origin CGContextTranslateCTM(gc, 0, imageRect.Height()); CGContextScaleCTM(gc, 1.0, -1.0); pixmap->CopyImageRectangle(*sw, imageRect, PRectangle(0, 0, imageRect.Width(), imageRect.Height())); // XXX TODO: overwrite any part of the image that is not part of the // selection to make it transparent. right now we just use // the full rectangle which may include non-selected text. } sw->Release(); delete sw; } hideSelection = lastHideSelection; NSBitmapImageRep* bitmap = NULL; if (pixmap) { CGImageRef imagePixmap = pixmap->GetImage(); bitmap = [[[NSBitmapImageRep alloc] initWithCGImage: imagePixmap] autorelease]; CGImageRelease(imagePixmap); pixmap->Release(); delete pixmap; } #else // Poor man's drag image: take a snapshot of the content view. [content lockFocus]; NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc] initWithFocusedViewRect: selectionRectangle] autorelease]; [bitmap setColorSpaceName: NSDeviceRGBColorSpace]; [content unlockFocus]; #endif NSImage* image = [[[NSImage alloc] initWithSize: selectionRectangle.size] autorelease]; [image addRepresentation: bitmap]; NSImage* dragImage = [[[NSImage alloc] initWithSize: selectionRectangle.size] autorelease]; [dragImage setBackgroundColor: [NSColor clearColor]]; [dragImage lockFocus]; [image dissolveToPoint: NSMakePoint(0.0, 0.0) fraction: 0.5]; [dragImage unlockFocus]; NSPoint startPoint; startPoint.x = selectionRectangle.origin.x; startPoint.y = selectionRectangle.origin.y + selectionRectangle.size.height; [content dragImage: dragImage at: startPoint offset: NSZeroSize event: lastMouseEvent // Set in MouseMove. pasteboard: pasteboard source: content slideBack: YES]; } //-------------------------------------------------------------------------------------------------- /** * Called when a drag operation reaches the control which was initiated outside. */ NSDragOperation ScintillaCocoa::DraggingEntered(id <NSDraggingInfo> info) { inDragDrop = ddDragging; return DraggingUpdated(info); } //-------------------------------------------------------------------------------------------------- /** * Called frequently during a drag operation if we are the target. Keep telling the caller * what drag operation we accept and update the drop caret position to indicate the * potential insertion point of the dragged data. */ NSDragOperation ScintillaCocoa::DraggingUpdated(id <NSDraggingInfo> info) { // Convert the drag location from window coordinates to view coordinates and // from there to a text position to finally set the drag position. Point location = ConvertPoint([info draggingLocation]); SetDragPosition(SPositionFromLocation(location)); NSDragOperation sourceDragMask = [info draggingSourceOperationMask]; if (sourceDragMask == NSDragOperationNone) return sourceDragMask; NSPasteboard* pasteboard = [info draggingPasteboard]; // Return what type of operation we will perform. Prefer move over copy. if ([[pasteboard types] containsObject: NSStringPboardType] || [[pasteboard types] containsObject: ScintillaRecPboardType]) return (sourceDragMask & NSDragOperationMove) ? NSDragOperationMove : NSDragOperationCopy; if ([[pasteboard types] containsObject: NSFilenamesPboardType]) return (sourceDragMask & NSDragOperationGeneric); return NSDragOperationNone; } //-------------------------------------------------------------------------------------------------- /** * Resets the current drag position as we are no longer the drag target. */ void ScintillaCocoa::DraggingExited(id <NSDraggingInfo> info) { #pragma unused(info) SetDragPosition(SelectionPosition(invalidPosition)); inDragDrop = ddNone; } //-------------------------------------------------------------------------------------------------- /** * Here is where the real work is done. Insert the text from the pasteboard. */ bool ScintillaCocoa::PerformDragOperation(id <NSDraggingInfo> info) { NSPasteboard* pasteboard = [info draggingPasteboard]; if ([[pasteboard types] containsObject: NSFilenamesPboardType]) { NSArray* files = [pasteboard propertyListForType: NSFilenamesPboardType]; for (NSString* uri in files) NotifyURIDropped([uri UTF8String]); } else { SelectionText text; GetPasteboardData(pasteboard, &text); if (text.len > 0) { NSDragOperation operation = [info draggingSourceOperationMask]; bool moving = (operation & NSDragOperationMove) != 0; DropAt(posDrag, text.s, moving, text.rectangular); }; } return true; } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::SetPasteboardData(NSPasteboard* board, const SelectionText &selectedText) { if (selectedText.len == 0) return; CFStringEncoding encoding = EncodingFromCharacterSet(selectedText.codePage == SC_CP_UTF8, selectedText.characterSet); CFStringRef cfsVal = CFStringCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(selectedText.s), selectedText.len-1, encoding, false); NSArray *pbTypes = selectedText.rectangular ? [NSArray arrayWithObjects: NSStringPboardType, ScintillaRecPboardType, nil] : [NSArray arrayWithObjects: NSStringPboardType, nil]; [board declareTypes:pbTypes owner:nil]; if (selectedText.rectangular) { // This is specific to scintilla, allows us to drag rectangular selections around the document. [board setString: (NSString *)cfsVal forType: ScintillaRecPboardType]; } [board setString: (NSString *)cfsVal forType: NSStringPboardType]; if (cfsVal) CFRelease(cfsVal); } //-------------------------------------------------------------------------------------------------- /** * Helper method to retrieve the best fitting alternative from the general pasteboard. */ bool ScintillaCocoa::GetPasteboardData(NSPasteboard* board, SelectionText* selectedText) { NSArray* supportedTypes = [NSArray arrayWithObjects: ScintillaRecPboardType, NSStringPboardType, nil]; NSString *bestType = [board availableTypeFromArray: supportedTypes]; NSString* data = [board stringForType: bestType]; if (data != nil) { if (selectedText != nil) { CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), vs.styles[STYLE_DEFAULT].characterSet); CFRange rangeAll = {0, static_cast<CFIndex>([data length])}; CFIndex usedLen = 0; CFStringGetBytes((CFStringRef)data, rangeAll, encoding, '?', false, NULL, 0, &usedLen); UInt8 *buffer = new UInt8[usedLen]; CFStringGetBytes((CFStringRef)data, rangeAll, encoding, '?', false, buffer,usedLen, NULL); bool rectangular = bestType == ScintillaRecPboardType; int len = static_cast<int>(usedLen); char *dest = Document::TransformLineEnds(&len, (char *)buffer, len, pdoc->eolMode); selectedText->Set(dest, len+1, pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet , rectangular, false); delete []buffer; } return true; } return false; } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::SetMouseCapture(bool on) { capturedMouse = on; } //-------------------------------------------------------------------------------------------------- bool ScintillaCocoa::HaveMouseCapture() { return capturedMouse; } //-------------------------------------------------------------------------------------------------- /** * Synchronously paint a rectangle of the window. */ bool ScintillaCocoa::SyncPaint(void* gc, PRectangle rc) { paintState = painting; rcPaint = rc; PRectangle rcText = GetTextRectangle(); paintingAllText = rcPaint.Contains(rcText); bool succeeded = true; Surface *sw = Surface::Allocate(SC_TECHNOLOGY_DEFAULT); if (sw) { sw->Init(gc, wMain.GetID()); Paint(sw, rc); succeeded = paintState != paintAbandoned; sw->Release(); delete sw; } paintState = notPainting; if (!succeeded) { NSView *marginView = static_cast<NSView*>(wMargin.GetID()); [marginView setNeedsDisplay:YES]; } return succeeded; } //-------------------------------------------------------------------------------------------------- /** * Paint the margin into the MarginView space. */ void ScintillaCocoa::PaintMargin(NSRect aRect) { CGContextRef gc = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; PRectangle rc = NSRectToPRectangle(aRect); rcPaint = rc; Surface *sw = Surface::Allocate(SC_TECHNOLOGY_DEFAULT); if (sw) { sw->Init(gc, wMargin.GetID()); PaintSelMargin(sw, rc); sw->Release(); delete sw; } } //-------------------------------------------------------------------------------------------------- /** * ScrollText is empty because scrolling is handled by the NSScrollView. */ void ScintillaCocoa::ScrollText(int linesToMove) { } //-------------------------------------------------------------------------------------------------- /** * Modifies the vertical scroll position to make the current top line show up as such. */ void ScintillaCocoa::SetVerticalScrollPos() { NSScrollView *scrollView = ScrollContainer(); if (scrollView) { NSClipView *clipView = [scrollView contentView]; NSRect contentRect = [clipView bounds]; [clipView scrollToPoint: NSMakePoint(contentRect.origin.x, topLine * vs.lineHeight)]; [scrollView reflectScrolledClipView:clipView]; } } //-------------------------------------------------------------------------------------------------- /** * Modifies the horizontal scroll position to match xOffset. */ void ScintillaCocoa::SetHorizontalScrollPos() { PRectangle textRect = GetTextRectangle(); int maxXOffset = scrollWidth - textRect.Width(); if (maxXOffset < 0) maxXOffset = 0; if (xOffset > maxXOffset) xOffset = maxXOffset; NSScrollView *scrollView = ScrollContainer(); if (scrollView) { NSClipView * clipView = [scrollView contentView]; NSRect contentRect = [clipView bounds]; [clipView scrollToPoint: NSMakePoint(xOffset, contentRect.origin.y)]; [scrollView reflectScrolledClipView:clipView]; } MoveFindIndicatorWithBounce(NO); } //-------------------------------------------------------------------------------------------------- /** * Used to adjust both scrollers to reflect the current scroll range and position in the editor. * Arguments no longer used as NSScrollView handles details of scroll bar sizes. * * @param nMax Number of lines in the editor. * @param nPage Number of lines per scroll page. * @return True if there was a change, otherwise false. */ bool ScintillaCocoa::ModifyScrollBars(int nMax, int nPage) { #pragma unused(nMax, nPage) return SetScrollingSize(); } bool ScintillaCocoa::SetScrollingSize(void) { bool changes = false; InnerView *inner = ContentView(); if (!enteredSetScrollingSize) { enteredSetScrollingSize = true; NSScrollView *scrollView = ScrollContainer(); NSClipView *clipView = [ScrollContainer() contentView]; NSRect clipRect = [clipView bounds]; int docHeight = (cs.LinesDisplayed()+1) * vs.lineHeight; if (!endAtLastLine) docHeight += (int([scrollView bounds].size.height / vs.lineHeight)-3) * vs.lineHeight; // Allow extra space so that last scroll position places whole line at top int clipExtra = int(clipRect.size.height) % vs.lineHeight; docHeight += clipExtra; // Ensure all of clipRect covered by Scintilla drawing if (docHeight < clipRect.size.height) docHeight = clipRect.size.height; int docWidth = scrollWidth; bool showHorizontalScroll = horizontalScrollBarVisible && (wrapState == eWrapNone); if (!showHorizontalScroll) docWidth = clipRect.size.width; NSRect contentRect = {0, 0, docWidth, docHeight}; NSRect contentRectNow = [inner frame]; changes = (contentRect.size.width != contentRectNow.size.width) || (contentRect.size.height != contentRectNow.size.height); if (changes) { [inner setFrame: contentRect]; } [scrollView setHasVerticalScroller: verticalScrollBarVisible]; [scrollView setHasHorizontalScroller: showHorizontalScroll]; SetVerticalScrollPos(); enteredSetScrollingSize = false; } [inner.owner setMarginWidth: vs.fixedColumnWidth]; return changes; } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::Resize() { SetScrollingSize(); ChangeSize(); } //-------------------------------------------------------------------------------------------------- /** * Update fields to match scroll position after receiving a notification that the user has scrolled. */ void ScintillaCocoa::UpdateForScroll() { Point ptOrigin = GetVisibleOriginInMain(); xOffset = ptOrigin.x; int newTop = Platform::Minimum(ptOrigin.y / vs.lineHeight, MaxScrollPos()); SetTopLine(newTop); } //-------------------------------------------------------------------------------------------------- /** * Used to register a callback function for a given window. This is used to emulate the way * Windows notfies other controls (mainly up in the view hierarchy) about certain events. * * @param windowid A handle to a window. That value is generic and can be anything. It is passed * through to the callback. * @param callback The callback function to be used for future notifications. If NULL then no * notifications will be sent anymore. */ void ScintillaCocoa::RegisterNotifyCallback(intptr_t windowid, SciNotifyFunc callback) { notifyObj = windowid; notifyProc = callback; } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::NotifyChange() { if (notifyProc != NULL) notifyProc(notifyObj, WM_COMMAND, Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE), (uintptr_t) this); } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::NotifyFocus(bool focus) { if (notifyProc != NULL) notifyProc(notifyObj, WM_COMMAND, Platform::LongFromTwoShorts(GetCtrlID(), (focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS)), (uintptr_t) this); } //-------------------------------------------------------------------------------------------------- /** * Used to send a notification (as WM_NOTIFY call) to the procedure, which has been set by the call * to RegisterNotifyCallback (so it is not necessarily the parent window). * * @param scn The notification to send. */ void ScintillaCocoa::NotifyParent(SCNotification scn) { if (notifyProc != NULL) { scn.nmhdr.hwndFrom = (void*) this; scn.nmhdr.idFrom = GetCtrlID(); notifyProc(notifyObj, WM_NOTIFY, (uintptr_t) 0, (uintptr_t) &scn); } } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::NotifyURIDropped(const char *uri) { SCNotification scn; scn.nmhdr.code = SCN_URIDROPPED; scn.text = uri; NotifyParent(scn); } //-------------------------------------------------------------------------------------------------- bool ScintillaCocoa::HasSelection() { return !sel.Empty(); } //-------------------------------------------------------------------------------------------------- bool ScintillaCocoa::CanUndo() { return pdoc->CanUndo(); } //-------------------------------------------------------------------------------------------------- bool ScintillaCocoa::CanRedo() { return pdoc->CanRedo(); } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::TimerFired(NSTimer* timer) { #pragma unused(timer) Tick(); DragScroll(); } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::IdleTimerFired() { bool more = Idle(); if (!more) SetIdle(false); } //-------------------------------------------------------------------------------------------------- /** * Main entry point for drawing the control. * * @param rect The area to paint, given in the sender's coordinate system. * @param gc The context we can use to paint. */ bool ScintillaCocoa::Draw(NSRect rect, CGContextRef gc) { return SyncPaint(gc, NSRectToPRectangle(rect)); } //-------------------------------------------------------------------------------------------------- /** * Helper function to translate OS X key codes to Scintilla key codes. */ static inline UniChar KeyTranslate(UniChar unicodeChar) { switch (unicodeChar) { case NSDownArrowFunctionKey: return SCK_DOWN; case NSUpArrowFunctionKey: return SCK_UP; case NSLeftArrowFunctionKey: return SCK_LEFT; case NSRightArrowFunctionKey: return SCK_RIGHT; case NSHomeFunctionKey: return SCK_HOME; case NSEndFunctionKey: return SCK_END; case NSPageUpFunctionKey: return SCK_PRIOR; case NSPageDownFunctionKey: return SCK_NEXT; case NSDeleteFunctionKey: return SCK_DELETE; case NSInsertFunctionKey: return SCK_INSERT; case '\n': case 3: return SCK_RETURN; case 27: return SCK_ESCAPE; case 127: return SCK_BACK; case '\t': case 25: // Shift tab, return to unmodified tab and handle that via modifiers. return SCK_TAB; default: return unicodeChar; } } //-------------------------------------------------------------------------------------------------- /** * Main keyboard input handling method. It is called for any key down event, including function keys, * numeric keypad input and whatnot. * * @param event The event instance associated with the key down event. * @return True if the input was handled, false otherwise. */ bool ScintillaCocoa::KeyboardInput(NSEvent* event) { // For now filter out function keys. NSUInteger modifiers = [event modifierFlags]; NSString* input = [event characters]; bool control = (modifiers & NSControlKeyMask) != 0; bool shift = (modifiers & NSShiftKeyMask) != 0; bool command = (modifiers & NSCommandKeyMask) != 0; bool alt = (modifiers & NSAlternateKeyMask) != 0; bool handled = false; // Handle each entry individually. Usually we only have one entry anway. for (size_t i = 0; i < input.length; i++) { const UniChar originalKey = [input characterAtIndex: i]; UniChar key = KeyTranslate(originalKey); bool consumed = false; // Consumed as command? // Signal Control as SCMOD_META int modifierKeys = (shift ? SCI_SHIFT : 0) | (command ? SCI_CTRL : 0) | (alt ? SCI_ALT : 0) | (control ? SCI_META : 0); if (KeyDownWithModifiers(key, modifierKeys, &consumed)) handled = true; if (consumed) handled = true; } return handled; } //-------------------------------------------------------------------------------------------------- /** * Used to insert already processed text provided by the Cocoa text input system. */ int ScintillaCocoa::InsertText(NSString* input) { CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), vs.styles[STYLE_DEFAULT].characterSet); CFRange rangeAll = {0, static_cast<CFIndex>([input length])}; CFIndex usedLen = 0; CFStringGetBytes((CFStringRef)input, rangeAll, encoding, '?', false, NULL, 0, &usedLen); UInt8 *buffer = new UInt8[usedLen]; CFStringGetBytes((CFStringRef)input, rangeAll, encoding, '?', false, buffer,usedLen, NULL); AddCharUTF((char*) buffer, static_cast<unsigned int>(usedLen), false); delete []buffer; return static_cast<int>(usedLen); } //-------------------------------------------------------------------------------------------------- /** * Called by the owning view when the mouse pointer enters the control. */ void ScintillaCocoa::MouseEntered(NSEvent* event) { if (!HaveMouseCapture()) { WndProc(SCI_SETCURSOR, (long int)SC_CURSORNORMAL, 0); // Mouse location is given in screen coordinates and might also be outside of our bounds. Point location = ConvertPoint([event locationInWindow]); ButtonMove(location); } } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::MouseExited(NSEvent* /* event */) { // Nothing to do here. } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::MouseDown(NSEvent* event) { Point location = ConvertPoint([event locationInWindow]); NSTimeInterval time = [event timestamp]; bool command = ([event modifierFlags] & NSCommandKeyMask) != 0; bool shift = ([event modifierFlags] & NSShiftKeyMask) != 0; bool alt = ([event modifierFlags] & NSAlternateKeyMask) != 0; ButtonDown(Point(location.x, location.y), (int) (time * 1000), shift, command, alt); } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::MouseMove(NSEvent* event) { lastMouseEvent = event; ButtonMove(ConvertPoint([event locationInWindow])); } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::MouseUp(NSEvent* event) { NSTimeInterval time = [event timestamp]; bool control = ([event modifierFlags] & NSControlKeyMask) != 0; ButtonUp(ConvertPoint([event locationInWindow]), (int) (time * 1000), control); } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::MouseWheel(NSEvent* event) { bool command = ([event modifierFlags] & NSCommandKeyMask) != 0; int dY = 0; // In order to make scrolling with larger offset smoother we scroll less lines the larger the // delta value is. if ([event deltaY] < 0) dY = -(int) sqrt(-10.0 * [event deltaY]); else dY = (int) sqrt(10.0 * [event deltaY]); if (command) { // Zoom! We play with the font sizes in the styles. // Number of steps/line is ignored, we just care if sizing up or down. if (dY > 0.5) KeyCommand(SCI_ZOOMIN); else if (dY < -0.5) KeyCommand(SCI_ZOOMOUT); } else { } } //-------------------------------------------------------------------------------------------------- // Helper methods for NSResponder actions. void ScintillaCocoa::SelectAll() { Editor::SelectAll(); } void ScintillaCocoa::DeleteBackward() { KeyDown(SCK_BACK, false, false, false, nil); } void ScintillaCocoa::Cut() { Editor::Cut(); } void ScintillaCocoa::Undo() { Editor::Undo(); } void ScintillaCocoa::Redo() { Editor::Redo(); } //-------------------------------------------------------------------------------------------------- /** * Creates and returns a popup menu, which is then displayed by the Cocoa framework. */ NSMenu* ScintillaCocoa::CreateContextMenu(NSEvent* /* event */) { // Call ScintillaBase to create the context menu. ContextMenu(Point(0, 0)); return reinterpret_cast<NSMenu*>(popup.GetID()); } //-------------------------------------------------------------------------------------------------- /** * An intermediate function to forward context menu commands from the menu action handler to * scintilla. */ void ScintillaCocoa::HandleCommand(NSInteger command) { Command(static_cast<int>(command)); } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::ActiveStateChanged(bool isActive) { // If the window is being deactivated, lose the focus and turn off the ticking if (!isActive) { DropCaret(); //SetFocusState( false ); SetTicking( false ); } else { ShowCaretAtCurrentPosition(); } } //-------------------------------------------------------------------------------------------------- void ScintillaCocoa::ShowFindIndicatorForRange(NSRange charRange, BOOL retaining) { #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 NSView *content = ContentView(); if (!layerFindIndicator) { layerFindIndicator = [[FindHighlightLayer alloc] init]; [content setWantsLayer: YES]; layerFindIndicator.geometryFlipped = content.layer.geometryFlipped; [[content layer] addSublayer:layerFindIndicator]; } [layerFindIndicator removeAnimationForKey:@"animateFound"]; if (charRange.length) { CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), vs.styles[STYLE_DEFAULT].characterSet); std::vector<char> buffer(charRange.length); pdoc->GetCharRange(&buffer[0], charRange.location, charRange.length); CFStringRef cfsFind = CFStringCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(&buffer[0]), charRange.length, encoding, false); layerFindIndicator.sFind = (NSString *)cfsFind; if (cfsFind) CFRelease(cfsFind); layerFindIndicator.retaining = retaining; layerFindIndicator.positionFind = charRange.location; int style = WndProc(SCI_GETSTYLEAT, charRange.location, 0); std::vector<char> bufferFontName(WndProc(SCI_STYLEGETFONT, style, 0) + 1); WndProc(SCI_STYLEGETFONT, style, (sptr_t)&bufferFontName[0]); layerFindIndicator.sFont = [NSString stringWithUTF8String: &bufferFontName[0]]; layerFindIndicator.fontSize = WndProc(SCI_STYLEGETSIZEFRACTIONAL, style, 0) / (float)SC_FONT_SIZE_MULTIPLIER; layerFindIndicator.widthText = WndProc(SCI_POINTXFROMPOSITION, 0, charRange.location + charRange.length) - WndProc(SCI_POINTXFROMPOSITION, 0, charRange.location); layerFindIndicator.heightLine = WndProc(SCI_TEXTHEIGHT, 0, 0); MoveFindIndicatorWithBounce(YES); } else { [layerFindIndicator hideMatch]; } #endif } void ScintillaCocoa::MoveFindIndicatorWithBounce(BOOL bounce) { #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 if (layerFindIndicator) { CGPoint ptText = CGPointMake( WndProc(SCI_POINTXFROMPOSITION, 0, layerFindIndicator.positionFind), WndProc(SCI_POINTYFROMPOSITION, 0, layerFindIndicator.positionFind)); ptText.x = ptText.x - vs.fixedColumnWidth + xOffset; ptText.y += topLine * vs.lineHeight; if (!layerFindIndicator.geometryFlipped) { NSView *content = ContentView(); ptText.y = content.bounds.size.height - ptText.y; } [layerFindIndicator animateMatch:ptText bounce:bounce]; } #endif } void ScintillaCocoa::HideFindIndicator() { #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 if (layerFindIndicator) { [layerFindIndicator hideMatch]; } #endif } |
Added cocoa/ScintillaFramework/English.lproj/InfoPlist.strings.
> > |
1 2 |
/* Localized versions of Info.plist keys */
|
Added cocoa/ScintillaFramework/Info.plist.
> > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> <string>English</string> <key>CFBundleExecutable</key> <string>${EXECUTABLE_NAME}</string> <key>CFBundleIconFile</key> <string></string> <key>CFBundleIdentifier</key> <string>com.sun.${PRODUCT_NAME:identifier}</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>${PRODUCT_NAME}</string> <key>CFBundlePackageType</key> <string>FMWK</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> <string>1.0</string> <key>NSPrincipalClass</key> <string></string> </dict> </plist> |
Added cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 |
// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 1102C31C169FB49300DC16AB /* LexLaTeX.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 1102C31B169FB49300DC16AB /* LexLaTeX.cxx */; }; 11126B8214CD3A6200803C49 /* LexAVS.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11126B8114CD3A6200803C49 /* LexAVS.cxx */; }; 1114D6CB1602A951001DC345 /* LexPO.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 1114D6CA1602A951001DC345 /* LexPO.cxx */; }; 114B6F0D11FA7526004FB6AB /* LexAbaqus.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EBE11FA7526004FB6AB /* LexAbaqus.cxx */; }; 114B6F0E11FA7526004FB6AB /* LexAda.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EBF11FA7526004FB6AB /* LexAda.cxx */; }; 114B6F0F11FA7526004FB6AB /* LexAPDL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EC011FA7526004FB6AB /* LexAPDL.cxx */; }; 114B6F1011FA7526004FB6AB /* LexAsm.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EC111FA7526004FB6AB /* LexAsm.cxx */; }; 114B6F1111FA7526004FB6AB /* LexAsn1.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EC211FA7526004FB6AB /* LexAsn1.cxx */; }; 114B6F1211FA7526004FB6AB /* LexASY.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EC311FA7526004FB6AB /* LexASY.cxx */; }; 114B6F1311FA7526004FB6AB /* LexAU3.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EC411FA7526004FB6AB /* LexAU3.cxx */; }; 114B6F1411FA7526004FB6AB /* LexAVE.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EC511FA7526004FB6AB /* LexAVE.cxx */; }; 114B6F1511FA7526004FB6AB /* LexBaan.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EC611FA7526004FB6AB /* LexBaan.cxx */; }; 114B6F1611FA7526004FB6AB /* LexBash.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EC711FA7526004FB6AB /* LexBash.cxx */; }; 114B6F1711FA7526004FB6AB /* LexBasic.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EC811FA7526004FB6AB /* LexBasic.cxx */; }; 114B6F1811FA7526004FB6AB /* LexBullant.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EC911FA7526004FB6AB /* LexBullant.cxx */; }; 114B6F1911FA7526004FB6AB /* LexCaml.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6ECA11FA7526004FB6AB /* LexCaml.cxx */; }; 114B6F1A11FA7526004FB6AB /* LexCLW.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6ECB11FA7526004FB6AB /* LexCLW.cxx */; }; 114B6F1B11FA7526004FB6AB /* LexCmake.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6ECC11FA7526004FB6AB /* LexCmake.cxx */; }; 114B6F1C11FA7526004FB6AB /* LexCOBOL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6ECD11FA7526004FB6AB /* LexCOBOL.cxx */; }; 114B6F1D11FA7526004FB6AB /* LexConf.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6ECE11FA7526004FB6AB /* LexConf.cxx */; }; 114B6F1E11FA7526004FB6AB /* LexCPP.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6ECF11FA7526004FB6AB /* LexCPP.cxx */; }; 114B6F1F11FA7526004FB6AB /* LexCrontab.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6ED011FA7526004FB6AB /* LexCrontab.cxx */; }; 114B6F2011FA7526004FB6AB /* LexCsound.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6ED111FA7526004FB6AB /* LexCsound.cxx */; }; 114B6F2111FA7526004FB6AB /* LexCSS.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6ED211FA7526004FB6AB /* LexCSS.cxx */; }; 114B6F2211FA7526004FB6AB /* LexD.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6ED311FA7526004FB6AB /* LexD.cxx */; }; 114B6F2311FA7526004FB6AB /* LexEiffel.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6ED411FA7526004FB6AB /* LexEiffel.cxx */; }; 114B6F2411FA7526004FB6AB /* LexErlang.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6ED511FA7526004FB6AB /* LexErlang.cxx */; }; 114B6F2511FA7526004FB6AB /* LexEScript.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6ED611FA7526004FB6AB /* LexEScript.cxx */; }; 114B6F2611FA7526004FB6AB /* LexFlagship.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6ED711FA7526004FB6AB /* LexFlagship.cxx */; }; 114B6F2711FA7526004FB6AB /* LexForth.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6ED811FA7526004FB6AB /* LexForth.cxx */; }; 114B6F2811FA7526004FB6AB /* LexFortran.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6ED911FA7526004FB6AB /* LexFortran.cxx */; }; 114B6F2911FA7526004FB6AB /* LexGAP.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EDA11FA7526004FB6AB /* LexGAP.cxx */; }; 114B6F2A11FA7526004FB6AB /* LexGui4Cli.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EDB11FA7526004FB6AB /* LexGui4Cli.cxx */; }; 114B6F2B11FA7526004FB6AB /* LexHaskell.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EDC11FA7526004FB6AB /* LexHaskell.cxx */; }; 114B6F2C11FA7526004FB6AB /* LexHTML.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EDD11FA7526004FB6AB /* LexHTML.cxx */; }; 114B6F2D11FA7526004FB6AB /* LexInno.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EDE11FA7526004FB6AB /* LexInno.cxx */; }; 114B6F2E11FA7526004FB6AB /* LexKix.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EDF11FA7526004FB6AB /* LexKix.cxx */; }; 114B6F2F11FA7526004FB6AB /* LexLisp.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EE011FA7526004FB6AB /* LexLisp.cxx */; }; 114B6F3011FA7526004FB6AB /* LexLout.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EE111FA7526004FB6AB /* LexLout.cxx */; }; 114B6F3111FA7526004FB6AB /* LexLua.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EE211FA7526004FB6AB /* LexLua.cxx */; }; 114B6F3211FA7526004FB6AB /* LexMagik.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EE311FA7526004FB6AB /* LexMagik.cxx */; }; 114B6F3311FA7526004FB6AB /* LexMarkdown.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EE411FA7526004FB6AB /* LexMarkdown.cxx */; }; 114B6F3411FA7526004FB6AB /* LexMatlab.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EE511FA7526004FB6AB /* LexMatlab.cxx */; }; 114B6F3511FA7526004FB6AB /* LexMetapost.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EE611FA7526004FB6AB /* LexMetapost.cxx */; }; 114B6F3611FA7526004FB6AB /* LexMMIXAL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EE711FA7526004FB6AB /* LexMMIXAL.cxx */; }; 114B6F3711FA7526004FB6AB /* LexMPT.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EE811FA7526004FB6AB /* LexMPT.cxx */; }; 114B6F3811FA7526004FB6AB /* LexMSSQL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EE911FA7526004FB6AB /* LexMSSQL.cxx */; }; 114B6F3911FA7526004FB6AB /* LexMySQL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EEA11FA7526004FB6AB /* LexMySQL.cxx */; }; 114B6F3A11FA7526004FB6AB /* LexNimrod.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EEB11FA7526004FB6AB /* LexNimrod.cxx */; }; 114B6F3B11FA7526004FB6AB /* LexNsis.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EEC11FA7526004FB6AB /* LexNsis.cxx */; }; 114B6F3C11FA7526004FB6AB /* LexOpal.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EED11FA7526004FB6AB /* LexOpal.cxx */; }; 114B6F3D11FA7526004FB6AB /* LexOthers.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EEE11FA7526004FB6AB /* LexOthers.cxx */; }; 114B6F3E11FA7526004FB6AB /* LexPascal.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EEF11FA7526004FB6AB /* LexPascal.cxx */; }; 114B6F3F11FA7526004FB6AB /* LexPB.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EF011FA7526004FB6AB /* LexPB.cxx */; }; 114B6F4011FA7526004FB6AB /* LexPerl.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EF111FA7526004FB6AB /* LexPerl.cxx */; }; 114B6F4111FA7526004FB6AB /* LexPLM.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EF211FA7526004FB6AB /* LexPLM.cxx */; }; 114B6F4211FA7526004FB6AB /* LexPOV.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EF311FA7526004FB6AB /* LexPOV.cxx */; }; 114B6F4311FA7526004FB6AB /* LexPowerPro.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EF411FA7526004FB6AB /* LexPowerPro.cxx */; }; 114B6F4411FA7526004FB6AB /* LexPowerShell.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EF511FA7526004FB6AB /* LexPowerShell.cxx */; }; 114B6F4511FA7526004FB6AB /* LexProgress.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EF611FA7526004FB6AB /* LexProgress.cxx */; }; 114B6F4611FA7526004FB6AB /* LexPS.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EF711FA7526004FB6AB /* LexPS.cxx */; }; 114B6F4711FA7526004FB6AB /* LexPython.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EF811FA7526004FB6AB /* LexPython.cxx */; }; 114B6F4811FA7526004FB6AB /* LexR.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EF911FA7526004FB6AB /* LexR.cxx */; }; 114B6F4911FA7526004FB6AB /* LexRebol.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EFA11FA7526004FB6AB /* LexRebol.cxx */; }; 114B6F4A11FA7526004FB6AB /* LexRuby.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EFB11FA7526004FB6AB /* LexRuby.cxx */; }; 114B6F4B11FA7526004FB6AB /* LexScriptol.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EFC11FA7526004FB6AB /* LexScriptol.cxx */; }; 114B6F4C11FA7526004FB6AB /* LexSmalltalk.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EFD11FA7526004FB6AB /* LexSmalltalk.cxx */; }; 114B6F4D11FA7526004FB6AB /* LexSML.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EFE11FA7526004FB6AB /* LexSML.cxx */; }; 114B6F4E11FA7526004FB6AB /* LexSorcus.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6EFF11FA7526004FB6AB /* LexSorcus.cxx */; }; 114B6F4F11FA7526004FB6AB /* LexSpecman.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F0011FA7526004FB6AB /* LexSpecman.cxx */; }; 114B6F5011FA7526004FB6AB /* LexSpice.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F0111FA7526004FB6AB /* LexSpice.cxx */; }; 114B6F5111FA7526004FB6AB /* LexSQL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F0211FA7526004FB6AB /* LexSQL.cxx */; }; 114B6F5211FA7526004FB6AB /* LexTACL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F0311FA7526004FB6AB /* LexTACL.cxx */; }; 114B6F5311FA7526004FB6AB /* LexTADS3.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F0411FA7526004FB6AB /* LexTADS3.cxx */; }; 114B6F5411FA7526004FB6AB /* LexTAL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F0511FA7526004FB6AB /* LexTAL.cxx */; }; 114B6F5511FA7526004FB6AB /* LexTCL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F0611FA7526004FB6AB /* LexTCL.cxx */; }; 114B6F5611FA7526004FB6AB /* LexTeX.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F0711FA7526004FB6AB /* LexTeX.cxx */; }; 114B6F5711FA7526004FB6AB /* LexTxt2tags.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F0811FA7526004FB6AB /* LexTxt2tags.cxx */; }; 114B6F5811FA7526004FB6AB /* LexVB.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F0911FA7526004FB6AB /* LexVB.cxx */; }; 114B6F5911FA7526004FB6AB /* LexVerilog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F0A11FA7526004FB6AB /* LexVerilog.cxx */; }; 114B6F5A11FA7526004FB6AB /* LexVHDL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F0B11FA7526004FB6AB /* LexVHDL.cxx */; }; 114B6F5B11FA7526004FB6AB /* LexYAML.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F0C11FA7526004FB6AB /* LexYAML.cxx */; }; 114B6F7711FA7598004FB6AB /* AutoComplete.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F6011FA7597004FB6AB /* AutoComplete.cxx */; }; 114B6F7811FA7598004FB6AB /* CallTip.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F6111FA7597004FB6AB /* CallTip.cxx */; }; 114B6F7911FA7598004FB6AB /* Catalogue.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F6211FA7597004FB6AB /* Catalogue.cxx */; }; 114B6F7A11FA7598004FB6AB /* CellBuffer.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F6311FA7597004FB6AB /* CellBuffer.cxx */; }; 114B6F7B11FA7598004FB6AB /* CharClassify.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F6411FA7597004FB6AB /* CharClassify.cxx */; }; 114B6F7C11FA7598004FB6AB /* ContractionState.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F6511FA7597004FB6AB /* ContractionState.cxx */; }; 114B6F7D11FA7598004FB6AB /* Decoration.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F6611FA7597004FB6AB /* Decoration.cxx */; }; 114B6F7E11FA7598004FB6AB /* Document.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F6711FA7597004FB6AB /* Document.cxx */; }; 114B6F7F11FA7598004FB6AB /* Editor.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F6811FA7597004FB6AB /* Editor.cxx */; }; 114B6F8011FA7598004FB6AB /* ExternalLexer.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F6911FA7598004FB6AB /* ExternalLexer.cxx */; }; 114B6F8111FA7598004FB6AB /* Indicator.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F6A11FA7598004FB6AB /* Indicator.cxx */; }; 114B6F8211FA7598004FB6AB /* KeyMap.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F6B11FA7598004FB6AB /* KeyMap.cxx */; }; 114B6F8311FA7598004FB6AB /* LineMarker.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F6C11FA7598004FB6AB /* LineMarker.cxx */; }; 114B6F8411FA7598004FB6AB /* PerLine.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F6D11FA7598004FB6AB /* PerLine.cxx */; }; 114B6F8511FA7598004FB6AB /* PositionCache.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F6E11FA7598004FB6AB /* PositionCache.cxx */; }; 114B6F8611FA7598004FB6AB /* RESearch.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F6F11FA7598004FB6AB /* RESearch.cxx */; }; 114B6F8711FA7598004FB6AB /* RunStyles.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F7011FA7598004FB6AB /* RunStyles.cxx */; }; 114B6F8811FA7598004FB6AB /* ScintillaBase.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F7111FA7598004FB6AB /* ScintillaBase.cxx */; }; 114B6F8911FA7598004FB6AB /* Selection.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F7211FA7598004FB6AB /* Selection.cxx */; }; 114B6F8A11FA7598004FB6AB /* Style.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F7311FA7598004FB6AB /* Style.cxx */; }; 114B6F8B11FA7598004FB6AB /* UniConversion.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F7411FA7598004FB6AB /* UniConversion.cxx */; }; 114B6F8C11FA7598004FB6AB /* ViewStyle.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F7511FA7598004FB6AB /* ViewStyle.cxx */; }; 114B6F8D11FA7598004FB6AB /* XPM.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F7611FA7598004FB6AB /* XPM.cxx */; }; 114B6F9711FA75BE004FB6AB /* Accessor.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F8E11FA75BE004FB6AB /* Accessor.cxx */; }; 114B6F9811FA75BE004FB6AB /* CharacterSet.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F8F11FA75BE004FB6AB /* CharacterSet.cxx */; }; 114B6F9911FA75BE004FB6AB /* LexerBase.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F9011FA75BE004FB6AB /* LexerBase.cxx */; }; 114B6F9A11FA75BE004FB6AB /* LexerModule.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F9111FA75BE004FB6AB /* LexerModule.cxx */; }; 114B6F9B11FA75BE004FB6AB /* LexerNoExceptions.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F9211FA75BE004FB6AB /* LexerNoExceptions.cxx */; }; 114B6F9C11FA75BE004FB6AB /* LexerSimple.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F9311FA75BE004FB6AB /* LexerSimple.cxx */; }; 114B6F9D11FA75BE004FB6AB /* PropSetSimple.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F9411FA75BE004FB6AB /* PropSetSimple.cxx */; }; 114B6F9E11FA75BE004FB6AB /* StyleContext.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F9511FA75BE004FB6AB /* StyleContext.cxx */; }; 114B6F9F11FA75BE004FB6AB /* WordList.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 114B6F9611FA75BE004FB6AB /* WordList.cxx */; }; 114B6FA111FA75DB004FB6AB /* ILexer.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FA011FA75DB004FB6AB /* ILexer.h */; }; 114B6FBD11FA7623004FB6AB /* AutoComplete.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FA211FA7623004FB6AB /* AutoComplete.h */; }; 114B6FBE11FA7623004FB6AB /* CallTip.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FA311FA7623004FB6AB /* CallTip.h */; }; 114B6FBF11FA7623004FB6AB /* Catalogue.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FA411FA7623004FB6AB /* Catalogue.h */; }; 114B6FC011FA7623004FB6AB /* CellBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FA511FA7623004FB6AB /* CellBuffer.h */; }; 114B6FC111FA7623004FB6AB /* CharClassify.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FA611FA7623004FB6AB /* CharClassify.h */; }; 114B6FC211FA7623004FB6AB /* ContractionState.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FA711FA7623004FB6AB /* ContractionState.h */; }; 114B6FC311FA7623004FB6AB /* Decoration.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FA811FA7623004FB6AB /* Decoration.h */; }; 114B6FC411FA7623004FB6AB /* Document.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FA911FA7623004FB6AB /* Document.h */; }; 114B6FC511FA7623004FB6AB /* Editor.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FAA11FA7623004FB6AB /* Editor.h */; }; 114B6FC611FA7623004FB6AB /* ExternalLexer.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FAB11FA7623004FB6AB /* ExternalLexer.h */; }; 114B6FC711FA7623004FB6AB /* FontQuality.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FAC11FA7623004FB6AB /* FontQuality.h */; }; 114B6FC811FA7623004FB6AB /* Indicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FAD11FA7623004FB6AB /* Indicator.h */; }; 114B6FC911FA7623004FB6AB /* KeyMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FAE11FA7623004FB6AB /* KeyMap.h */; }; 114B6FCA11FA7623004FB6AB /* LineMarker.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FAF11FA7623004FB6AB /* LineMarker.h */; }; 114B6FCB11FA7623004FB6AB /* Partitioning.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FB011FA7623004FB6AB /* Partitioning.h */; }; 114B6FCC11FA7623004FB6AB /* PerLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FB111FA7623004FB6AB /* PerLine.h */; }; 114B6FCD11FA7623004FB6AB /* PositionCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FB211FA7623004FB6AB /* PositionCache.h */; }; 114B6FCE11FA7623004FB6AB /* RESearch.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FB311FA7623004FB6AB /* RESearch.h */; }; 114B6FCF11FA7623004FB6AB /* RunStyles.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FB411FA7623004FB6AB /* RunStyles.h */; }; 114B6FD011FA7623004FB6AB /* ScintillaBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FB511FA7623004FB6AB /* ScintillaBase.h */; }; 114B6FD111FA7623004FB6AB /* Selection.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FB611FA7623004FB6AB /* Selection.h */; }; 114B6FD211FA7623004FB6AB /* SplitVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FB711FA7623004FB6AB /* SplitVector.h */; }; 114B6FD311FA7623004FB6AB /* Style.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FB811FA7623004FB6AB /* Style.h */; }; 114B6FD411FA7623004FB6AB /* SVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FB911FA7623004FB6AB /* SVector.h */; }; 114B6FD511FA7623004FB6AB /* UniConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FBA11FA7623004FB6AB /* UniConversion.h */; }; 114B6FD611FA7623004FB6AB /* ViewStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FBB11FA7623004FB6AB /* ViewStyle.h */; }; 114B6FD711FA7623004FB6AB /* XPM.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FBC11FA7623004FB6AB /* XPM.h */; }; 114B6FE311FA7645004FB6AB /* Accessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FD811FA7645004FB6AB /* Accessor.h */; }; 114B6FE411FA7645004FB6AB /* CharacterSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FD911FA7645004FB6AB /* CharacterSet.h */; }; 114B6FE511FA7645004FB6AB /* LexAccessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FDA11FA7645004FB6AB /* LexAccessor.h */; }; 114B6FE611FA7645004FB6AB /* LexerBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FDB11FA7645004FB6AB /* LexerBase.h */; }; 114B6FE711FA7645004FB6AB /* LexerModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FDC11FA7645004FB6AB /* LexerModule.h */; }; 114B6FE811FA7645004FB6AB /* LexerNoExceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FDD11FA7645004FB6AB /* LexerNoExceptions.h */; }; 114B6FE911FA7645004FB6AB /* LexerSimple.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FDE11FA7645004FB6AB /* LexerSimple.h */; }; 114B6FEA11FA7645004FB6AB /* OptionSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FDF11FA7645004FB6AB /* OptionSet.h */; }; 114B6FEB11FA7645004FB6AB /* PropSetSimple.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FE011FA7645004FB6AB /* PropSetSimple.h */; }; 114B6FEC11FA7645004FB6AB /* StyleContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FE111FA7645004FB6AB /* StyleContext.h */; }; 114B6FED11FA7645004FB6AB /* WordList.h in Headers */ = {isa = PBXBuildFile; fileRef = 114B6FE211FA7645004FB6AB /* WordList.h */; }; 1152A77315313E58000D4E1A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1152A77215313E58000D4E1A /* QuartzCore.framework */; }; 11594BE9155B91DF0099E1FA /* LexOScript.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11594BE7155B91DF0099E1FA /* LexOScript.cxx */; }; 11594BEA155B91DF0099E1FA /* LexVisualProlog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11594BE8155B91DF0099E1FA /* LexVisualProlog.cxx */; }; 117ACE9114A29A1E002876F9 /* LexTCMD.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 117ACE9014A29A1E002876F9 /* LexTCMD.cxx */; }; 119FF1BF13C9D1820007CE42 /* QuartzTextStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 119FF1BE13C9D1820007CE42 /* QuartzTextStyle.h */; }; 11A0A8A1148602DF0018D143 /* LexCoffeeScript.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11A0A8A0148602DF0018D143 /* LexCoffeeScript.cxx */; }; 11BB124D12FF9C1300F6BCF7 /* LexModula.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11BB124C12FF9C1300F6BCF7 /* LexModula.cxx */; }; 11BEB6A214EF189600BDE92A /* LexECL.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11BEB6A114EF189600BDE92A /* LexECL.cxx */; }; 11F35FDB12AEFAF100F0236D /* LexA68k.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 11F35FDA12AEFAF100F0236D /* LexA68k.cxx */; }; 2744E5A40FC168A100E85C33 /* InfoBar.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E59D0FC168A100E85C33 /* InfoBar.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2744E5AA0FC168A100E85C33 /* ScintillaView.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E5A30FC168A100E85C33 /* ScintillaView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2744E5AC0FC168B200E85C33 /* InfoBarCommunicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E5AB0FC168B200E85C33 /* InfoBarCommunicator.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2744E5B20FC168C500E85C33 /* InfoBar.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5AD0FC168C500E85C33 /* InfoBar.mm */; }; 2744E5B30FC168C500E85C33 /* PlatCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5AE0FC168C500E85C33 /* PlatCocoa.mm */; }; 2744E5B50FC168C500E85C33 /* ScintillaCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5B00FC168C500E85C33 /* ScintillaCocoa.mm */; }; 2744E5B60FC168C500E85C33 /* ScintillaView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2744E5B10FC168C500E85C33 /* ScintillaView.mm */; }; 2791F3C60FC19F71009DBCF9 /* PlatCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E59E0FC168A100E85C33 /* PlatCocoa.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2791F3C70FC19F71009DBCF9 /* Platform.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4850FC1678600E85C33 /* Platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2791F3C80FC19F71009DBCF9 /* SciLexer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4870FC1678600E85C33 /* SciLexer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2791F3C90FC19F71009DBCF9 /* Scintilla.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E4880FC1678600E85C33 /* Scintilla.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2791F3E00FC1A390009DBCF9 /* ScintillaCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E5A20FC168A100E85C33 /* ScintillaCocoa.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2791F3E30FC1A3AE009DBCF9 /* QuartzTextLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E59F0FC168A100E85C33 /* QuartzTextLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2791F3E40FC1A3AE009DBCF9 /* QuartzTextStyleAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 2744E5A00FC168A100E85C33 /* QuartzTextStyleAttribute.h */; settings = {ATTRIBUTES = (Public, ); }; }; 27FEF4540FC1B413005E115A /* info_bar_bg.png in Resources */ = {isa = PBXBuildFile; fileRef = 27FEF4510FC1B413005E115A /* info_bar_bg.png */; }; 27FEF4550FC1B413005E115A /* mac_cursor_busy.png in Resources */ = {isa = PBXBuildFile; fileRef = 27FEF4520FC1B413005E115A /* mac_cursor_busy.png */; }; 27FEF4560FC1B413005E115A /* mac_cursor_flipped.png in Resources */ = {isa = PBXBuildFile; fileRef = 27FEF4530FC1B413005E115A /* mac_cursor_flipped.png */; }; 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; }; 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 0867D69BFE84028FC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; }; 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; }; 089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; }; 1102C31B169FB49300DC16AB /* LexLaTeX.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexLaTeX.cxx; path = ../../lexers/LexLaTeX.cxx; sourceTree = "<group>"; }; 11126B8114CD3A6200803C49 /* LexAVS.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAVS.cxx; path = ../../lexers/LexAVS.cxx; sourceTree = "<group>"; }; 1114D6CA1602A951001DC345 /* LexPO.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPO.cxx; path = ../../lexers/LexPO.cxx; sourceTree = "<group>"; }; 114B6EBE11FA7526004FB6AB /* LexAbaqus.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAbaqus.cxx; path = ../../lexers/LexAbaqus.cxx; sourceTree = SOURCE_ROOT; }; 114B6EBF11FA7526004FB6AB /* LexAda.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAda.cxx; path = ../../lexers/LexAda.cxx; sourceTree = SOURCE_ROOT; }; 114B6EC011FA7526004FB6AB /* LexAPDL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAPDL.cxx; path = ../../lexers/LexAPDL.cxx; sourceTree = SOURCE_ROOT; }; 114B6EC111FA7526004FB6AB /* LexAsm.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAsm.cxx; path = ../../lexers/LexAsm.cxx; sourceTree = SOURCE_ROOT; }; 114B6EC211FA7526004FB6AB /* LexAsn1.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAsn1.cxx; path = ../../lexers/LexAsn1.cxx; sourceTree = SOURCE_ROOT; }; 114B6EC311FA7526004FB6AB /* LexASY.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexASY.cxx; path = ../../lexers/LexASY.cxx; sourceTree = SOURCE_ROOT; }; 114B6EC411FA7526004FB6AB /* LexAU3.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAU3.cxx; path = ../../lexers/LexAU3.cxx; sourceTree = SOURCE_ROOT; }; 114B6EC511FA7526004FB6AB /* LexAVE.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAVE.cxx; path = ../../lexers/LexAVE.cxx; sourceTree = SOURCE_ROOT; }; 114B6EC611FA7526004FB6AB /* LexBaan.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexBaan.cxx; path = ../../lexers/LexBaan.cxx; sourceTree = SOURCE_ROOT; }; 114B6EC711FA7526004FB6AB /* LexBash.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexBash.cxx; path = ../../lexers/LexBash.cxx; sourceTree = SOURCE_ROOT; }; 114B6EC811FA7526004FB6AB /* LexBasic.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexBasic.cxx; path = ../../lexers/LexBasic.cxx; sourceTree = SOURCE_ROOT; }; 114B6EC911FA7526004FB6AB /* LexBullant.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexBullant.cxx; path = ../../lexers/LexBullant.cxx; sourceTree = SOURCE_ROOT; }; 114B6ECA11FA7526004FB6AB /* LexCaml.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCaml.cxx; path = ../../lexers/LexCaml.cxx; sourceTree = SOURCE_ROOT; }; 114B6ECB11FA7526004FB6AB /* LexCLW.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCLW.cxx; path = ../../lexers/LexCLW.cxx; sourceTree = SOURCE_ROOT; }; 114B6ECC11FA7526004FB6AB /* LexCmake.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCmake.cxx; path = ../../lexers/LexCmake.cxx; sourceTree = SOURCE_ROOT; }; 114B6ECD11FA7526004FB6AB /* LexCOBOL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCOBOL.cxx; path = ../../lexers/LexCOBOL.cxx; sourceTree = SOURCE_ROOT; }; 114B6ECE11FA7526004FB6AB /* LexConf.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexConf.cxx; path = ../../lexers/LexConf.cxx; sourceTree = SOURCE_ROOT; }; 114B6ECF11FA7526004FB6AB /* LexCPP.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCPP.cxx; path = ../../lexers/LexCPP.cxx; sourceTree = SOURCE_ROOT; }; 114B6ED011FA7526004FB6AB /* LexCrontab.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCrontab.cxx; path = ../../lexers/LexCrontab.cxx; sourceTree = SOURCE_ROOT; }; 114B6ED111FA7526004FB6AB /* LexCsound.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCsound.cxx; path = ../../lexers/LexCsound.cxx; sourceTree = SOURCE_ROOT; }; 114B6ED211FA7526004FB6AB /* LexCSS.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCSS.cxx; path = ../../lexers/LexCSS.cxx; sourceTree = SOURCE_ROOT; }; 114B6ED311FA7526004FB6AB /* LexD.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexD.cxx; path = ../../lexers/LexD.cxx; sourceTree = SOURCE_ROOT; }; 114B6ED411FA7526004FB6AB /* LexEiffel.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexEiffel.cxx; path = ../../lexers/LexEiffel.cxx; sourceTree = SOURCE_ROOT; }; 114B6ED511FA7526004FB6AB /* LexErlang.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexErlang.cxx; path = ../../lexers/LexErlang.cxx; sourceTree = SOURCE_ROOT; }; 114B6ED611FA7526004FB6AB /* LexEScript.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexEScript.cxx; path = ../../lexers/LexEScript.cxx; sourceTree = SOURCE_ROOT; }; 114B6ED711FA7526004FB6AB /* LexFlagship.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexFlagship.cxx; path = ../../lexers/LexFlagship.cxx; sourceTree = SOURCE_ROOT; }; 114B6ED811FA7526004FB6AB /* LexForth.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexForth.cxx; path = ../../lexers/LexForth.cxx; sourceTree = SOURCE_ROOT; }; 114B6ED911FA7526004FB6AB /* LexFortran.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexFortran.cxx; path = ../../lexers/LexFortran.cxx; sourceTree = SOURCE_ROOT; }; 114B6EDA11FA7526004FB6AB /* LexGAP.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexGAP.cxx; path = ../../lexers/LexGAP.cxx; sourceTree = SOURCE_ROOT; }; 114B6EDB11FA7526004FB6AB /* LexGui4Cli.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexGui4Cli.cxx; path = ../../lexers/LexGui4Cli.cxx; sourceTree = SOURCE_ROOT; }; 114B6EDC11FA7526004FB6AB /* LexHaskell.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexHaskell.cxx; path = ../../lexers/LexHaskell.cxx; sourceTree = SOURCE_ROOT; }; 114B6EDD11FA7526004FB6AB /* LexHTML.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexHTML.cxx; path = ../../lexers/LexHTML.cxx; sourceTree = SOURCE_ROOT; }; 114B6EDE11FA7526004FB6AB /* LexInno.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexInno.cxx; path = ../../lexers/LexInno.cxx; sourceTree = SOURCE_ROOT; }; 114B6EDF11FA7526004FB6AB /* LexKix.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexKix.cxx; path = ../../lexers/LexKix.cxx; sourceTree = SOURCE_ROOT; }; 114B6EE011FA7526004FB6AB /* LexLisp.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexLisp.cxx; path = ../../lexers/LexLisp.cxx; sourceTree = SOURCE_ROOT; }; 114B6EE111FA7526004FB6AB /* LexLout.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexLout.cxx; path = ../../lexers/LexLout.cxx; sourceTree = SOURCE_ROOT; }; 114B6EE211FA7526004FB6AB /* LexLua.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexLua.cxx; path = ../../lexers/LexLua.cxx; sourceTree = SOURCE_ROOT; }; 114B6EE311FA7526004FB6AB /* LexMagik.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMagik.cxx; path = ../../lexers/LexMagik.cxx; sourceTree = SOURCE_ROOT; }; 114B6EE411FA7526004FB6AB /* LexMarkdown.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMarkdown.cxx; path = ../../lexers/LexMarkdown.cxx; sourceTree = SOURCE_ROOT; }; 114B6EE511FA7526004FB6AB /* LexMatlab.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMatlab.cxx; path = ../../lexers/LexMatlab.cxx; sourceTree = SOURCE_ROOT; }; 114B6EE611FA7526004FB6AB /* LexMetapost.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMetapost.cxx; path = ../../lexers/LexMetapost.cxx; sourceTree = SOURCE_ROOT; }; 114B6EE711FA7526004FB6AB /* LexMMIXAL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMMIXAL.cxx; path = ../../lexers/LexMMIXAL.cxx; sourceTree = SOURCE_ROOT; }; 114B6EE811FA7526004FB6AB /* LexMPT.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMPT.cxx; path = ../../lexers/LexMPT.cxx; sourceTree = SOURCE_ROOT; }; 114B6EE911FA7526004FB6AB /* LexMSSQL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMSSQL.cxx; path = ../../lexers/LexMSSQL.cxx; sourceTree = SOURCE_ROOT; }; 114B6EEA11FA7526004FB6AB /* LexMySQL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexMySQL.cxx; path = ../../lexers/LexMySQL.cxx; sourceTree = SOURCE_ROOT; }; 114B6EEB11FA7526004FB6AB /* LexNimrod.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexNimrod.cxx; path = ../../lexers/LexNimrod.cxx; sourceTree = SOURCE_ROOT; }; 114B6EEC11FA7526004FB6AB /* LexNsis.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexNsis.cxx; path = ../../lexers/LexNsis.cxx; sourceTree = SOURCE_ROOT; }; 114B6EED11FA7526004FB6AB /* LexOpal.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexOpal.cxx; path = ../../lexers/LexOpal.cxx; sourceTree = SOURCE_ROOT; }; 114B6EEE11FA7526004FB6AB /* LexOthers.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexOthers.cxx; path = ../../lexers/LexOthers.cxx; sourceTree = SOURCE_ROOT; }; 114B6EEF11FA7526004FB6AB /* LexPascal.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPascal.cxx; path = ../../lexers/LexPascal.cxx; sourceTree = SOURCE_ROOT; }; 114B6EF011FA7526004FB6AB /* LexPB.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPB.cxx; path = ../../lexers/LexPB.cxx; sourceTree = SOURCE_ROOT; }; 114B6EF111FA7526004FB6AB /* LexPerl.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPerl.cxx; path = ../../lexers/LexPerl.cxx; sourceTree = SOURCE_ROOT; }; 114B6EF211FA7526004FB6AB /* LexPLM.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPLM.cxx; path = ../../lexers/LexPLM.cxx; sourceTree = SOURCE_ROOT; }; 114B6EF311FA7526004FB6AB /* LexPOV.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPOV.cxx; path = ../../lexers/LexPOV.cxx; sourceTree = SOURCE_ROOT; }; 114B6EF411FA7526004FB6AB /* LexPowerPro.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPowerPro.cxx; path = ../../lexers/LexPowerPro.cxx; sourceTree = SOURCE_ROOT; }; 114B6EF511FA7526004FB6AB /* LexPowerShell.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPowerShell.cxx; path = ../../lexers/LexPowerShell.cxx; sourceTree = SOURCE_ROOT; }; 114B6EF611FA7526004FB6AB /* LexProgress.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexProgress.cxx; path = ../../lexers/LexProgress.cxx; sourceTree = SOURCE_ROOT; }; 114B6EF711FA7526004FB6AB /* LexPS.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPS.cxx; path = ../../lexers/LexPS.cxx; sourceTree = SOURCE_ROOT; }; 114B6EF811FA7526004FB6AB /* LexPython.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexPython.cxx; path = ../../lexers/LexPython.cxx; sourceTree = SOURCE_ROOT; }; 114B6EF911FA7526004FB6AB /* LexR.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexR.cxx; path = ../../lexers/LexR.cxx; sourceTree = SOURCE_ROOT; }; 114B6EFA11FA7526004FB6AB /* LexRebol.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexRebol.cxx; path = ../../lexers/LexRebol.cxx; sourceTree = SOURCE_ROOT; }; 114B6EFB11FA7526004FB6AB /* LexRuby.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexRuby.cxx; path = ../../lexers/LexRuby.cxx; sourceTree = SOURCE_ROOT; }; 114B6EFC11FA7526004FB6AB /* LexScriptol.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexScriptol.cxx; path = ../../lexers/LexScriptol.cxx; sourceTree = SOURCE_ROOT; }; 114B6EFD11FA7526004FB6AB /* LexSmalltalk.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSmalltalk.cxx; path = ../../lexers/LexSmalltalk.cxx; sourceTree = SOURCE_ROOT; }; 114B6EFE11FA7526004FB6AB /* LexSML.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSML.cxx; path = ../../lexers/LexSML.cxx; sourceTree = SOURCE_ROOT; }; 114B6EFF11FA7526004FB6AB /* LexSorcus.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSorcus.cxx; path = ../../lexers/LexSorcus.cxx; sourceTree = SOURCE_ROOT; }; 114B6F0011FA7526004FB6AB /* LexSpecman.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSpecman.cxx; path = ../../lexers/LexSpecman.cxx; sourceTree = SOURCE_ROOT; }; 114B6F0111FA7526004FB6AB /* LexSpice.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSpice.cxx; path = ../../lexers/LexSpice.cxx; sourceTree = SOURCE_ROOT; }; 114B6F0211FA7526004FB6AB /* LexSQL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexSQL.cxx; path = ../../lexers/LexSQL.cxx; sourceTree = SOURCE_ROOT; }; 114B6F0311FA7526004FB6AB /* LexTACL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTACL.cxx; path = ../../lexers/LexTACL.cxx; sourceTree = SOURCE_ROOT; }; 114B6F0411FA7526004FB6AB /* LexTADS3.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTADS3.cxx; path = ../../lexers/LexTADS3.cxx; sourceTree = SOURCE_ROOT; }; 114B6F0511FA7526004FB6AB /* LexTAL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTAL.cxx; path = ../../lexers/LexTAL.cxx; sourceTree = SOURCE_ROOT; }; 114B6F0611FA7526004FB6AB /* LexTCL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTCL.cxx; path = ../../lexers/LexTCL.cxx; sourceTree = SOURCE_ROOT; }; 114B6F0711FA7526004FB6AB /* LexTeX.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTeX.cxx; path = ../../lexers/LexTeX.cxx; sourceTree = SOURCE_ROOT; }; 114B6F0811FA7526004FB6AB /* LexTxt2tags.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTxt2tags.cxx; path = ../../lexers/LexTxt2tags.cxx; sourceTree = SOURCE_ROOT; }; 114B6F0911FA7526004FB6AB /* LexVB.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexVB.cxx; path = ../../lexers/LexVB.cxx; sourceTree = SOURCE_ROOT; }; 114B6F0A11FA7526004FB6AB /* LexVerilog.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexVerilog.cxx; path = ../../lexers/LexVerilog.cxx; sourceTree = SOURCE_ROOT; }; 114B6F0B11FA7526004FB6AB /* LexVHDL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexVHDL.cxx; path = ../../lexers/LexVHDL.cxx; sourceTree = SOURCE_ROOT; }; 114B6F0C11FA7526004FB6AB /* LexYAML.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexYAML.cxx; path = ../../lexers/LexYAML.cxx; sourceTree = SOURCE_ROOT; }; 114B6F6011FA7597004FB6AB /* AutoComplete.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AutoComplete.cxx; path = ../../src/AutoComplete.cxx; sourceTree = SOURCE_ROOT; }; 114B6F6111FA7597004FB6AB /* CallTip.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CallTip.cxx; path = ../../src/CallTip.cxx; sourceTree = SOURCE_ROOT; }; 114B6F6211FA7597004FB6AB /* Catalogue.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Catalogue.cxx; path = ../../src/Catalogue.cxx; sourceTree = SOURCE_ROOT; }; 114B6F6311FA7597004FB6AB /* CellBuffer.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CellBuffer.cxx; path = ../../src/CellBuffer.cxx; sourceTree = SOURCE_ROOT; }; 114B6F6411FA7597004FB6AB /* CharClassify.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CharClassify.cxx; path = ../../src/CharClassify.cxx; sourceTree = SOURCE_ROOT; }; 114B6F6511FA7597004FB6AB /* ContractionState.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ContractionState.cxx; path = ../../src/ContractionState.cxx; sourceTree = SOURCE_ROOT; }; 114B6F6611FA7597004FB6AB /* Decoration.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Decoration.cxx; path = ../../src/Decoration.cxx; sourceTree = SOURCE_ROOT; }; 114B6F6711FA7597004FB6AB /* Document.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Document.cxx; path = ../../src/Document.cxx; sourceTree = SOURCE_ROOT; }; 114B6F6811FA7597004FB6AB /* Editor.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Editor.cxx; path = ../../src/Editor.cxx; sourceTree = SOURCE_ROOT; }; 114B6F6911FA7598004FB6AB /* ExternalLexer.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExternalLexer.cxx; path = ../../src/ExternalLexer.cxx; sourceTree = SOURCE_ROOT; }; 114B6F6A11FA7598004FB6AB /* Indicator.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Indicator.cxx; path = ../../src/Indicator.cxx; sourceTree = SOURCE_ROOT; }; 114B6F6B11FA7598004FB6AB /* KeyMap.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KeyMap.cxx; path = ../../src/KeyMap.cxx; sourceTree = SOURCE_ROOT; }; 114B6F6C11FA7598004FB6AB /* LineMarker.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LineMarker.cxx; path = ../../src/LineMarker.cxx; sourceTree = SOURCE_ROOT; }; 114B6F6D11FA7598004FB6AB /* PerLine.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PerLine.cxx; path = ../../src/PerLine.cxx; sourceTree = SOURCE_ROOT; }; 114B6F6E11FA7598004FB6AB /* PositionCache.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PositionCache.cxx; path = ../../src/PositionCache.cxx; sourceTree = SOURCE_ROOT; }; 114B6F6F11FA7598004FB6AB /* RESearch.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RESearch.cxx; path = ../../src/RESearch.cxx; sourceTree = SOURCE_ROOT; }; 114B6F7011FA7598004FB6AB /* RunStyles.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RunStyles.cxx; path = ../../src/RunStyles.cxx; sourceTree = SOURCE_ROOT; }; 114B6F7111FA7598004FB6AB /* ScintillaBase.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScintillaBase.cxx; path = ../../src/ScintillaBase.cxx; sourceTree = SOURCE_ROOT; }; 114B6F7211FA7598004FB6AB /* Selection.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Selection.cxx; path = ../../src/Selection.cxx; sourceTree = SOURCE_ROOT; }; 114B6F7311FA7598004FB6AB /* Style.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Style.cxx; path = ../../src/Style.cxx; sourceTree = SOURCE_ROOT; }; 114B6F7411FA7598004FB6AB /* UniConversion.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UniConversion.cxx; path = ../../src/UniConversion.cxx; sourceTree = SOURCE_ROOT; }; 114B6F7511FA7598004FB6AB /* ViewStyle.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ViewStyle.cxx; path = ../../src/ViewStyle.cxx; sourceTree = SOURCE_ROOT; }; 114B6F7611FA7598004FB6AB /* XPM.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = XPM.cxx; path = ../../src/XPM.cxx; sourceTree = SOURCE_ROOT; }; 114B6F8E11FA75BE004FB6AB /* Accessor.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Accessor.cxx; path = ../../lexlib/Accessor.cxx; sourceTree = SOURCE_ROOT; }; 114B6F8F11FA75BE004FB6AB /* CharacterSet.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CharacterSet.cxx; path = ../../lexlib/CharacterSet.cxx; sourceTree = SOURCE_ROOT; }; 114B6F9011FA75BE004FB6AB /* LexerBase.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexerBase.cxx; path = ../../lexlib/LexerBase.cxx; sourceTree = SOURCE_ROOT; }; 114B6F9111FA75BE004FB6AB /* LexerModule.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexerModule.cxx; path = ../../lexlib/LexerModule.cxx; sourceTree = SOURCE_ROOT; }; 114B6F9211FA75BE004FB6AB /* LexerNoExceptions.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexerNoExceptions.cxx; path = ../../lexlib/LexerNoExceptions.cxx; sourceTree = SOURCE_ROOT; }; 114B6F9311FA75BE004FB6AB /* LexerSimple.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexerSimple.cxx; path = ../../lexlib/LexerSimple.cxx; sourceTree = SOURCE_ROOT; }; 114B6F9411FA75BE004FB6AB /* PropSetSimple.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PropSetSimple.cxx; path = ../../lexlib/PropSetSimple.cxx; sourceTree = SOURCE_ROOT; }; 114B6F9511FA75BE004FB6AB /* StyleContext.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StyleContext.cxx; path = ../../lexlib/StyleContext.cxx; sourceTree = SOURCE_ROOT; }; 114B6F9611FA75BE004FB6AB /* WordList.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WordList.cxx; path = ../../lexlib/WordList.cxx; sourceTree = SOURCE_ROOT; }; 114B6FA011FA75DB004FB6AB /* ILexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ILexer.h; path = ../../include/ILexer.h; sourceTree = SOURCE_ROOT; }; 114B6FA211FA7623004FB6AB /* AutoComplete.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AutoComplete.h; path = ../../src/AutoComplete.h; sourceTree = SOURCE_ROOT; }; 114B6FA311FA7623004FB6AB /* CallTip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CallTip.h; path = ../../src/CallTip.h; sourceTree = SOURCE_ROOT; }; 114B6FA411FA7623004FB6AB /* Catalogue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Catalogue.h; path = ../../src/Catalogue.h; sourceTree = SOURCE_ROOT; }; 114B6FA511FA7623004FB6AB /* CellBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CellBuffer.h; path = ../../src/CellBuffer.h; sourceTree = SOURCE_ROOT; }; 114B6FA611FA7623004FB6AB /* CharClassify.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CharClassify.h; path = ../../src/CharClassify.h; sourceTree = SOURCE_ROOT; }; 114B6FA711FA7623004FB6AB /* ContractionState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ContractionState.h; path = ../../src/ContractionState.h; sourceTree = SOURCE_ROOT; }; 114B6FA811FA7623004FB6AB /* Decoration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Decoration.h; path = ../../src/Decoration.h; sourceTree = SOURCE_ROOT; }; 114B6FA911FA7623004FB6AB /* Document.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Document.h; path = ../../src/Document.h; sourceTree = SOURCE_ROOT; }; 114B6FAA11FA7623004FB6AB /* Editor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Editor.h; path = ../../src/Editor.h; sourceTree = SOURCE_ROOT; }; 114B6FAB11FA7623004FB6AB /* ExternalLexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExternalLexer.h; path = ../../src/ExternalLexer.h; sourceTree = SOURCE_ROOT; }; 114B6FAC11FA7623004FB6AB /* FontQuality.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FontQuality.h; path = ../../src/FontQuality.h; sourceTree = SOURCE_ROOT; }; 114B6FAD11FA7623004FB6AB /* Indicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Indicator.h; path = ../../src/Indicator.h; sourceTree = SOURCE_ROOT; }; 114B6FAE11FA7623004FB6AB /* KeyMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KeyMap.h; path = ../../src/KeyMap.h; sourceTree = SOURCE_ROOT; }; 114B6FAF11FA7623004FB6AB /* LineMarker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LineMarker.h; path = ../../src/LineMarker.h; sourceTree = SOURCE_ROOT; }; 114B6FB011FA7623004FB6AB /* Partitioning.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Partitioning.h; path = ../../src/Partitioning.h; sourceTree = SOURCE_ROOT; }; 114B6FB111FA7623004FB6AB /* PerLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PerLine.h; path = ../../src/PerLine.h; sourceTree = SOURCE_ROOT; }; 114B6FB211FA7623004FB6AB /* PositionCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PositionCache.h; path = ../../src/PositionCache.h; sourceTree = SOURCE_ROOT; }; 114B6FB311FA7623004FB6AB /* RESearch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RESearch.h; path = ../../src/RESearch.h; sourceTree = SOURCE_ROOT; }; 114B6FB411FA7623004FB6AB /* RunStyles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RunStyles.h; path = ../../src/RunStyles.h; sourceTree = SOURCE_ROOT; }; 114B6FB511FA7623004FB6AB /* ScintillaBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScintillaBase.h; path = ../../src/ScintillaBase.h; sourceTree = SOURCE_ROOT; }; 114B6FB611FA7623004FB6AB /* Selection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Selection.h; path = ../../src/Selection.h; sourceTree = SOURCE_ROOT; }; 114B6FB711FA7623004FB6AB /* SplitVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SplitVector.h; path = ../../src/SplitVector.h; sourceTree = SOURCE_ROOT; }; 114B6FB811FA7623004FB6AB /* Style.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Style.h; path = ../../src/Style.h; sourceTree = SOURCE_ROOT; }; 114B6FB911FA7623004FB6AB /* SVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SVector.h; path = ../../src/SVector.h; sourceTree = SOURCE_ROOT; }; 114B6FBA11FA7623004FB6AB /* UniConversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UniConversion.h; path = ../../src/UniConversion.h; sourceTree = SOURCE_ROOT; }; 114B6FBB11FA7623004FB6AB /* ViewStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ViewStyle.h; path = ../../src/ViewStyle.h; sourceTree = SOURCE_ROOT; }; 114B6FBC11FA7623004FB6AB /* XPM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XPM.h; path = ../../src/XPM.h; sourceTree = SOURCE_ROOT; }; 114B6FD811FA7645004FB6AB /* Accessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Accessor.h; path = ../../lexlib/Accessor.h; sourceTree = SOURCE_ROOT; }; 114B6FD911FA7645004FB6AB /* CharacterSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CharacterSet.h; path = ../../lexlib/CharacterSet.h; sourceTree = SOURCE_ROOT; }; 114B6FDA11FA7645004FB6AB /* LexAccessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LexAccessor.h; path = ../../lexlib/LexAccessor.h; sourceTree = SOURCE_ROOT; }; 114B6FDB11FA7645004FB6AB /* LexerBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LexerBase.h; path = ../../lexlib/LexerBase.h; sourceTree = SOURCE_ROOT; }; 114B6FDC11FA7645004FB6AB /* LexerModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LexerModule.h; path = ../../lexlib/LexerModule.h; sourceTree = SOURCE_ROOT; }; 114B6FDD11FA7645004FB6AB /* LexerNoExceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LexerNoExceptions.h; path = ../../lexlib/LexerNoExceptions.h; sourceTree = SOURCE_ROOT; }; 114B6FDE11FA7645004FB6AB /* LexerSimple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LexerSimple.h; path = ../../lexlib/LexerSimple.h; sourceTree = SOURCE_ROOT; }; 114B6FDF11FA7645004FB6AB /* OptionSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OptionSet.h; path = ../../lexlib/OptionSet.h; sourceTree = SOURCE_ROOT; }; 114B6FE011FA7645004FB6AB /* PropSetSimple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PropSetSimple.h; path = ../../lexlib/PropSetSimple.h; sourceTree = SOURCE_ROOT; }; 114B6FE111FA7645004FB6AB /* StyleContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StyleContext.h; path = ../../lexlib/StyleContext.h; sourceTree = SOURCE_ROOT; }; 114B6FE211FA7645004FB6AB /* WordList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WordList.h; path = ../../lexlib/WordList.h; sourceTree = SOURCE_ROOT; }; 1152A77215313E58000D4E1A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = ../../../../../../../../System/Library/Frameworks/QuartzCore.framework; sourceTree = "<group>"; }; 11594BE7155B91DF0099E1FA /* LexOScript.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexOScript.cxx; path = ../../lexers/LexOScript.cxx; sourceTree = "<group>"; }; 11594BE8155B91DF0099E1FA /* LexVisualProlog.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexVisualProlog.cxx; path = ../../lexers/LexVisualProlog.cxx; sourceTree = "<group>"; }; 117ACE9014A29A1E002876F9 /* LexTCMD.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTCMD.cxx; path = ../../lexers/LexTCMD.cxx; sourceTree = "<group>"; }; 119FF1BE13C9D1820007CE42 /* QuartzTextStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QuartzTextStyle.h; path = ../QuartzTextStyle.h; sourceTree = "<group>"; }; 11A0A8A0148602DF0018D143 /* LexCoffeeScript.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexCoffeeScript.cxx; path = ../../lexers/LexCoffeeScript.cxx; sourceTree = "<group>"; }; 11BB124C12FF9C1300F6BCF7 /* LexModula.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexModula.cxx; path = ../../lexers/LexModula.cxx; sourceTree = SOURCE_ROOT; }; 11BEB6A114EF189600BDE92A /* LexECL.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexECL.cxx; path = ../../lexers/LexECL.cxx; sourceTree = "<group>"; }; 11F35FDA12AEFAF100F0236D /* LexA68k.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexA68k.cxx; path = ../../lexers/LexA68k.cxx; sourceTree = SOURCE_ROOT; }; 2744E4850FC1678600E85C33 /* Platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Platform.h; path = ../../include/Platform.h; sourceTree = SOURCE_ROOT; }; 2744E4870FC1678600E85C33 /* SciLexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SciLexer.h; path = ../../include/SciLexer.h; sourceTree = SOURCE_ROOT; }; 2744E4880FC1678600E85C33 /* Scintilla.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Scintilla.h; path = ../../include/Scintilla.h; sourceTree = SOURCE_ROOT; }; 2744E59D0FC168A100E85C33 /* InfoBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InfoBar.h; path = ../InfoBar.h; sourceTree = SOURCE_ROOT; }; 2744E59E0FC168A100E85C33 /* PlatCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlatCocoa.h; path = ../PlatCocoa.h; sourceTree = SOURCE_ROOT; }; 2744E59F0FC168A100E85C33 /* QuartzTextLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QuartzTextLayout.h; path = ../QuartzTextLayout.h; sourceTree = SOURCE_ROOT; }; 2744E5A00FC168A100E85C33 /* QuartzTextStyleAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = QuartzTextStyleAttribute.h; path = ../QuartzTextStyleAttribute.h; sourceTree = SOURCE_ROOT; }; 2744E5A20FC168A100E85C33 /* ScintillaCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScintillaCocoa.h; path = ../ScintillaCocoa.h; sourceTree = "<group>"; }; 2744E5A30FC168A100E85C33 /* ScintillaView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScintillaView.h; path = ../ScintillaView.h; sourceTree = "<group>"; }; 2744E5AB0FC168B200E85C33 /* InfoBarCommunicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InfoBarCommunicator.h; path = ../InfoBarCommunicator.h; sourceTree = SOURCE_ROOT; }; 2744E5AD0FC168C500E85C33 /* InfoBar.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = InfoBar.mm; path = ../InfoBar.mm; sourceTree = SOURCE_ROOT; }; 2744E5AE0FC168C500E85C33 /* PlatCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PlatCocoa.mm; path = ../PlatCocoa.mm; sourceTree = SOURCE_ROOT; }; 2744E5B00FC168C500E85C33 /* ScintillaCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ScintillaCocoa.mm; path = ../ScintillaCocoa.mm; sourceTree = "<group>"; }; 2744E5B10FC168C500E85C33 /* ScintillaView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ScintillaView.mm; path = ../ScintillaView.mm; sourceTree = "<group>"; }; 27FEF4510FC1B413005E115A /* info_bar_bg.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = info_bar_bg.png; sourceTree = "<group>"; }; 27FEF4520FC1B413005E115A /* mac_cursor_busy.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mac_cursor_busy.png; sourceTree = "<group>"; }; 27FEF4530FC1B413005E115A /* mac_cursor_flipped.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mac_cursor_flipped.png; sourceTree = "<group>"; }; 32DBCF5E0370ADEE00C91783 /* Scintilla_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Scintilla_Prefix.pch; sourceTree = "<group>"; }; 8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 8DC2EF5B0486A6940098B216 /* Scintilla.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Scintilla.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D2F7E79907B2D74100F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 8DC2EF560486A6940098B216 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */, 1152A77315313E58000D4E1A /* QuartzCore.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 034768DFFF38A50411DB9C8B /* Products */ = { isa = PBXGroup; children = ( 8DC2EF5B0486A6940098B216 /* Scintilla.framework */, ); name = Products; sourceTree = "<group>"; }; 0867D691FE84028FC02AAC07 /* Scintilla */ = { isa = PBXGroup; children = ( 2744E47D0FC1674E00E85C33 /* Lexers */, 2744E47C0FC1674100E85C33 /* Backend */, 08FB77AEFE84172EC02AAC07 /* Classes */, 32C88DFF0371C24200C91783 /* Other Sources */, 089C1665FE841158C02AAC07 /* Resources */, 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, 034768DFFF38A50411DB9C8B /* Products */, ); name = Scintilla; sourceTree = "<group>"; }; 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { isa = PBXGroup; children = ( 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */, 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */, ); name = "External Frameworks and Libraries"; sourceTree = "<group>"; }; 089C1665FE841158C02AAC07 /* Resources */ = { isa = PBXGroup; children = ( 27FEF4500FC1B413005E115A /* res */, 8DC2EF5A0486A6940098B216 /* Info.plist */, 089C1666FE841158C02AAC07 /* InfoPlist.strings */, ); name = Resources; sourceTree = "<group>"; }; 08FB77AEFE84172EC02AAC07 /* Classes */ = { isa = PBXGroup; children = ( 2744E4980FC167ED00E85C33 /* Source Files */, 2744E4970FC167E400E85C33 /* Header Files */, ); name = Classes; sourceTree = "<group>"; }; 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */ = { isa = PBXGroup; children = ( 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */, ); name = "Linked Frameworks"; sourceTree = "<group>"; }; 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = { isa = PBXGroup; children = ( 1152A77215313E58000D4E1A /* QuartzCore.framework */, 0867D6A5FE840307C02AAC07 /* AppKit.framework */, D2F7E79907B2D74100F64583 /* CoreData.framework */, 0867D69BFE84028FC02AAC07 /* Foundation.framework */, ); name = "Other Frameworks"; sourceTree = "<group>"; }; 2744E47C0FC1674100E85C33 /* Backend */ = { isa = PBXGroup; children = ( 2744E47F0FC1676400E85C33 /* Source Files */, 2744E47E0FC1675800E85C33 /* Header Files */, ); name = Backend; sourceTree = "<group>"; }; 2744E47D0FC1674E00E85C33 /* Lexers */ = { isa = PBXGroup; children = ( 11126B8114CD3A6200803C49 /* LexAVS.cxx */, 11F35FDA12AEFAF100F0236D /* LexA68k.cxx */, 114B6EBE11FA7526004FB6AB /* LexAbaqus.cxx */, 114B6EBF11FA7526004FB6AB /* LexAda.cxx */, 114B6EC011FA7526004FB6AB /* LexAPDL.cxx */, 114B6EC111FA7526004FB6AB /* LexAsm.cxx */, 114B6EC211FA7526004FB6AB /* LexAsn1.cxx */, 114B6EC311FA7526004FB6AB /* LexASY.cxx */, 114B6EC411FA7526004FB6AB /* LexAU3.cxx */, 114B6EC511FA7526004FB6AB /* LexAVE.cxx */, 114B6EC611FA7526004FB6AB /* LexBaan.cxx */, 114B6EC711FA7526004FB6AB /* LexBash.cxx */, 114B6EC811FA7526004FB6AB /* LexBasic.cxx */, 114B6EC911FA7526004FB6AB /* LexBullant.cxx */, 114B6ECA11FA7526004FB6AB /* LexCaml.cxx */, 114B6ECB11FA7526004FB6AB /* LexCLW.cxx */, 114B6ECC11FA7526004FB6AB /* LexCmake.cxx */, 114B6ECD11FA7526004FB6AB /* LexCOBOL.cxx */, 11A0A8A0148602DF0018D143 /* LexCoffeeScript.cxx */, 114B6ECE11FA7526004FB6AB /* LexConf.cxx */, 114B6ECF11FA7526004FB6AB /* LexCPP.cxx */, 114B6ED011FA7526004FB6AB /* LexCrontab.cxx */, 114B6ED111FA7526004FB6AB /* LexCsound.cxx */, 114B6ED211FA7526004FB6AB /* LexCSS.cxx */, 114B6ED311FA7526004FB6AB /* LexD.cxx */, 11BEB6A114EF189600BDE92A /* LexECL.cxx */, 114B6ED411FA7526004FB6AB /* LexEiffel.cxx */, 114B6ED511FA7526004FB6AB /* LexErlang.cxx */, 114B6ED611FA7526004FB6AB /* LexEScript.cxx */, 114B6ED711FA7526004FB6AB /* LexFlagship.cxx */, 114B6ED811FA7526004FB6AB /* LexForth.cxx */, 114B6ED911FA7526004FB6AB /* LexFortran.cxx */, 114B6EDA11FA7526004FB6AB /* LexGAP.cxx */, 114B6EDB11FA7526004FB6AB /* LexGui4Cli.cxx */, 114B6EDC11FA7526004FB6AB /* LexHaskell.cxx */, 114B6EDD11FA7526004FB6AB /* LexHTML.cxx */, 114B6EDE11FA7526004FB6AB /* LexInno.cxx */, 114B6EDF11FA7526004FB6AB /* LexKix.cxx */, 1102C31B169FB49300DC16AB /* LexLaTeX.cxx */, 114B6EE011FA7526004FB6AB /* LexLisp.cxx */, 114B6EE111FA7526004FB6AB /* LexLout.cxx */, 114B6EE211FA7526004FB6AB /* LexLua.cxx */, 114B6EE311FA7526004FB6AB /* LexMagik.cxx */, 114B6EE411FA7526004FB6AB /* LexMarkdown.cxx */, 114B6EE511FA7526004FB6AB /* LexMatlab.cxx */, 114B6EE611FA7526004FB6AB /* LexMetapost.cxx */, 114B6EE711FA7526004FB6AB /* LexMMIXAL.cxx */, 11BB124C12FF9C1300F6BCF7 /* LexModula.cxx */, 114B6EE811FA7526004FB6AB /* LexMPT.cxx */, 114B6EE911FA7526004FB6AB /* LexMSSQL.cxx */, 114B6EEA11FA7526004FB6AB /* LexMySQL.cxx */, 114B6EEB11FA7526004FB6AB /* LexNimrod.cxx */, 114B6EEC11FA7526004FB6AB /* LexNsis.cxx */, 114B6EED11FA7526004FB6AB /* LexOpal.cxx */, 11594BE7155B91DF0099E1FA /* LexOScript.cxx */, 114B6EEE11FA7526004FB6AB /* LexOthers.cxx */, 114B6EEF11FA7526004FB6AB /* LexPascal.cxx */, 114B6EF011FA7526004FB6AB /* LexPB.cxx */, 114B6EF111FA7526004FB6AB /* LexPerl.cxx */, 114B6EF211FA7526004FB6AB /* LexPLM.cxx */, 1114D6CA1602A951001DC345 /* LexPO.cxx */, 114B6EF311FA7526004FB6AB /* LexPOV.cxx */, 114B6EF411FA7526004FB6AB /* LexPowerPro.cxx */, 114B6EF511FA7526004FB6AB /* LexPowerShell.cxx */, 114B6EF611FA7526004FB6AB /* LexProgress.cxx */, 114B6EF711FA7526004FB6AB /* LexPS.cxx */, 114B6EF811FA7526004FB6AB /* LexPython.cxx */, 114B6EF911FA7526004FB6AB /* LexR.cxx */, 114B6EFA11FA7526004FB6AB /* LexRebol.cxx */, 114B6EFB11FA7526004FB6AB /* LexRuby.cxx */, 114B6EFC11FA7526004FB6AB /* LexScriptol.cxx */, 114B6EFD11FA7526004FB6AB /* LexSmalltalk.cxx */, 114B6EFE11FA7526004FB6AB /* LexSML.cxx */, 114B6EFF11FA7526004FB6AB /* LexSorcus.cxx */, 114B6F0011FA7526004FB6AB /* LexSpecman.cxx */, 114B6F0111FA7526004FB6AB /* LexSpice.cxx */, 114B6F0211FA7526004FB6AB /* LexSQL.cxx */, 114B6F0311FA7526004FB6AB /* LexTACL.cxx */, 114B6F0411FA7526004FB6AB /* LexTADS3.cxx */, 114B6F0511FA7526004FB6AB /* LexTAL.cxx */, 114B6F0611FA7526004FB6AB /* LexTCL.cxx */, 117ACE9014A29A1E002876F9 /* LexTCMD.cxx */, 114B6F0711FA7526004FB6AB /* LexTeX.cxx */, 114B6F0811FA7526004FB6AB /* LexTxt2tags.cxx */, 114B6F0911FA7526004FB6AB /* LexVB.cxx */, 114B6F0A11FA7526004FB6AB /* LexVerilog.cxx */, 114B6F0B11FA7526004FB6AB /* LexVHDL.cxx */, 11594BE8155B91DF0099E1FA /* LexVisualProlog.cxx */, 114B6F0C11FA7526004FB6AB /* LexYAML.cxx */, ); name = Lexers; sourceTree = "<group>"; }; 2744E47E0FC1675800E85C33 /* Header Files */ = { isa = PBXGroup; children = ( 114B6FD811FA7645004FB6AB /* Accessor.h */, 114B6FD911FA7645004FB6AB /* CharacterSet.h */, 114B6FDA11FA7645004FB6AB /* LexAccessor.h */, 114B6FDB11FA7645004FB6AB /* LexerBase.h */, 114B6FDC11FA7645004FB6AB /* LexerModule.h */, 114B6FDD11FA7645004FB6AB /* LexerNoExceptions.h */, 114B6FDE11FA7645004FB6AB /* LexerSimple.h */, 114B6FDF11FA7645004FB6AB /* OptionSet.h */, 114B6FE011FA7645004FB6AB /* PropSetSimple.h */, 114B6FE111FA7645004FB6AB /* StyleContext.h */, 114B6FE211FA7645004FB6AB /* WordList.h */, 114B6FA211FA7623004FB6AB /* AutoComplete.h */, 114B6FA311FA7623004FB6AB /* CallTip.h */, 114B6FA411FA7623004FB6AB /* Catalogue.h */, 114B6FA511FA7623004FB6AB /* CellBuffer.h */, 114B6FA611FA7623004FB6AB /* CharClassify.h */, 114B6FA711FA7623004FB6AB /* ContractionState.h */, 114B6FA811FA7623004FB6AB /* Decoration.h */, 114B6FA911FA7623004FB6AB /* Document.h */, 114B6FAA11FA7623004FB6AB /* Editor.h */, 114B6FAB11FA7623004FB6AB /* ExternalLexer.h */, 114B6FAC11FA7623004FB6AB /* FontQuality.h */, 114B6FAD11FA7623004FB6AB /* Indicator.h */, 114B6FAE11FA7623004FB6AB /* KeyMap.h */, 114B6FAF11FA7623004FB6AB /* LineMarker.h */, 114B6FB011FA7623004FB6AB /* Partitioning.h */, 114B6FB111FA7623004FB6AB /* PerLine.h */, 114B6FB211FA7623004FB6AB /* PositionCache.h */, 114B6FB311FA7623004FB6AB /* RESearch.h */, 114B6FB411FA7623004FB6AB /* RunStyles.h */, 114B6FB511FA7623004FB6AB /* ScintillaBase.h */, 114B6FB611FA7623004FB6AB /* Selection.h */, 114B6FB711FA7623004FB6AB /* SplitVector.h */, 114B6FB811FA7623004FB6AB /* Style.h */, 114B6FB911FA7623004FB6AB /* SVector.h */, 114B6FBA11FA7623004FB6AB /* UniConversion.h */, 114B6FBB11FA7623004FB6AB /* ViewStyle.h */, 114B6FBC11FA7623004FB6AB /* XPM.h */, 114B6FA011FA75DB004FB6AB /* ILexer.h */, ); name = "Header Files"; sourceTree = "<group>"; }; 2744E47F0FC1676400E85C33 /* Source Files */ = { isa = PBXGroup; children = ( 114B6F8E11FA75BE004FB6AB /* Accessor.cxx */, 114B6F8F11FA75BE004FB6AB /* CharacterSet.cxx */, 114B6F9011FA75BE004FB6AB /* LexerBase.cxx */, 114B6F9111FA75BE004FB6AB /* LexerModule.cxx */, 114B6F9211FA75BE004FB6AB /* LexerNoExceptions.cxx */, 114B6F9311FA75BE004FB6AB /* LexerSimple.cxx */, 114B6F9411FA75BE004FB6AB /* PropSetSimple.cxx */, 114B6F9511FA75BE004FB6AB /* StyleContext.cxx */, 114B6F9611FA75BE004FB6AB /* WordList.cxx */, 114B6F6011FA7597004FB6AB /* AutoComplete.cxx */, 114B6F6111FA7597004FB6AB /* CallTip.cxx */, 114B6F6211FA7597004FB6AB /* Catalogue.cxx */, 114B6F6311FA7597004FB6AB /* CellBuffer.cxx */, 114B6F6411FA7597004FB6AB /* CharClassify.cxx */, 114B6F6511FA7597004FB6AB /* ContractionState.cxx */, 114B6F6611FA7597004FB6AB /* Decoration.cxx */, 114B6F6711FA7597004FB6AB /* Document.cxx */, 114B6F6811FA7597004FB6AB /* Editor.cxx */, 114B6F6911FA7598004FB6AB /* ExternalLexer.cxx */, 114B6F6A11FA7598004FB6AB /* Indicator.cxx */, 114B6F6B11FA7598004FB6AB /* KeyMap.cxx */, 114B6F6C11FA7598004FB6AB /* LineMarker.cxx */, 114B6F6D11FA7598004FB6AB /* PerLine.cxx */, 114B6F6E11FA7598004FB6AB /* PositionCache.cxx */, 114B6F6F11FA7598004FB6AB /* RESearch.cxx */, 114B6F7011FA7598004FB6AB /* RunStyles.cxx */, 114B6F7111FA7598004FB6AB /* ScintillaBase.cxx */, 114B6F7211FA7598004FB6AB /* Selection.cxx */, 114B6F7311FA7598004FB6AB /* Style.cxx */, 114B6F7411FA7598004FB6AB /* UniConversion.cxx */, 114B6F7511FA7598004FB6AB /* ViewStyle.cxx */, 114B6F7611FA7598004FB6AB /* XPM.cxx */, ); name = "Source Files"; sourceTree = "<group>"; }; 2744E4970FC167E400E85C33 /* Header Files */ = { isa = PBXGroup; children = ( 2744E59D0FC168A100E85C33 /* InfoBar.h */, 2744E5AB0FC168B200E85C33 /* InfoBarCommunicator.h */, 2744E59E0FC168A100E85C33 /* PlatCocoa.h */, 2744E4850FC1678600E85C33 /* Platform.h */, 2744E59F0FC168A100E85C33 /* QuartzTextLayout.h */, 119FF1BE13C9D1820007CE42 /* QuartzTextStyle.h */, 2744E5A00FC168A100E85C33 /* QuartzTextStyleAttribute.h */, 2744E4870FC1678600E85C33 /* SciLexer.h */, 2744E4880FC1678600E85C33 /* Scintilla.h */, 2744E5A20FC168A100E85C33 /* ScintillaCocoa.h */, 2744E5A30FC168A100E85C33 /* ScintillaView.h */, ); name = "Header Files"; sourceTree = "<group>"; }; 2744E4980FC167ED00E85C33 /* Source Files */ = { isa = PBXGroup; children = ( 2744E5AD0FC168C500E85C33 /* InfoBar.mm */, 2744E5AE0FC168C500E85C33 /* PlatCocoa.mm */, 2744E5B00FC168C500E85C33 /* ScintillaCocoa.mm */, 2744E5B10FC168C500E85C33 /* ScintillaView.mm */, ); name = "Source Files"; sourceTree = "<group>"; }; 27FEF4500FC1B413005E115A /* res */ = { isa = PBXGroup; children = ( 27FEF4510FC1B413005E115A /* info_bar_bg.png */, 27FEF4520FC1B413005E115A /* mac_cursor_busy.png */, 27FEF4530FC1B413005E115A /* mac_cursor_flipped.png */, ); name = res; path = ../res; sourceTree = SOURCE_ROOT; }; 32C88DFF0371C24200C91783 /* Other Sources */ = { isa = PBXGroup; children = ( 32DBCF5E0370ADEE00C91783 /* Scintilla_Prefix.pch */, ); name = "Other Sources"; sourceTree = "<group>"; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 8DC2EF500486A6940098B216 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 2744E5A40FC168A100E85C33 /* InfoBar.h in Headers */, 2744E5AC0FC168B200E85C33 /* InfoBarCommunicator.h in Headers */, 2791F3C60FC19F71009DBCF9 /* PlatCocoa.h in Headers */, 2791F3E30FC1A3AE009DBCF9 /* QuartzTextLayout.h in Headers */, 2791F3E40FC1A3AE009DBCF9 /* QuartzTextStyleAttribute.h in Headers */, 2791F3E00FC1A390009DBCF9 /* ScintillaCocoa.h in Headers */, 2744E5AA0FC168A100E85C33 /* ScintillaView.h in Headers */, 2791F3C70FC19F71009DBCF9 /* Platform.h in Headers */, 2791F3C80FC19F71009DBCF9 /* SciLexer.h in Headers */, 2791F3C90FC19F71009DBCF9 /* Scintilla.h in Headers */, 114B6FA111FA75DB004FB6AB /* ILexer.h in Headers */, 114B6FBD11FA7623004FB6AB /* AutoComplete.h in Headers */, 114B6FBE11FA7623004FB6AB /* CallTip.h in Headers */, 114B6FBF11FA7623004FB6AB /* Catalogue.h in Headers */, 114B6FC011FA7623004FB6AB /* CellBuffer.h in Headers */, 114B6FC111FA7623004FB6AB /* CharClassify.h in Headers */, 114B6FC211FA7623004FB6AB /* ContractionState.h in Headers */, 114B6FC311FA7623004FB6AB /* Decoration.h in Headers */, 114B6FC411FA7623004FB6AB /* Document.h in Headers */, 114B6FC511FA7623004FB6AB /* Editor.h in Headers */, 114B6FC611FA7623004FB6AB /* ExternalLexer.h in Headers */, 114B6FC711FA7623004FB6AB /* FontQuality.h in Headers */, 114B6FC811FA7623004FB6AB /* Indicator.h in Headers */, 114B6FC911FA7623004FB6AB /* KeyMap.h in Headers */, 114B6FCA11FA7623004FB6AB /* LineMarker.h in Headers */, 114B6FCB11FA7623004FB6AB /* Partitioning.h in Headers */, 114B6FCC11FA7623004FB6AB /* PerLine.h in Headers */, 114B6FCD11FA7623004FB6AB /* PositionCache.h in Headers */, 114B6FCE11FA7623004FB6AB /* RESearch.h in Headers */, 114B6FCF11FA7623004FB6AB /* RunStyles.h in Headers */, 114B6FD011FA7623004FB6AB /* ScintillaBase.h in Headers */, 114B6FD111FA7623004FB6AB /* Selection.h in Headers */, 114B6FD211FA7623004FB6AB /* SplitVector.h in Headers */, 114B6FD311FA7623004FB6AB /* Style.h in Headers */, 114B6FD411FA7623004FB6AB /* SVector.h in Headers */, 114B6FD511FA7623004FB6AB /* UniConversion.h in Headers */, 114B6FD611FA7623004FB6AB /* ViewStyle.h in Headers */, 114B6FD711FA7623004FB6AB /* XPM.h in Headers */, 114B6FE311FA7645004FB6AB /* Accessor.h in Headers */, 114B6FE411FA7645004FB6AB /* CharacterSet.h in Headers */, 114B6FE511FA7645004FB6AB /* LexAccessor.h in Headers */, 114B6FE611FA7645004FB6AB /* LexerBase.h in Headers */, 114B6FE711FA7645004FB6AB /* LexerModule.h in Headers */, 114B6FE811FA7645004FB6AB /* LexerNoExceptions.h in Headers */, 114B6FE911FA7645004FB6AB /* LexerSimple.h in Headers */, 114B6FEA11FA7645004FB6AB /* OptionSet.h in Headers */, 114B6FEB11FA7645004FB6AB /* PropSetSimple.h in Headers */, 114B6FEC11FA7645004FB6AB /* StyleContext.h in Headers */, 114B6FED11FA7645004FB6AB /* WordList.h in Headers */, 119FF1BF13C9D1820007CE42 /* QuartzTextStyle.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 8DC2EF4F0486A6940098B216 /* Scintilla */ = { isa = PBXNativeTarget; buildConfigurationList = 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "Scintilla" */; buildPhases = ( 8DC2EF500486A6940098B216 /* Headers */, 8DC2EF520486A6940098B216 /* Resources */, 8DC2EF540486A6940098B216 /* Sources */, 8DC2EF560486A6940098B216 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = Scintilla; productInstallPath = "$(HOME)/Library/Frameworks"; productName = Scintilla; productReference = 8DC2EF5B0486A6940098B216 /* Scintilla.framework */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0460; }; buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "ScintillaFramework" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 0867D691FE84028FC02AAC07 /* Scintilla */; productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 8DC2EF4F0486A6940098B216 /* Scintilla */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 8DC2EF520486A6940098B216 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */, 27FEF4540FC1B413005E115A /* info_bar_bg.png in Resources */, 27FEF4550FC1B413005E115A /* mac_cursor_busy.png in Resources */, 27FEF4560FC1B413005E115A /* mac_cursor_flipped.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 8DC2EF540486A6940098B216 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 2744E5B20FC168C500E85C33 /* InfoBar.mm in Sources */, 2744E5B30FC168C500E85C33 /* PlatCocoa.mm in Sources */, 2744E5B50FC168C500E85C33 /* ScintillaCocoa.mm in Sources */, 2744E5B60FC168C500E85C33 /* ScintillaView.mm in Sources */, 114B6F0D11FA7526004FB6AB /* LexAbaqus.cxx in Sources */, 114B6F0E11FA7526004FB6AB /* LexAda.cxx in Sources */, 114B6F0F11FA7526004FB6AB /* LexAPDL.cxx in Sources */, 114B6F1011FA7526004FB6AB /* LexAsm.cxx in Sources */, 114B6F1111FA7526004FB6AB /* LexAsn1.cxx in Sources */, 114B6F1211FA7526004FB6AB /* LexASY.cxx in Sources */, 114B6F1311FA7526004FB6AB /* LexAU3.cxx in Sources */, 114B6F1411FA7526004FB6AB /* LexAVE.cxx in Sources */, 114B6F1511FA7526004FB6AB /* LexBaan.cxx in Sources */, 114B6F1611FA7526004FB6AB /* LexBash.cxx in Sources */, 114B6F1711FA7526004FB6AB /* LexBasic.cxx in Sources */, 114B6F1811FA7526004FB6AB /* LexBullant.cxx in Sources */, 114B6F1911FA7526004FB6AB /* LexCaml.cxx in Sources */, 114B6F1A11FA7526004FB6AB /* LexCLW.cxx in Sources */, 114B6F1B11FA7526004FB6AB /* LexCmake.cxx in Sources */, 114B6F1C11FA7526004FB6AB /* LexCOBOL.cxx in Sources */, 114B6F1D11FA7526004FB6AB /* LexConf.cxx in Sources */, 114B6F1E11FA7526004FB6AB /* LexCPP.cxx in Sources */, 114B6F1F11FA7526004FB6AB /* LexCrontab.cxx in Sources */, 114B6F2011FA7526004FB6AB /* LexCsound.cxx in Sources */, 114B6F2111FA7526004FB6AB /* LexCSS.cxx in Sources */, 114B6F2211FA7526004FB6AB /* LexD.cxx in Sources */, 114B6F2311FA7526004FB6AB /* LexEiffel.cxx in Sources */, 114B6F2411FA7526004FB6AB /* LexErlang.cxx in Sources */, 114B6F2511FA7526004FB6AB /* LexEScript.cxx in Sources */, 114B6F2611FA7526004FB6AB /* LexFlagship.cxx in Sources */, 114B6F2711FA7526004FB6AB /* LexForth.cxx in Sources */, 114B6F2811FA7526004FB6AB /* LexFortran.cxx in Sources */, 114B6F2911FA7526004FB6AB /* LexGAP.cxx in Sources */, 114B6F2A11FA7526004FB6AB /* LexGui4Cli.cxx in Sources */, 114B6F2B11FA7526004FB6AB /* LexHaskell.cxx in Sources */, 114B6F2C11FA7526004FB6AB /* LexHTML.cxx in Sources */, 114B6F2D11FA7526004FB6AB /* LexInno.cxx in Sources */, 114B6F2E11FA7526004FB6AB /* LexKix.cxx in Sources */, 114B6F2F11FA7526004FB6AB /* LexLisp.cxx in Sources */, 114B6F3011FA7526004FB6AB /* LexLout.cxx in Sources */, 114B6F3111FA7526004FB6AB /* LexLua.cxx in Sources */, 114B6F3211FA7526004FB6AB /* LexMagik.cxx in Sources */, 114B6F3311FA7526004FB6AB /* LexMarkdown.cxx in Sources */, 114B6F3411FA7526004FB6AB /* LexMatlab.cxx in Sources */, 114B6F3511FA7526004FB6AB /* LexMetapost.cxx in Sources */, 114B6F3611FA7526004FB6AB /* LexMMIXAL.cxx in Sources */, 114B6F3711FA7526004FB6AB /* LexMPT.cxx in Sources */, 114B6F3811FA7526004FB6AB /* LexMSSQL.cxx in Sources */, 114B6F3911FA7526004FB6AB /* LexMySQL.cxx in Sources */, 114B6F3A11FA7526004FB6AB /* LexNimrod.cxx in Sources */, 114B6F3B11FA7526004FB6AB /* LexNsis.cxx in Sources */, 114B6F3C11FA7526004FB6AB /* LexOpal.cxx in Sources */, 114B6F3D11FA7526004FB6AB /* LexOthers.cxx in Sources */, 114B6F3E11FA7526004FB6AB /* LexPascal.cxx in Sources */, 114B6F3F11FA7526004FB6AB /* LexPB.cxx in Sources */, 114B6F4011FA7526004FB6AB /* LexPerl.cxx in Sources */, 114B6F4111FA7526004FB6AB /* LexPLM.cxx in Sources */, 114B6F4211FA7526004FB6AB /* LexPOV.cxx in Sources */, 114B6F4311FA7526004FB6AB /* LexPowerPro.cxx in Sources */, 114B6F4411FA7526004FB6AB /* LexPowerShell.cxx in Sources */, 114B6F4511FA7526004FB6AB /* LexProgress.cxx in Sources */, 114B6F4611FA7526004FB6AB /* LexPS.cxx in Sources */, 114B6F4711FA7526004FB6AB /* LexPython.cxx in Sources */, 114B6F4811FA7526004FB6AB /* LexR.cxx in Sources */, 114B6F4911FA7526004FB6AB /* LexRebol.cxx in Sources */, 114B6F4A11FA7526004FB6AB /* LexRuby.cxx in Sources */, 114B6F4B11FA7526004FB6AB /* LexScriptol.cxx in Sources */, 114B6F4C11FA7526004FB6AB /* LexSmalltalk.cxx in Sources */, 114B6F4D11FA7526004FB6AB /* LexSML.cxx in Sources */, 114B6F4E11FA7526004FB6AB /* LexSorcus.cxx in Sources */, 114B6F4F11FA7526004FB6AB /* LexSpecman.cxx in Sources */, 114B6F5011FA7526004FB6AB /* LexSpice.cxx in Sources */, 114B6F5111FA7526004FB6AB /* LexSQL.cxx in Sources */, 114B6F5211FA7526004FB6AB /* LexTACL.cxx in Sources */, 114B6F5311FA7526004FB6AB /* LexTADS3.cxx in Sources */, 114B6F5411FA7526004FB6AB /* LexTAL.cxx in Sources */, 114B6F5511FA7526004FB6AB /* LexTCL.cxx in Sources */, 114B6F5611FA7526004FB6AB /* LexTeX.cxx in Sources */, 114B6F5711FA7526004FB6AB /* LexTxt2tags.cxx in Sources */, 114B6F5811FA7526004FB6AB /* LexVB.cxx in Sources */, 114B6F5911FA7526004FB6AB /* LexVerilog.cxx in Sources */, 114B6F5A11FA7526004FB6AB /* LexVHDL.cxx in Sources */, 114B6F5B11FA7526004FB6AB /* LexYAML.cxx in Sources */, 114B6F7711FA7598004FB6AB /* AutoComplete.cxx in Sources */, 114B6F7811FA7598004FB6AB /* CallTip.cxx in Sources */, 114B6F7911FA7598004FB6AB /* Catalogue.cxx in Sources */, 114B6F7A11FA7598004FB6AB /* CellBuffer.cxx in Sources */, 114B6F7B11FA7598004FB6AB /* CharClassify.cxx in Sources */, 114B6F7C11FA7598004FB6AB /* ContractionState.cxx in Sources */, 114B6F7D11FA7598004FB6AB /* Decoration.cxx in Sources */, 114B6F7E11FA7598004FB6AB /* Document.cxx in Sources */, 114B6F7F11FA7598004FB6AB /* Editor.cxx in Sources */, 114B6F8011FA7598004FB6AB /* ExternalLexer.cxx in Sources */, 114B6F8111FA7598004FB6AB /* Indicator.cxx in Sources */, 114B6F8211FA7598004FB6AB /* KeyMap.cxx in Sources */, 114B6F8311FA7598004FB6AB /* LineMarker.cxx in Sources */, 114B6F8411FA7598004FB6AB /* PerLine.cxx in Sources */, 114B6F8511FA7598004FB6AB /* PositionCache.cxx in Sources */, 114B6F8611FA7598004FB6AB /* RESearch.cxx in Sources */, 114B6F8711FA7598004FB6AB /* RunStyles.cxx in Sources */, 114B6F8811FA7598004FB6AB /* ScintillaBase.cxx in Sources */, 114B6F8911FA7598004FB6AB /* Selection.cxx in Sources */, 114B6F8A11FA7598004FB6AB /* Style.cxx in Sources */, 114B6F8B11FA7598004FB6AB /* UniConversion.cxx in Sources */, 114B6F8C11FA7598004FB6AB /* ViewStyle.cxx in Sources */, 114B6F8D11FA7598004FB6AB /* XPM.cxx in Sources */, 114B6F9711FA75BE004FB6AB /* Accessor.cxx in Sources */, 114B6F9811FA75BE004FB6AB /* CharacterSet.cxx in Sources */, 114B6F9911FA75BE004FB6AB /* LexerBase.cxx in Sources */, 114B6F9A11FA75BE004FB6AB /* LexerModule.cxx in Sources */, 114B6F9B11FA75BE004FB6AB /* LexerNoExceptions.cxx in Sources */, 114B6F9C11FA75BE004FB6AB /* LexerSimple.cxx in Sources */, 114B6F9D11FA75BE004FB6AB /* PropSetSimple.cxx in Sources */, 114B6F9E11FA75BE004FB6AB /* StyleContext.cxx in Sources */, 114B6F9F11FA75BE004FB6AB /* WordList.cxx in Sources */, 11F35FDB12AEFAF100F0236D /* LexA68k.cxx in Sources */, 11BB124D12FF9C1300F6BCF7 /* LexModula.cxx in Sources */, 11A0A8A1148602DF0018D143 /* LexCoffeeScript.cxx in Sources */, 117ACE9114A29A1E002876F9 /* LexTCMD.cxx in Sources */, 11126B8214CD3A6200803C49 /* LexAVS.cxx in Sources */, 11BEB6A214EF189600BDE92A /* LexECL.cxx in Sources */, 11594BE9155B91DF0099E1FA /* LexOScript.cxx in Sources */, 11594BEA155B91DF0099E1FA /* LexVisualProlog.cxx in Sources */, 1114D6CB1602A951001DC345 /* LexPO.cxx in Sources */, 1102C31C169FB49300DC16AB /* LexLaTeX.cxx in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 089C1666FE841158C02AAC07 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( 089C1667FE841158C02AAC07 /* English */, ); name = InfoPlist.strings; sourceTree = "<group>"; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 1DEB91AE08733DA50010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; COPY_PHASE_STRIP = NO; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = ".bzr *.nib *.lproj *.framework *.gch (*) CVS .svn *.xcodeproj *.xcode *.pbproj *.pbxproj"; FRAMEWORK_VERSION = A; GCC_DYNAMIC_NO_PIC = NO; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = Scintilla_Prefix.pch; GCC_PREPROCESSOR_DEFINITIONS = ( SCI_NAMESPACE, SCI_LEXER, ); GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_UNINITIALIZED_AUTOS = NO; GCC_WARN_UNKNOWN_PRAGMAS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_LABEL = YES; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "@executable_path/../Frameworks"; PRODUCT_NAME = Scintilla; SDKROOT = macosx10.7; WRAPPER_EXTENSION = framework; }; name = Debug; }; 1DEB91AF08733DA50010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_VERSION = A; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = Scintilla_Prefix.pch; GCC_PREPROCESSOR_DEFINITIONS = ( SCI_NAMESPACE, SCI_LEXER, ); GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_UNINITIALIZED_AUTOS = NO; GCC_WARN_UNKNOWN_PRAGMAS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_LABEL = YES; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "@executable_path/../Frameworks"; PRODUCT_NAME = Scintilla; SDKROOT = macosx10.7; WRAPPER_EXTENSION = framework; }; name = Release; }; 1DEB91B208733DA50010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( ../../include, ../../src, ../../lexlib, ); ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx10.7; }; name = Debug; }; 1DEB91B308733DA50010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( ../../include, ../../src, ../../lexlib, ); SDKROOT = macosx10.7; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "Scintilla" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB91AE08733DA50010E9CD /* Debug */, 1DEB91AF08733DA50010E9CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "ScintillaFramework" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB91B208733DA50010E9CD /* Debug */, 1DEB91B308733DA50010E9CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 0867D690FE84028FC02AAC07 /* Project object */; } |
Added cocoa/ScintillaFramework/Scintilla_Prefix.pch.
> > > > > > > |
1 2 3 4 5 6 7 |
// // Prefix header for all source files of the 'Scintilla' target in the 'Scintilla' project. // #ifdef __OBJC__ #import <Cocoa/Cocoa.h> #endif |
Added cocoa/ScintillaTest/AppController.h.
> > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
/** * AppController.h * SciTest * * Created by Mike Lischke on 01.04.09. * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). */ #import <Cocoa/Cocoa.h> #import "ScintillaView.h" #import "InfoBar.h" @interface AppController : NSObject { IBOutlet NSBox *mEditHost; ScintillaView* mEditor; } - (void) awakeFromNib; - (void) setupEditor; - (IBAction) searchText: (id) sender; @end |
Added cocoa/ScintillaTest/AppController.mm.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
/** * AppController.m * ScintillaTest * * Created by Mike Lischke on 01.04.09. * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). */ #import "AppController.h" const char major_keywords[] = "accessible add all alter analyze and as asc asensitive " "before between bigint binary blob both by " "call cascade case change char character check collate column condition connection constraint " "continue convert create cross current_date current_time current_timestamp current_user cursor " "database databases day_hour day_microsecond day_minute day_second dec decimal declare default " "delayed delete desc describe deterministic distinct distinctrow div double drop dual " "each else elseif enclosed escaped exists exit explain " "false fetch float float4 float8 for force foreign from fulltext " "goto grant group " "having high_priority hour_microsecond hour_minute hour_second " "if ignore in index infile inner inout insensitive insert int int1 int2 int3 int4 int8 integer " "interval into is iterate " "join " "key keys kill " "label leading leave left like limit linear lines load localtime localtimestamp lock long " "longblob longtext loop low_priority " "master_ssl_verify_server_cert match mediumblob mediumint mediumtext middleint minute_microsecond " "minute_second mod modifies " "natural not no_write_to_binlog null numeric " "on optimize option optionally or order out outer outfile " "precision primary procedure purge " "range read reads read_only read_write real references regexp release rename repeat replace " "require restrict return revoke right rlike " "schema schemas second_microsecond select sensitive separator set show smallint spatial specific " "sql sqlexception sqlstate sqlwarning sql_big_result sql_calc_found_rows sql_small_result ssl " "starting straight_join " "table terminated then tinyblob tinyint tinytext to trailing trigger true " "undo union unique unlock unsigned update upgrade usage use using utc_date utc_time utc_timestamp " "values varbinary varchar varcharacter varying " "when where while with write " "xor " "year_month " "zerofill"; const char procedure_keywords[] = // Not reserved words but intrinsic part of procedure definitions. "begin comment end"; const char client_keywords[] = // Definition of keywords only used by clients, not the server itself. "delimiter"; const char user_keywords[] = // Definition of own keywords, not used by MySQL. "edit"; //-------------------------------------------------------------------------------------------------- @implementation AppController - (void) awakeFromNib { // Manually set up the scintilla editor. Create an instance and dock it to our edit host. // Leave some free space around the new view to avoid overlapping with the box borders. NSRect newFrame = mEditHost.frame; newFrame.size.width -= 2 * newFrame.origin.x; newFrame.size.height -= 3 * newFrame.origin.y; mEditor = [[[ScintillaView alloc] initWithFrame: newFrame] autorelease]; [mEditHost.contentView addSubview: mEditor]; [mEditor setAutoresizesSubviews: YES]; [mEditor setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; // Let's load some text for the editor, as initial content. NSError* error = nil; NSString* path = [[NSBundle mainBundle] pathForResource: @"TestData" ofType: @"sql" inDirectory: nil]; NSString* sql = [NSString stringWithContentsOfFile: path encoding: NSUTF8StringEncoding error: &error]; if (error && [[error domain] isEqual: NSCocoaErrorDomain]) NSLog(@"%@", error); [mEditor setString: sql]; [self setupEditor]; } //-------------------------------------------------------------------------------------------------- /** * Initialize scintilla editor (styles, colors, markers, folding etc.]. */ - (void) setupEditor { // Lexer type is MySQL. [mEditor setGeneralProperty: SCI_SETLEXER parameter: SCLEX_MYSQL value: 0]; // alternatively: [mEditor setEditorProperty: SCI_SETLEXERLANGUAGE parameter: nil value: (sptr_t) "mysql"]; // Number of styles we use with this lexer. [mEditor setGeneralProperty: SCI_SETSTYLEBITS value: [mEditor getGeneralProperty: SCI_GETSTYLEBITSNEEDED]]; // Keywords to highlight. Indices are: // 0 - Major keywords (reserved keywords) // 1 - Normal keywords (everything not reserved but integral part of the language) // 2 - Database objects // 3 - Function keywords // 4 - System variable keywords // 5 - Procedure keywords (keywords used in procedures like "begin" and "end") // 6..8 - User keywords 1..3 [mEditor setReferenceProperty: SCI_SETKEYWORDS parameter: 0 value: major_keywords]; [mEditor setReferenceProperty: SCI_SETKEYWORDS parameter: 5 value: procedure_keywords]; [mEditor setReferenceProperty: SCI_SETKEYWORDS parameter: 6 value: client_keywords]; [mEditor setReferenceProperty: SCI_SETKEYWORDS parameter: 7 value: user_keywords]; // Colors and styles for various syntactic elements. First the default style. [mEditor setStringProperty: SCI_STYLESETFONT parameter: STYLE_DEFAULT value: @"Helvetica"]; // [mEditor setStringProperty: SCI_STYLESETFONT parameter: STYLE_DEFAULT value: @"Monospac821 BT"]; // Very pleasing programmer's font. [mEditor setGeneralProperty: SCI_STYLESETSIZE parameter: STYLE_DEFAULT value: 14]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: STYLE_DEFAULT value: [NSColor blackColor]]; [mEditor setGeneralProperty: SCI_STYLECLEARALL parameter: 0 value: 0]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_DEFAULT value: [NSColor blackColor]]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_COMMENT fromHTML: @"#097BF7"]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_COMMENTLINE fromHTML: @"#097BF7"]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_HIDDENCOMMAND fromHTML: @"#097BF7"]; [mEditor setColorProperty: SCI_STYLESETBACK parameter: SCE_MYSQL_HIDDENCOMMAND fromHTML: @"#F0F0F0"]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_VARIABLE fromHTML: @"378EA5"]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_SYSTEMVARIABLE fromHTML: @"378EA5"]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_KNOWNSYSTEMVARIABLE fromHTML: @"#3A37A5"]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_NUMBER fromHTML: @"#7F7F00"]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_SQSTRING fromHTML: @"#FFAA3E"]; // Note: if we were using ANSI quotes we would set the DQSTRING to the same color as the // the back tick string. [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_DQSTRING fromHTML: @"#274A6D"]; // Keyword highlighting. [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_MAJORKEYWORD fromHTML: @"#007F00"]; [mEditor setGeneralProperty: SCI_STYLESETBOLD parameter: SCE_MYSQL_MAJORKEYWORD value: 1]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_KEYWORD fromHTML: @"#007F00"]; [mEditor setGeneralProperty: SCI_STYLESETBOLD parameter: SCE_MYSQL_KEYWORD value: 1]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_PROCEDUREKEYWORD fromHTML: @"#56007F"]; [mEditor setGeneralProperty: SCI_STYLESETBOLD parameter: SCE_MYSQL_PROCEDUREKEYWORD value: 1]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_USER1 fromHTML: @"#808080"]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_USER2 fromHTML: @"#808080"]; [mEditor setColorProperty: SCI_STYLESETBACK parameter: SCE_MYSQL_USER2 fromHTML: @"#F0E0E0"]; // The following 3 styles have no impact as we did not set a keyword list for any of them. [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_DATABASEOBJECT value: [NSColor redColor]]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_FUNCTION value: [NSColor redColor]]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_IDENTIFIER value: [NSColor blackColor]]; [mEditor setColorProperty: SCI_STYLESETFORE parameter: SCE_MYSQL_QUOTEDIDENTIFIER fromHTML: @"#274A6D"]; [mEditor setGeneralProperty: SCI_STYLESETBOLD parameter: SCE_SQL_OPERATOR value: 1]; // Line number style. [mEditor setColorProperty: SCI_STYLESETFORE parameter: STYLE_LINENUMBER fromHTML: @"#F0F0F0"]; [mEditor setColorProperty: SCI_STYLESETBACK parameter: STYLE_LINENUMBER fromHTML: @"#808080"]; [mEditor setGeneralProperty: SCI_SETMARGINTYPEN parameter: 0 value: SC_MARGIN_NUMBER]; [mEditor setGeneralProperty: SCI_SETMARGINWIDTHN parameter: 0 value: 35]; // Markers. [mEditor setGeneralProperty: SCI_SETMARGINWIDTHN parameter: 1 value: 16]; // Some special lexer properties. [mEditor setLexerProperty: @"fold" value: @"1"]; [mEditor setLexerProperty: @"fold.compact" value: @"0"]; [mEditor setLexerProperty: @"fold.comment" value: @"1"]; [mEditor setLexerProperty: @"fold.preprocessor" value: @"1"]; // Folder setup. [mEditor setGeneralProperty: SCI_SETMARGINWIDTHN parameter: 2 value: 16]; [mEditor setGeneralProperty: SCI_SETMARGINMASKN parameter: 2 value: SC_MASK_FOLDERS]; [mEditor setGeneralProperty: SCI_SETMARGINSENSITIVEN parameter: 2 value: 1]; [mEditor setGeneralProperty: SCI_MARKERDEFINE parameter: SC_MARKNUM_FOLDEROPEN value: SC_MARK_BOXMINUS]; [mEditor setGeneralProperty: SCI_MARKERDEFINE parameter: SC_MARKNUM_FOLDER value: SC_MARK_BOXPLUS]; [mEditor setGeneralProperty: SCI_MARKERDEFINE parameter: SC_MARKNUM_FOLDERSUB value: SC_MARK_VLINE]; [mEditor setGeneralProperty: SCI_MARKERDEFINE parameter: SC_MARKNUM_FOLDERTAIL value: SC_MARK_LCORNER]; [mEditor setGeneralProperty: SCI_MARKERDEFINE parameter: SC_MARKNUM_FOLDEREND value: SC_MARK_BOXPLUSCONNECTED]; [mEditor setGeneralProperty: SCI_MARKERDEFINE parameter: SC_MARKNUM_FOLDEROPENMID value: SC_MARK_BOXMINUSCONNECTED]; [mEditor setGeneralProperty : SCI_MARKERDEFINE parameter: SC_MARKNUM_FOLDERMIDTAIL value: SC_MARK_TCORNER]; for (int n= 25; n < 32; ++n) // Markers 25..31 are reserved for folding. { [mEditor setColorProperty: SCI_MARKERSETFORE parameter: n value: [NSColor whiteColor]]; [mEditor setColorProperty: SCI_MARKERSETBACK parameter: n value: [NSColor blackColor]]; } // Init markers & indicators for highlighting of syntax errors. [mEditor setColorProperty: SCI_INDICSETFORE parameter: 0 value: [NSColor redColor]]; [mEditor setGeneralProperty: SCI_INDICSETUNDER parameter: 0 value: 1]; [mEditor setGeneralProperty: SCI_INDICSETSTYLE parameter: 0 value: INDIC_SQUIGGLE]; [mEditor setColorProperty: SCI_MARKERSETBACK parameter: 0 fromHTML: @"#B1151C"]; [mEditor setColorProperty: SCI_SETSELBACK parameter: 1 value: [NSColor selectedTextBackgroundColor]]; // Uncomment if you wanna see auto wrapping in action. //[mEditor setGeneralProperty: SCI_SETWRAPMODE parameter: SC_WRAP_WORD value: 0]; InfoBar* infoBar = [[[InfoBar alloc] initWithFrame: NSMakeRect(0, 0, 400, 0)] autorelease]; [infoBar setDisplay: IBShowAll]; [mEditor setInfoBar: infoBar top: NO]; [mEditor setStatusText: @"Operation complete"]; } //-------------------------------------------------------------------------------------------------- /* XPM */ static const char * box_xpm[] = { "12 12 2 1", " c None", ". c #800000", " .........", " . . ..", " . . . .", "......... .", ". . . .", ". . . ..", ". . .. .", "......... .", ". . . .", ". . . . ", ". . .. ", "......... "}; - (void) showAutocompletion { const char *words = "Babylon-5?1 Battlestar-Galactica Millenium-Falcon?2 Moya?2 Serenity Voyager"; [mEditor setGeneralProperty: SCI_AUTOCSETIGNORECASE parameter: 1 value:0]; [mEditor setGeneralProperty: SCI_REGISTERIMAGE parameter: 1 value:(sptr_t)box_xpm]; const int imSize = 12; [mEditor setGeneralProperty: SCI_RGBAIMAGESETWIDTH parameter: imSize value:0]; [mEditor setGeneralProperty: SCI_RGBAIMAGESETHEIGHT parameter: imSize value:0]; char image[imSize * imSize * 4]; for (size_t y = 0; y < imSize; y++) { for (size_t x = 0; x < imSize; x++) { char *p = image + (y * imSize + x) * 4; p[0] = 0xFF; p[1] = 0xA0; p[2] = 0; p[3] = x * 23; } } [mEditor setGeneralProperty: SCI_REGISTERRGBAIMAGE parameter: 2 value:(sptr_t)image]; [mEditor setGeneralProperty: SCI_AUTOCSHOW parameter: 0 value:(sptr_t)words]; } - (IBAction) searchText: (id) sender { NSSearchField* searchField = (NSSearchField*) sender; [mEditor findAndHighlightText: [searchField stringValue] matchCase: NO wholeWord: NO scrollTo: YES wrap: YES]; long matchStart = [mEditor getGeneralProperty: SCI_GETSELECTIONSTART parameter: 0]; long matchEnd = [mEditor getGeneralProperty: SCI_GETSELECTIONEND parameter: 0]; [mEditor setGeneralProperty: SCI_FINDINDICATORFLASH parameter: matchStart value:matchEnd]; if ([[searchField stringValue] isEqualToString: @"XX"]) [self showAutocompletion]; } @end //-------------------------------------------------------------------------------------------------- |
Added cocoa/ScintillaTest/English.lproj/InfoPlist.strings.
> > |
1 2 |
/* Localized versions of Info.plist keys */
|
Added cocoa/ScintillaTest/English.lproj/MainMenu.xib.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 |
<?xml version="1.0" encoding="UTF-8"?> <archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10"> <data> <int key="IBDocument.SystemTarget">1050</int> <string key="IBDocument.SystemVersion">10D573</string> <string key="IBDocument.InterfaceBuilderVersion">762</string> <string key="IBDocument.AppKitVersion">1038.29</string> <string key="IBDocument.HIToolboxVersion">460.00</string> <object class="NSMutableDictionary" key="IBDocument.PluginVersions"> <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string> <string key="NS.object.0">762</string> </object> <object class="NSMutableArray" key="IBDocument.EditedObjectIDs"> <bool key="EncodedWithXMLCoder">YES</bool> <integer value="372"/> </object> <object class="NSArray" key="IBDocument.PluginDependencies"> <bool key="EncodedWithXMLCoder">YES</bool> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> </object> <object class="NSMutableDictionary" key="IBDocument.Metadata"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSArray" key="dict.sortedKeys" id="0"> <bool key="EncodedWithXMLCoder">YES</bool> </object> <object class="NSMutableArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> </object> </object> <object class="NSMutableArray" key="IBDocument.RootObjects" id="1048"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSCustomObject" id="1021"> <string key="NSClassName">NSApplication</string> </object> <object class="NSCustomObject" id="1014"> <string key="NSClassName">FirstResponder</string> </object> <object class="NSCustomObject" id="1050"> <string key="NSClassName">NSApplication</string> </object> <object class="NSMenu" id="649796088"> <string key="NSTitle">AMainMenu</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="694149608"> <reference key="NSMenu" ref="649796088"/> <string key="NSTitle">NewApplication</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <object class="NSCustomResource" key="NSOnImage" id="35465992"> <string key="NSClassName">NSImage</string> <string key="NSResourceName">NSMenuCheckmark</string> </object> <object class="NSCustomResource" key="NSMixedImage" id="502551668"> <string key="NSClassName">NSImage</string> <string key="NSResourceName">NSMenuMixedState</string> </object> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="110575045"> <string key="NSTitle">NewApplication</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="238522557"> <reference key="NSMenu" ref="110575045"/> <string key="NSTitle">About NewApplication</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="304266470"> <reference key="NSMenu" ref="110575045"/> <bool key="NSIsDisabled">YES</bool> <bool key="NSIsSeparator">YES</bool> <string key="NSTitle"/> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="609285721"> <reference key="NSMenu" ref="110575045"/> <string key="NSTitle">Preferences…</string> <string key="NSKeyEquiv">,</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="481834944"> <reference key="NSMenu" ref="110575045"/> <bool key="NSIsDisabled">YES</bool> <bool key="NSIsSeparator">YES</bool> <string key="NSTitle"/> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="1046388886"> <reference key="NSMenu" ref="110575045"/> <string key="NSTitle">Services</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="752062318"> <string key="NSTitle">Services</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> </object> <string key="NSName">_NSServicesMenu</string> </object> </object> <object class="NSMenuItem" id="646227648"> <reference key="NSMenu" ref="110575045"/> <bool key="NSIsDisabled">YES</bool> <bool key="NSIsSeparator">YES</bool> <string key="NSTitle"/> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="755159360"> <reference key="NSMenu" ref="110575045"/> <string key="NSTitle">Hide NewApplication</string> <string key="NSKeyEquiv">h</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="342932134"> <reference key="NSMenu" ref="110575045"/> <string key="NSTitle">Hide Others</string> <string key="NSKeyEquiv">h</string> <int key="NSKeyEquivModMask">1572864</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="908899353"> <reference key="NSMenu" ref="110575045"/> <string key="NSTitle">Show All</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="1056857174"> <reference key="NSMenu" ref="110575045"/> <bool key="NSIsDisabled">YES</bool> <bool key="NSIsSeparator">YES</bool> <string key="NSTitle"/> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="632727374"> <reference key="NSMenu" ref="110575045"/> <string key="NSTitle">Quit NewApplication</string> <string key="NSKeyEquiv">q</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> </object> <string key="NSName">_NSAppleMenu</string> </object> </object> <object class="NSMenuItem" id="379814623"> <reference key="NSMenu" ref="649796088"/> <string key="NSTitle">File</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="720053764"> <string key="NSTitle">File</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="705341025"> <reference key="NSMenu" ref="720053764"/> <string key="NSTitle">New</string> <string key="NSKeyEquiv">n</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="722745758"> <reference key="NSMenu" ref="720053764"/> <string key="NSTitle">Open…</string> <string key="NSKeyEquiv">o</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="1025936716"> <reference key="NSMenu" ref="720053764"/> <string key="NSTitle">Open Recent</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="1065607017"> <string key="NSTitle">Open Recent</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="759406840"> <reference key="NSMenu" ref="1065607017"/> <string key="NSTitle">Clear Menu</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> </object> <string key="NSName">_NSRecentDocumentsMenu</string> </object> </object> <object class="NSMenuItem" id="425164168"> <reference key="NSMenu" ref="720053764"/> <bool key="NSIsDisabled">YES</bool> <bool key="NSIsSeparator">YES</bool> <string key="NSTitle"/> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="776162233"> <reference key="NSMenu" ref="720053764"/> <string key="NSTitle">Close</string> <string key="NSKeyEquiv">w</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="1023925487"> <reference key="NSMenu" ref="720053764"/> <string key="NSTitle">Save</string> <string key="NSKeyEquiv">s</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="117038363"> <reference key="NSMenu" ref="720053764"/> <string key="NSTitle">Save As…</string> <string key="NSKeyEquiv">S</string> <int key="NSKeyEquivModMask">1179648</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="579971712"> <reference key="NSMenu" ref="720053764"/> <string key="NSTitle">Revert to Saved</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="1010469920"> <reference key="NSMenu" ref="720053764"/> <bool key="NSIsDisabled">YES</bool> <bool key="NSIsSeparator">YES</bool> <string key="NSTitle"/> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="294629803"> <reference key="NSMenu" ref="720053764"/> <string key="NSTitle">Page Setup...</string> <string key="NSKeyEquiv">P</string> <int key="NSKeyEquivModMask">1179648</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSToolTip"/> </object> <object class="NSMenuItem" id="49223823"> <reference key="NSMenu" ref="720053764"/> <string key="NSTitle">Print…</string> <string key="NSKeyEquiv">p</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> </object> </object> </object> <object class="NSMenuItem" id="952259628"> <reference key="NSMenu" ref="649796088"/> <string key="NSTitle">Edit</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="789758025"> <string key="NSTitle">Edit</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="1058277027"> <reference key="NSMenu" ref="789758025"/> <string key="NSTitle">Undo</string> <string key="NSKeyEquiv">z</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="790794224"> <reference key="NSMenu" ref="789758025"/> <string key="NSTitle">Redo</string> <string key="NSKeyEquiv">Z</string> <int key="NSKeyEquivModMask">1179648</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="1040322652"> <reference key="NSMenu" ref="789758025"/> <bool key="NSIsDisabled">YES</bool> <bool key="NSIsSeparator">YES</bool> <string key="NSTitle"/> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="296257095"> <reference key="NSMenu" ref="789758025"/> <string key="NSTitle">Cut</string> <string key="NSKeyEquiv">x</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="860595796"> <reference key="NSMenu" ref="789758025"/> <string key="NSTitle">Copy</string> <string key="NSKeyEquiv">c</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="29853731"> <reference key="NSMenu" ref="789758025"/> <string key="NSTitle">Paste</string> <string key="NSKeyEquiv">v</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="437104165"> <reference key="NSMenu" ref="789758025"/> <string key="NSTitle">Delete</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="583158037"> <reference key="NSMenu" ref="789758025"/> <string key="NSTitle">Select All</string> <string key="NSKeyEquiv">a</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="212016141"> <reference key="NSMenu" ref="789758025"/> <bool key="NSIsDisabled">YES</bool> <bool key="NSIsSeparator">YES</bool> <string key="NSTitle"/> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="892235320"> <reference key="NSMenu" ref="789758025"/> <string key="NSTitle">Find</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="963351320"> <string key="NSTitle">Find</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="447796847"> <reference key="NSMenu" ref="963351320"/> <string key="NSTitle">Find…</string> <string key="NSKeyEquiv">f</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <int key="NSTag">1</int> </object> <object class="NSMenuItem" id="326711663"> <reference key="NSMenu" ref="963351320"/> <string key="NSTitle">Find Next</string> <string key="NSKeyEquiv">g</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <int key="NSTag">2</int> </object> <object class="NSMenuItem" id="270902937"> <reference key="NSMenu" ref="963351320"/> <string key="NSTitle">Find Previous</string> <string key="NSKeyEquiv">G</string> <int key="NSKeyEquivModMask">1179648</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <int key="NSTag">3</int> </object> <object class="NSMenuItem" id="159080638"> <reference key="NSMenu" ref="963351320"/> <string key="NSTitle">Use Selection for Find</string> <string key="NSKeyEquiv">e</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <int key="NSTag">7</int> </object> <object class="NSMenuItem" id="88285865"> <reference key="NSMenu" ref="963351320"/> <string key="NSTitle">Jump to Selection</string> <string key="NSKeyEquiv">j</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> </object> </object> </object> <object class="NSMenuItem" id="972420730"> <reference key="NSMenu" ref="789758025"/> <string key="NSTitle">Spelling and Grammar</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="769623530"> <string key="NSTitle">Spelling and Grammar</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="679648819"> <reference key="NSMenu" ref="769623530"/> <string key="NSTitle">Show Spelling…</string> <string key="NSKeyEquiv">:</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="96193923"> <reference key="NSMenu" ref="769623530"/> <string key="NSTitle">Check Spelling</string> <string key="NSKeyEquiv">;</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="948374510"> <reference key="NSMenu" ref="769623530"/> <string key="NSTitle">Check Spelling While Typing</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="967646866"> <reference key="NSMenu" ref="769623530"/> <string key="NSTitle">Check Grammar With Spelling</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> </object> </object> </object> <object class="NSMenuItem" id="507821607"> <reference key="NSMenu" ref="789758025"/> <string key="NSTitle">Substitutions</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="698887838"> <string key="NSTitle">Substitutions</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="605118523"> <reference key="NSMenu" ref="698887838"/> <string key="NSTitle">Smart Copy/Paste</string> <string key="NSKeyEquiv">f</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <int key="NSTag">1</int> </object> <object class="NSMenuItem" id="197661976"> <reference key="NSMenu" ref="698887838"/> <string key="NSTitle">Smart Quotes</string> <string key="NSKeyEquiv">g</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <int key="NSTag">2</int> </object> <object class="NSMenuItem" id="708854459"> <reference key="NSMenu" ref="698887838"/> <string key="NSTitle">Smart Links</string> <string key="NSKeyEquiv">G</string> <int key="NSKeyEquivModMask">1179648</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <int key="NSTag">3</int> </object> </object> </object> </object> <object class="NSMenuItem" id="676164635"> <reference key="NSMenu" ref="789758025"/> <string key="NSTitle">Speech</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="785027613"> <string key="NSTitle">Speech</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="731782645"> <reference key="NSMenu" ref="785027613"/> <string key="NSTitle">Start Speaking</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="680220178"> <reference key="NSMenu" ref="785027613"/> <string key="NSTitle">Stop Speaking</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> </object> </object> </object> </object> </object> </object> <object class="NSMenuItem" id="302598603"> <reference key="NSMenu" ref="649796088"/> <string key="NSTitle">Format</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="941447902"> <string key="NSTitle">Format</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="792887677"> <reference key="NSMenu" ref="941447902"/> <string key="NSTitle">Font</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="786677654"> <string key="NSTitle">Font</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="159677712"> <reference key="NSMenu" ref="786677654"/> <string key="NSTitle">Show Fonts</string> <string key="NSKeyEquiv">t</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="305399458"> <reference key="NSMenu" ref="786677654"/> <string key="NSTitle">Bold</string> <string key="NSKeyEquiv">b</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <int key="NSTag">2</int> </object> <object class="NSMenuItem" id="814362025"> <reference key="NSMenu" ref="786677654"/> <string key="NSTitle">Italic</string> <string key="NSKeyEquiv">i</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <int key="NSTag">1</int> </object> <object class="NSMenuItem" id="330926929"> <reference key="NSMenu" ref="786677654"/> <string key="NSTitle">Underline</string> <string key="NSKeyEquiv">u</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="533507878"> <reference key="NSMenu" ref="786677654"/> <bool key="NSIsDisabled">YES</bool> <bool key="NSIsSeparator">YES</bool> <string key="NSTitle"/> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="158063935"> <reference key="NSMenu" ref="786677654"/> <string key="NSTitle">Bigger</string> <string key="NSKeyEquiv">+</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <int key="NSTag">3</int> </object> <object class="NSMenuItem" id="885547335"> <reference key="NSMenu" ref="786677654"/> <string key="NSTitle">Smaller</string> <string key="NSKeyEquiv">-</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <int key="NSTag">4</int> </object> <object class="NSMenuItem" id="901062459"> <reference key="NSMenu" ref="786677654"/> <bool key="NSIsDisabled">YES</bool> <bool key="NSIsSeparator">YES</bool> <string key="NSTitle"/> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="767671776"> <reference key="NSMenu" ref="786677654"/> <string key="NSTitle">Kern</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="175441468"> <string key="NSTitle">Kern</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="252969304"> <reference key="NSMenu" ref="175441468"/> <string key="NSTitle">Use Default</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="766922938"> <reference key="NSMenu" ref="175441468"/> <string key="NSTitle">Use None</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="677519740"> <reference key="NSMenu" ref="175441468"/> <string key="NSTitle">Tighten</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="238351151"> <reference key="NSMenu" ref="175441468"/> <string key="NSTitle">Loosen</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> </object> </object> </object> <object class="NSMenuItem" id="691570813"> <reference key="NSMenu" ref="786677654"/> <string key="NSTitle">Ligature</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="1058217995"> <string key="NSTitle">Ligature</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="706297211"> <reference key="NSMenu" ref="1058217995"/> <string key="NSTitle">Use Default</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="568384683"> <reference key="NSMenu" ref="1058217995"/> <string key="NSTitle">Use None</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="663508465"> <reference key="NSMenu" ref="1058217995"/> <string key="NSTitle">Use All</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> </object> </object> </object> <object class="NSMenuItem" id="769124883"> <reference key="NSMenu" ref="786677654"/> <string key="NSTitle">Baseline</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="18263474"> <string key="NSTitle">Baseline</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="257962622"> <reference key="NSMenu" ref="18263474"/> <string key="NSTitle">Use Default</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="644725453"> <reference key="NSMenu" ref="18263474"/> <string key="NSTitle">Superscript</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="1037576581"> <reference key="NSMenu" ref="18263474"/> <string key="NSTitle">Subscript</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="941806246"> <reference key="NSMenu" ref="18263474"/> <string key="NSTitle">Raise</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="1045724900"> <reference key="NSMenu" ref="18263474"/> <string key="NSTitle">Lower</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> </object> </object> </object> <object class="NSMenuItem" id="739652853"> <reference key="NSMenu" ref="786677654"/> <bool key="NSIsDisabled">YES</bool> <bool key="NSIsSeparator">YES</bool> <string key="NSTitle"/> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="1012600125"> <reference key="NSMenu" ref="786677654"/> <string key="NSTitle">Show Colors</string> <string key="NSKeyEquiv">C</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="214559597"> <reference key="NSMenu" ref="786677654"/> <bool key="NSIsDisabled">YES</bool> <bool key="NSIsSeparator">YES</bool> <string key="NSTitle"/> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="596732606"> <reference key="NSMenu" ref="786677654"/> <string key="NSTitle">Copy Style</string> <string key="NSKeyEquiv">c</string> <int key="NSKeyEquivModMask">1572864</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="393423671"> <reference key="NSMenu" ref="786677654"/> <string key="NSTitle">Paste Style</string> <string key="NSKeyEquiv">v</string> <int key="NSKeyEquivModMask">1572864</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> </object> <string key="NSName">_NSFontMenu</string> </object> </object> <object class="NSMenuItem" id="15516124"> <reference key="NSMenu" ref="941447902"/> <string key="NSTitle">Text</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="23081656"> <string key="NSTitle">Text</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="135107054"> <reference key="NSMenu" ref="23081656"/> <string key="NSTitle">Align Left</string> <string key="NSKeyEquiv">{</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="310547522"> <reference key="NSMenu" ref="23081656"/> <string key="NSTitle">Center</string> <string key="NSKeyEquiv">|</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="436088763"> <reference key="NSMenu" ref="23081656"/> <string key="NSTitle">Justify</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="498119243"> <reference key="NSMenu" ref="23081656"/> <string key="NSTitle">Align Right</string> <string key="NSKeyEquiv">}</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="607995063"> <reference key="NSMenu" ref="23081656"/> <bool key="NSIsDisabled">YES</bool> <bool key="NSIsSeparator">YES</bool> <string key="NSTitle"/> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="420564933"> <reference key="NSMenu" ref="23081656"/> <string key="NSTitle">Show Ruler</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="479856769"> <reference key="NSMenu" ref="23081656"/> <string key="NSTitle">Copy Ruler</string> <string key="NSKeyEquiv">c</string> <int key="NSKeyEquivModMask">1310720</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="333628178"> <reference key="NSMenu" ref="23081656"/> <string key="NSTitle">Paste Ruler</string> <string key="NSKeyEquiv">v</string> <int key="NSKeyEquivModMask">1310720</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> </object> </object> </object> </object> </object> </object> <object class="NSMenuItem" id="586577488"> <reference key="NSMenu" ref="649796088"/> <string key="NSTitle">View</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="466310130"> <string key="NSTitle">View</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="102151532"> <reference key="NSMenu" ref="466310130"/> <string key="NSTitle">Show Toolbar</string> <string key="NSKeyEquiv">t</string> <int key="NSKeyEquivModMask">1572864</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="237841660"> <reference key="NSMenu" ref="466310130"/> <string key="NSTitle">Customize Toolbar…</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> </object> </object> </object> <object class="NSMenuItem" id="713487014"> <reference key="NSMenu" ref="649796088"/> <string key="NSTitle">Window</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="835318025"> <string key="NSTitle">Window</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="1011231497"> <reference key="NSMenu" ref="835318025"/> <string key="NSTitle">Minimize</string> <string key="NSKeyEquiv">m</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="575023229"> <reference key="NSMenu" ref="835318025"/> <string key="NSTitle">Zoom</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="299356726"> <reference key="NSMenu" ref="835318025"/> <bool key="NSIsDisabled">YES</bool> <bool key="NSIsSeparator">YES</bool> <string key="NSTitle"/> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> <object class="NSMenuItem" id="625202149"> <reference key="NSMenu" ref="835318025"/> <string key="NSTitle">Bring All to Front</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> </object> <string key="NSName">_NSWindowsMenu</string> </object> </object> <object class="NSMenuItem" id="391199113"> <reference key="NSMenu" ref="649796088"/> <string key="NSTitle">Help</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="374024848"> <string key="NSTitle">Help</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="238773614"> <reference key="NSMenu" ref="374024848"/> <string key="NSTitle">NewApplication Help</string> <string key="NSKeyEquiv">?</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> <reference key="NSMixedImage" ref="502551668"/> </object> </object> </object> </object> </object> <string key="NSName">_NSMainMenu</string> </object> <object class="NSWindowTemplate" id="972006081"> <int key="NSWindowStyleMask">15</int> <int key="NSWindowBacking">2</int> <string key="NSWindowRect">{{335, 58}, {982, 692}}</string> <int key="NSWTFlags">1946157056</int> <string key="NSWindowTitle">Window</string> <string key="NSWindowClass">NSWindow</string> <nil key="NSViewClass"/> <string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string> <object class="NSView" key="NSWindowView" id="439893737"> <reference key="NSNextResponder"/> <int key="NSvFlags">319</int> <object class="NSMutableArray" key="NSSubviews"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSBox" id="1016473779"> <reference key="NSNextResponder" ref="439893737"/> <int key="NSvFlags">18</int> <object class="NSMutableArray" key="NSSubviews"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSView" id="33804839"> <reference key="NSNextResponder" ref="1016473779"/> <int key="NSvFlags">256</int> <string key="NSFrame">{{1, 1}, {842, 590}}</string> <reference key="NSSuperview" ref="1016473779"/> </object> </object> <string key="NSFrame">{{17, 16}, {844, 606}}</string> <reference key="NSSuperview" ref="439893737"/> <string key="NSOffsets">{0, 0}</string> <object class="NSTextFieldCell" key="NSTitleCell"> <int key="NSCellFlags">67239424</int> <int key="NSCellFlags2">0</int> <string key="NSContents">Scintilla Editor</string> <object class="NSFont" key="NSSupport"> <string key="NSName">LucidaGrande</string> <double key="NSSize">11</double> <int key="NSfFlags">3100</int> </object> <object class="NSColor" key="NSBackgroundColor" id="561710607"> <int key="NSColorSpace">6</int> <string key="NSCatalogName">System</string> <string key="NSColorName">textBackgroundColor</string> <object class="NSColor" key="NSColor"> <int key="NSColorSpace">3</int> <bytes key="NSWhite">MQA</bytes> </object> </object> <object class="NSColor" key="NSTextColor"> <int key="NSColorSpace">3</int> <bytes key="NSWhite">MCAwLjgwMDAwMDAxAA</bytes> </object> </object> <reference key="NSContentView" ref="33804839"/> <int key="NSBorderType">1</int> <int key="NSBoxType">0</int> <int key="NSTitlePosition">2</int> <bool key="NSTransparent">NO</bool> </object> <object class="NSButton" id="610247741"> <reference key="NSNextResponder" ref="439893737"/> <int key="NSvFlags">289</int> <string key="NSFrame">{{872, 12}, {96, 32}}</string> <reference key="NSSuperview" ref="439893737"/> <bool key="NSEnabled">YES</bool> <object class="NSButtonCell" key="NSCell" id="1009897894"> <int key="NSCellFlags">67239424</int> <int key="NSCellFlags2">134217728</int> <string key="NSContents">Quit</string> <object class="NSFont" key="NSSupport" id="887178038"> <string key="NSName">LucidaGrande</string> <double key="NSSize">13</double> <int key="NSfFlags">1044</int> </object> <reference key="NSControlView" ref="610247741"/> <int key="NSButtonFlags">-2038284033</int> <int key="NSButtonFlags2">129</int> <string key="NSAlternateContents"/> <string key="NSKeyEquivalent"/> <int key="NSPeriodicDelay">200</int> <int key="NSPeriodicInterval">25</int> </object> </object> <object class="NSSearchField" id="552917647"> <reference key="NSNextResponder" ref="439893737"/> <int key="NSvFlags">268</int> <string key="NSFrame">{{20, 630}, {287, 22}}</string> <reference key="NSSuperview" ref="439893737"/> <bool key="NSEnabled">YES</bool> <object class="NSSearchFieldCell" key="NSCell" id="515024530"> <int key="NSCellFlags">343014976</int> <int key="NSCellFlags2">268436480</int> <string key="NSContents"/> <reference key="NSSupport" ref="887178038"/> <reference key="NSControlView" ref="552917647"/> <bool key="NSDrawsBackground">YES</bool> <int key="NSTextBezelStyle">1</int> <reference key="NSBackgroundColor" ref="561710607"/> <object class="NSColor" key="NSTextColor"> <int key="NSColorSpace">6</int> <string key="NSCatalogName">System</string> <string key="NSColorName">controlTextColor</string> <object class="NSColor" key="NSColor"> <int key="NSColorSpace">3</int> <bytes key="NSWhite">MAA</bytes> </object> </object> <object class="NSButtonCell" key="NSSearchButtonCell"> <int key="NSCellFlags">130560</int> <int key="NSCellFlags2">0</int> <string key="NSContents">search</string> <reference key="NSControlView" ref="552917647"/> <string key="NSAction">_searchFieldSearch:</string> <reference key="NSTarget" ref="515024530"/> <int key="NSButtonFlags">138690815</int> <int key="NSButtonFlags2">0</int> <string key="NSKeyEquivalent"/> <int key="NSPeriodicDelay">400</int> <int key="NSPeriodicInterval">75</int> </object> <object class="NSButtonCell" key="NSCancelButtonCell"> <int key="NSCellFlags">130560</int> <int key="NSCellFlags2">0</int> <string key="NSContents">clear</string> <object class="NSMutableArray" key="NSAccessibilityOverriddenAttributes"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMutableDictionary"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSArray" key="dict.sortedKeys"> <bool key="EncodedWithXMLCoder">YES</bool> <string>AXDescription</string> <string>NSAccessibilityEncodedAttributesValueType</string> </object> <object class="NSMutableArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>cancel</string> <integer value="1"/> </object> </object> </object> <reference key="NSControlView" ref="552917647"/> <string key="NSAction">_searchFieldCancel:</string> <reference key="NSTarget" ref="515024530"/> <int key="NSButtonFlags">138690815</int> <int key="NSButtonFlags2">0</int> <string key="NSKeyEquivalent"/> <int key="NSPeriodicDelay">400</int> <int key="NSPeriodicInterval">75</int> </object> <int key="NSMaximumRecents">255</int> </object> </object> </object> <string key="NSFrameSize">{982, 692}</string> <reference key="NSSuperview"/> </object> <string key="NSScreenRect">{{0, 0}, {1440, 878}}</string> <string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string> </object> <object class="NSCustomObject" id="755631768"> <string key="NSClassName">NSFontManager</string> </object> <object class="NSCustomObject" id="229445039"> <string key="NSClassName">AppController</string> </object> </object> <object class="IBObjectContainer" key="IBDocument.Objects"> <object class="NSMutableArray" key="connectionRecords"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">performMiniaturize:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="1011231497"/> </object> <int key="connectionID">37</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">arrangeInFront:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="625202149"/> </object> <int key="connectionID">39</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">print:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="49223823"/> </object> <int key="connectionID">86</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">runPageLayout:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="294629803"/> </object> <int key="connectionID">87</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">clearRecentDocuments:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="759406840"/> </object> <int key="connectionID">127</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">orderFrontStandardAboutPanel:</string> <reference key="source" ref="1021"/> <reference key="destination" ref="238522557"/> </object> <int key="connectionID">142</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">performClose:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="776162233"/> </object> <int key="connectionID">193</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">toggleContinuousSpellChecking:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="948374510"/> </object> <int key="connectionID">222</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">undo:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="1058277027"/> </object> <int key="connectionID">223</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">copy:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="860595796"/> </object> <int key="connectionID">224</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">checkSpelling:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="96193923"/> </object> <int key="connectionID">225</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">paste:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="29853731"/> </object> <int key="connectionID">226</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">stopSpeaking:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="680220178"/> </object> <int key="connectionID">227</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">cut:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="296257095"/> </object> <int key="connectionID">228</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">showGuessPanel:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="679648819"/> </object> <int key="connectionID">230</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">redo:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="790794224"/> </object> <int key="connectionID">231</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">selectAll:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="583158037"/> </object> <int key="connectionID">232</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">startSpeaking:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="731782645"/> </object> <int key="connectionID">233</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">delete:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="437104165"/> </object> <int key="connectionID">235</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">performZoom:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="575023229"/> </object> <int key="connectionID">240</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">performFindPanelAction:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="447796847"/> </object> <int key="connectionID">241</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">centerSelectionInVisibleArea:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="88285865"/> </object> <int key="connectionID">245</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">toggleGrammarChecking:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="967646866"/> </object> <int key="connectionID">347</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">toggleSmartInsertDelete:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="605118523"/> </object> <int key="connectionID">355</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">toggleAutomaticQuoteSubstitution:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="197661976"/> </object> <int key="connectionID">356</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">toggleAutomaticLinkDetection:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="708854459"/> </object> <int key="connectionID">357</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">showHelp:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="238773614"/> </object> <int key="connectionID">360</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">saveDocument:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="1023925487"/> </object> <int key="connectionID">362</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">saveDocumentAs:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="117038363"/> </object> <int key="connectionID">363</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">revertDocumentToSaved:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="579971712"/> </object> <int key="connectionID">364</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">runToolbarCustomizationPalette:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="237841660"/> </object> <int key="connectionID">365</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">toggleToolbarShown:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="102151532"/> </object> <int key="connectionID">366</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">hide:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="755159360"/> </object> <int key="connectionID">367</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">hideOtherApplications:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="342932134"/> </object> <int key="connectionID">368</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">unhideAllApplications:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="908899353"/> </object> <int key="connectionID">370</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">newDocument:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="705341025"/> </object> <int key="connectionID">373</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">openDocument:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="722745758"/> </object> <int key="connectionID">374</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">addFontTrait:</string> <reference key="source" ref="755631768"/> <reference key="destination" ref="305399458"/> </object> <int key="connectionID">421</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">addFontTrait:</string> <reference key="source" ref="755631768"/> <reference key="destination" ref="814362025"/> </object> <int key="connectionID">422</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">modifyFont:</string> <reference key="source" ref="755631768"/> <reference key="destination" ref="885547335"/> </object> <int key="connectionID">423</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">orderFrontFontPanel:</string> <reference key="source" ref="755631768"/> <reference key="destination" ref="159677712"/> </object> <int key="connectionID">424</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">modifyFont:</string> <reference key="source" ref="755631768"/> <reference key="destination" ref="158063935"/> </object> <int key="connectionID">425</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">raiseBaseline:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="941806246"/> </object> <int key="connectionID">426</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">lowerBaseline:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="1045724900"/> </object> <int key="connectionID">427</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">copyFont:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="596732606"/> </object> <int key="connectionID">428</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">subscript:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="1037576581"/> </object> <int key="connectionID">429</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">superscript:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="644725453"/> </object> <int key="connectionID">430</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">tightenKerning:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="677519740"/> </object> <int key="connectionID">431</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">underline:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="330926929"/> </object> <int key="connectionID">432</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">orderFrontColorPanel:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="1012600125"/> </object> <int key="connectionID">433</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">useAllLigatures:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="663508465"/> </object> <int key="connectionID">434</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">loosenKerning:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="238351151"/> </object> <int key="connectionID">435</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">pasteFont:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="393423671"/> </object> <int key="connectionID">436</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">unscript:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="257962622"/> </object> <int key="connectionID">437</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">useStandardKerning:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="252969304"/> </object> <int key="connectionID">438</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">useStandardLigatures:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="706297211"/> </object> <int key="connectionID">439</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">turnOffLigatures:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="568384683"/> </object> <int key="connectionID">440</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">turnOffKerning:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="766922938"/> </object> <int key="connectionID">441</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">alignLeft:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="135107054"/> </object> <int key="connectionID">442</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">alignJustified:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="436088763"/> </object> <int key="connectionID">443</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">copyRuler:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="479856769"/> </object> <int key="connectionID">444</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">alignCenter:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="310547522"/> </object> <int key="connectionID">445</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">toggleRuler:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="420564933"/> </object> <int key="connectionID">446</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">alignRight:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="498119243"/> </object> <int key="connectionID">447</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">pasteRuler:</string> <reference key="source" ref="1014"/> <reference key="destination" ref="333628178"/> </object> <int key="connectionID">448</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">terminate:</string> <reference key="source" ref="1050"/> <reference key="destination" ref="632727374"/> </object> <int key="connectionID">449</int> </object> <object class="IBConnectionRecord"> <object class="IBOutletConnection" key="connection"> <string key="label">mEditHost</string> <reference key="source" ref="229445039"/> <reference key="destination" ref="1016473779"/> </object> <int key="connectionID">454</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">terminate:</string> <reference key="source" ref="1050"/> <reference key="destination" ref="610247741"/> </object> <int key="connectionID">455</int> </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">searchText:</string> <reference key="source" ref="229445039"/> <reference key="destination" ref="552917647"/> </object> <int key="connectionID">468</int> </object> </object> <object class="IBMutableOrderedSet" key="objectRecords"> <object class="NSArray" key="orderedObjects"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="IBObjectRecord"> <int key="objectID">0</int> <reference key="object" ref="0"/> <reference key="children" ref="1048"/> <nil key="parent"/> </object> <object class="IBObjectRecord"> <int key="objectID">-2</int> <reference key="object" ref="1021"/> <reference key="parent" ref="0"/> <string key="objectName">File's Owner</string> </object> <object class="IBObjectRecord"> <int key="objectID">-1</int> <reference key="object" ref="1014"/> <reference key="parent" ref="0"/> <string key="objectName">First Responder</string> </object> <object class="IBObjectRecord"> <int key="objectID">-3</int> <reference key="object" ref="1050"/> <reference key="parent" ref="0"/> <string key="objectName">Application</string> </object> <object class="IBObjectRecord"> <int key="objectID">29</int> <reference key="object" ref="649796088"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="713487014"/> <reference ref="694149608"/> <reference ref="391199113"/> <reference ref="952259628"/> <reference ref="379814623"/> <reference ref="586577488"/> <reference ref="302598603"/> </object> <reference key="parent" ref="0"/> <string key="objectName">MainMenu</string> </object> <object class="IBObjectRecord"> <int key="objectID">19</int> <reference key="object" ref="713487014"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="835318025"/> </object> <reference key="parent" ref="649796088"/> </object> <object class="IBObjectRecord"> <int key="objectID">56</int> <reference key="object" ref="694149608"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="110575045"/> </object> <reference key="parent" ref="649796088"/> </object> <object class="IBObjectRecord"> <int key="objectID">103</int> <reference key="object" ref="391199113"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="374024848"/> </object> <reference key="parent" ref="649796088"/> <string key="objectName">1</string> </object> <object class="IBObjectRecord"> <int key="objectID">217</int> <reference key="object" ref="952259628"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="789758025"/> </object> <reference key="parent" ref="649796088"/> </object> <object class="IBObjectRecord"> <int key="objectID">83</int> <reference key="object" ref="379814623"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="720053764"/> </object> <reference key="parent" ref="649796088"/> </object> <object class="IBObjectRecord"> <int key="objectID">81</int> <reference key="object" ref="720053764"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="1023925487"/> <reference ref="117038363"/> <reference ref="49223823"/> <reference ref="722745758"/> <reference ref="705341025"/> <reference ref="1025936716"/> <reference ref="294629803"/> <reference ref="776162233"/> <reference ref="425164168"/> <reference ref="579971712"/> <reference ref="1010469920"/> </object> <reference key="parent" ref="379814623"/> </object> <object class="IBObjectRecord"> <int key="objectID">75</int> <reference key="object" ref="1023925487"/> <reference key="parent" ref="720053764"/> <string key="objectName">3</string> </object> <object class="IBObjectRecord"> <int key="objectID">80</int> <reference key="object" ref="117038363"/> <reference key="parent" ref="720053764"/> <string key="objectName">8</string> </object> <object class="IBObjectRecord"> <int key="objectID">78</int> <reference key="object" ref="49223823"/> <reference key="parent" ref="720053764"/> <string key="objectName">6</string> </object> <object class="IBObjectRecord"> <int key="objectID">72</int> <reference key="object" ref="722745758"/> <reference key="parent" ref="720053764"/> </object> <object class="IBObjectRecord"> <int key="objectID">82</int> <reference key="object" ref="705341025"/> <reference key="parent" ref="720053764"/> <string key="objectName">9</string> </object> <object class="IBObjectRecord"> <int key="objectID">124</int> <reference key="object" ref="1025936716"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="1065607017"/> </object> <reference key="parent" ref="720053764"/> </object> <object class="IBObjectRecord"> <int key="objectID">77</int> <reference key="object" ref="294629803"/> <reference key="parent" ref="720053764"/> <string key="objectName">5</string> </object> <object class="IBObjectRecord"> <int key="objectID">73</int> <reference key="object" ref="776162233"/> <reference key="parent" ref="720053764"/> <string key="objectName">1</string> </object> <object class="IBObjectRecord"> <int key="objectID">79</int> <reference key="object" ref="425164168"/> <reference key="parent" ref="720053764"/> <string key="objectName">7</string> </object> <object class="IBObjectRecord"> <int key="objectID">112</int> <reference key="object" ref="579971712"/> <reference key="parent" ref="720053764"/> <string key="objectName">10</string> </object> <object class="IBObjectRecord"> <int key="objectID">74</int> <reference key="object" ref="1010469920"/> <reference key="parent" ref="720053764"/> <string key="objectName">2</string> </object> <object class="IBObjectRecord"> <int key="objectID">125</int> <reference key="object" ref="1065607017"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="759406840"/> </object> <reference key="parent" ref="1025936716"/> </object> <object class="IBObjectRecord"> <int key="objectID">126</int> <reference key="object" ref="759406840"/> <reference key="parent" ref="1065607017"/> </object> <object class="IBObjectRecord"> <int key="objectID">205</int> <reference key="object" ref="789758025"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="437104165"/> <reference ref="583158037"/> <reference ref="1058277027"/> <reference ref="212016141"/> <reference ref="296257095"/> <reference ref="29853731"/> <reference ref="860595796"/> <reference ref="1040322652"/> <reference ref="790794224"/> <reference ref="892235320"/> <reference ref="972420730"/> <reference ref="676164635"/> <reference ref="507821607"/> </object> <reference key="parent" ref="952259628"/> </object> <object class="IBObjectRecord"> <int key="objectID">202</int> <reference key="object" ref="437104165"/> <reference key="parent" ref="789758025"/> </object> <object class="IBObjectRecord"> <int key="objectID">198</int> <reference key="object" ref="583158037"/> <reference key="parent" ref="789758025"/> </object> <object class="IBObjectRecord"> <int key="objectID">207</int> <reference key="object" ref="1058277027"/> <reference key="parent" ref="789758025"/> </object> <object class="IBObjectRecord"> <int key="objectID">214</int> <reference key="object" ref="212016141"/> <reference key="parent" ref="789758025"/> </object> <object class="IBObjectRecord"> <int key="objectID">199</int> <reference key="object" ref="296257095"/> <reference key="parent" ref="789758025"/> </object> <object class="IBObjectRecord"> <int key="objectID">203</int> <reference key="object" ref="29853731"/> <reference key="parent" ref="789758025"/> </object> <object class="IBObjectRecord"> <int key="objectID">197</int> <reference key="object" ref="860595796"/> <reference key="parent" ref="789758025"/> </object> <object class="IBObjectRecord"> <int key="objectID">206</int> <reference key="object" ref="1040322652"/> <reference key="parent" ref="789758025"/> </object> <object class="IBObjectRecord"> <int key="objectID">215</int> <reference key="object" ref="790794224"/> <reference key="parent" ref="789758025"/> </object> <object class="IBObjectRecord"> <int key="objectID">218</int> <reference key="object" ref="892235320"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="963351320"/> </object> <reference key="parent" ref="789758025"/> </object> <object class="IBObjectRecord"> <int key="objectID">216</int> <reference key="object" ref="972420730"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="769623530"/> </object> <reference key="parent" ref="789758025"/> </object> <object class="IBObjectRecord"> <int key="objectID">200</int> <reference key="object" ref="769623530"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="948374510"/> <reference ref="96193923"/> <reference ref="679648819"/> <reference ref="967646866"/> </object> <reference key="parent" ref="972420730"/> </object> <object class="IBObjectRecord"> <int key="objectID">219</int> <reference key="object" ref="948374510"/> <reference key="parent" ref="769623530"/> </object> <object class="IBObjectRecord"> <int key="objectID">201</int> <reference key="object" ref="96193923"/> <reference key="parent" ref="769623530"/> </object> <object class="IBObjectRecord"> <int key="objectID">204</int> <reference key="object" ref="679648819"/> <reference key="parent" ref="769623530"/> </object> <object class="IBObjectRecord"> <int key="objectID">220</int> <reference key="object" ref="963351320"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="270902937"/> <reference ref="88285865"/> <reference ref="159080638"/> <reference ref="326711663"/> <reference ref="447796847"/> </object> <reference key="parent" ref="892235320"/> </object> <object class="IBObjectRecord"> <int key="objectID">213</int> <reference key="object" ref="270902937"/> <reference key="parent" ref="963351320"/> </object> <object class="IBObjectRecord"> <int key="objectID">210</int> <reference key="object" ref="88285865"/> <reference key="parent" ref="963351320"/> </object> <object class="IBObjectRecord"> <int key="objectID">221</int> <reference key="object" ref="159080638"/> <reference key="parent" ref="963351320"/> </object> <object class="IBObjectRecord"> <int key="objectID">208</int> <reference key="object" ref="326711663"/> <reference key="parent" ref="963351320"/> </object> <object class="IBObjectRecord"> <int key="objectID">209</int> <reference key="object" ref="447796847"/> <reference key="parent" ref="963351320"/> </object> <object class="IBObjectRecord"> <int key="objectID">106</int> <reference key="object" ref="374024848"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="238773614"/> </object> <reference key="parent" ref="391199113"/> <string key="objectName">2</string> </object> <object class="IBObjectRecord"> <int key="objectID">111</int> <reference key="object" ref="238773614"/> <reference key="parent" ref="374024848"/> </object> <object class="IBObjectRecord"> <int key="objectID">57</int> <reference key="object" ref="110575045"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="238522557"/> <reference ref="755159360"/> <reference ref="908899353"/> <reference ref="632727374"/> <reference ref="646227648"/> <reference ref="609285721"/> <reference ref="481834944"/> <reference ref="304266470"/> <reference ref="1046388886"/> <reference ref="1056857174"/> <reference ref="342932134"/> </object> <reference key="parent" ref="694149608"/> </object> <object class="IBObjectRecord"> <int key="objectID">58</int> <reference key="object" ref="238522557"/> <reference key="parent" ref="110575045"/> </object> <object class="IBObjectRecord"> <int key="objectID">134</int> <reference key="object" ref="755159360"/> <reference key="parent" ref="110575045"/> </object> <object class="IBObjectRecord"> <int key="objectID">150</int> <reference key="object" ref="908899353"/> <reference key="parent" ref="110575045"/> </object> <object class="IBObjectRecord"> <int key="objectID">136</int> <reference key="object" ref="632727374"/> <reference key="parent" ref="110575045"/> <string key="objectName">1111</string> </object> <object class="IBObjectRecord"> <int key="objectID">144</int> <reference key="object" ref="646227648"/> <reference key="parent" ref="110575045"/> </object> <object class="IBObjectRecord"> <int key="objectID">129</int> <reference key="object" ref="609285721"/> <reference key="parent" ref="110575045"/> <string key="objectName">121</string> </object> <object class="IBObjectRecord"> <int key="objectID">143</int> <reference key="object" ref="481834944"/> <reference key="parent" ref="110575045"/> </object> <object class="IBObjectRecord"> <int key="objectID">236</int> <reference key="object" ref="304266470"/> <reference key="parent" ref="110575045"/> </object> <object class="IBObjectRecord"> <int key="objectID">131</int> <reference key="object" ref="1046388886"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="752062318"/> </object> <reference key="parent" ref="110575045"/> </object> <object class="IBObjectRecord"> <int key="objectID">149</int> <reference key="object" ref="1056857174"/> <reference key="parent" ref="110575045"/> </object> <object class="IBObjectRecord"> <int key="objectID">145</int> <reference key="object" ref="342932134"/> <reference key="parent" ref="110575045"/> </object> <object class="IBObjectRecord"> <int key="objectID">130</int> <reference key="object" ref="752062318"/> <reference key="parent" ref="1046388886"/> </object> <object class="IBObjectRecord"> <int key="objectID">24</int> <reference key="object" ref="835318025"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="299356726"/> <reference ref="625202149"/> <reference ref="575023229"/> <reference ref="1011231497"/> </object> <reference key="parent" ref="713487014"/> </object> <object class="IBObjectRecord"> <int key="objectID">92</int> <reference key="object" ref="299356726"/> <reference key="parent" ref="835318025"/> </object> <object class="IBObjectRecord"> <int key="objectID">5</int> <reference key="object" ref="625202149"/> <reference key="parent" ref="835318025"/> </object> <object class="IBObjectRecord"> <int key="objectID">239</int> <reference key="object" ref="575023229"/> <reference key="parent" ref="835318025"/> </object> <object class="IBObjectRecord"> <int key="objectID">23</int> <reference key="object" ref="1011231497"/> <reference key="parent" ref="835318025"/> </object> <object class="IBObjectRecord"> <int key="objectID">295</int> <reference key="object" ref="586577488"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="466310130"/> </object> <reference key="parent" ref="649796088"/> </object> <object class="IBObjectRecord"> <int key="objectID">296</int> <reference key="object" ref="466310130"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="102151532"/> <reference ref="237841660"/> </object> <reference key="parent" ref="586577488"/> </object> <object class="IBObjectRecord"> <int key="objectID">297</int> <reference key="object" ref="102151532"/> <reference key="parent" ref="466310130"/> </object> <object class="IBObjectRecord"> <int key="objectID">298</int> <reference key="object" ref="237841660"/> <reference key="parent" ref="466310130"/> </object> <object class="IBObjectRecord"> <int key="objectID">211</int> <reference key="object" ref="676164635"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="785027613"/> </object> <reference key="parent" ref="789758025"/> </object> <object class="IBObjectRecord"> <int key="objectID">212</int> <reference key="object" ref="785027613"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="680220178"/> <reference ref="731782645"/> </object> <reference key="parent" ref="676164635"/> </object> <object class="IBObjectRecord"> <int key="objectID">195</int> <reference key="object" ref="680220178"/> <reference key="parent" ref="785027613"/> </object> <object class="IBObjectRecord"> <int key="objectID">196</int> <reference key="object" ref="731782645"/> <reference key="parent" ref="785027613"/> </object> <object class="IBObjectRecord"> <int key="objectID">346</int> <reference key="object" ref="967646866"/> <reference key="parent" ref="769623530"/> </object> <object class="IBObjectRecord"> <int key="objectID">348</int> <reference key="object" ref="507821607"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="698887838"/> </object> <reference key="parent" ref="789758025"/> </object> <object class="IBObjectRecord"> <int key="objectID">349</int> <reference key="object" ref="698887838"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="605118523"/> <reference ref="197661976"/> <reference ref="708854459"/> </object> <reference key="parent" ref="507821607"/> </object> <object class="IBObjectRecord"> <int key="objectID">350</int> <reference key="object" ref="605118523"/> <reference key="parent" ref="698887838"/> </object> <object class="IBObjectRecord"> <int key="objectID">351</int> <reference key="object" ref="197661976"/> <reference key="parent" ref="698887838"/> </object> <object class="IBObjectRecord"> <int key="objectID">354</int> <reference key="object" ref="708854459"/> <reference key="parent" ref="698887838"/> </object> <object class="IBObjectRecord"> <int key="objectID">371</int> <reference key="object" ref="972006081"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="439893737"/> </object> <reference key="parent" ref="0"/> </object> <object class="IBObjectRecord"> <int key="objectID">372</int> <reference key="object" ref="439893737"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="1016473779"/> <reference ref="610247741"/> <reference ref="552917647"/> </object> <reference key="parent" ref="972006081"/> </object> <object class="IBObjectRecord"> <int key="objectID">375</int> <reference key="object" ref="302598603"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="941447902"/> </object> <reference key="parent" ref="649796088"/> </object> <object class="IBObjectRecord"> <int key="objectID">376</int> <reference key="object" ref="941447902"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="792887677"/> <reference ref="15516124"/> </object> <reference key="parent" ref="302598603"/> </object> <object class="IBObjectRecord"> <int key="objectID">377</int> <reference key="object" ref="792887677"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="786677654"/> </object> <reference key="parent" ref="941447902"/> </object> <object class="IBObjectRecord"> <int key="objectID">378</int> <reference key="object" ref="15516124"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="23081656"/> </object> <reference key="parent" ref="941447902"/> </object> <object class="IBObjectRecord"> <int key="objectID">379</int> <reference key="object" ref="23081656"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="135107054"/> <reference ref="310547522"/> <reference ref="436088763"/> <reference ref="498119243"/> <reference ref="607995063"/> <reference ref="420564933"/> <reference ref="479856769"/> <reference ref="333628178"/> </object> <reference key="parent" ref="15516124"/> </object> <object class="IBObjectRecord"> <int key="objectID">380</int> <reference key="object" ref="135107054"/> <reference key="parent" ref="23081656"/> </object> <object class="IBObjectRecord"> <int key="objectID">381</int> <reference key="object" ref="310547522"/> <reference key="parent" ref="23081656"/> </object> <object class="IBObjectRecord"> <int key="objectID">382</int> <reference key="object" ref="436088763"/> <reference key="parent" ref="23081656"/> </object> <object class="IBObjectRecord"> <int key="objectID">383</int> <reference key="object" ref="498119243"/> <reference key="parent" ref="23081656"/> </object> <object class="IBObjectRecord"> <int key="objectID">384</int> <reference key="object" ref="607995063"/> <reference key="parent" ref="23081656"/> </object> <object class="IBObjectRecord"> <int key="objectID">385</int> <reference key="object" ref="420564933"/> <reference key="parent" ref="23081656"/> </object> <object class="IBObjectRecord"> <int key="objectID">386</int> <reference key="object" ref="479856769"/> <reference key="parent" ref="23081656"/> </object> <object class="IBObjectRecord"> <int key="objectID">387</int> <reference key="object" ref="333628178"/> <reference key="parent" ref="23081656"/> </object> <object class="IBObjectRecord"> <int key="objectID">388</int> <reference key="object" ref="786677654"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="159677712"/> <reference ref="305399458"/> <reference ref="814362025"/> <reference ref="330926929"/> <reference ref="533507878"/> <reference ref="158063935"/> <reference ref="885547335"/> <reference ref="901062459"/> <reference ref="767671776"/> <reference ref="691570813"/> <reference ref="769124883"/> <reference ref="739652853"/> <reference ref="1012600125"/> <reference ref="214559597"/> <reference ref="596732606"/> <reference ref="393423671"/> </object> <reference key="parent" ref="792887677"/> </object> <object class="IBObjectRecord"> <int key="objectID">389</int> <reference key="object" ref="159677712"/> <reference key="parent" ref="786677654"/> </object> <object class="IBObjectRecord"> <int key="objectID">390</int> <reference key="object" ref="305399458"/> <reference key="parent" ref="786677654"/> </object> <object class="IBObjectRecord"> <int key="objectID">391</int> <reference key="object" ref="814362025"/> <reference key="parent" ref="786677654"/> </object> <object class="IBObjectRecord"> <int key="objectID">392</int> <reference key="object" ref="330926929"/> <reference key="parent" ref="786677654"/> </object> <object class="IBObjectRecord"> <int key="objectID">393</int> <reference key="object" ref="533507878"/> <reference key="parent" ref="786677654"/> </object> <object class="IBObjectRecord"> <int key="objectID">394</int> <reference key="object" ref="158063935"/> <reference key="parent" ref="786677654"/> </object> <object class="IBObjectRecord"> <int key="objectID">395</int> <reference key="object" ref="885547335"/> <reference key="parent" ref="786677654"/> </object> <object class="IBObjectRecord"> <int key="objectID">396</int> <reference key="object" ref="901062459"/> <reference key="parent" ref="786677654"/> </object> <object class="IBObjectRecord"> <int key="objectID">397</int> <reference key="object" ref="767671776"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="175441468"/> </object> <reference key="parent" ref="786677654"/> </object> <object class="IBObjectRecord"> <int key="objectID">398</int> <reference key="object" ref="691570813"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="1058217995"/> </object> <reference key="parent" ref="786677654"/> </object> <object class="IBObjectRecord"> <int key="objectID">399</int> <reference key="object" ref="769124883"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="18263474"/> </object> <reference key="parent" ref="786677654"/> </object> <object class="IBObjectRecord"> <int key="objectID">400</int> <reference key="object" ref="739652853"/> <reference key="parent" ref="786677654"/> </object> <object class="IBObjectRecord"> <int key="objectID">401</int> <reference key="object" ref="1012600125"/> <reference key="parent" ref="786677654"/> </object> <object class="IBObjectRecord"> <int key="objectID">402</int> <reference key="object" ref="214559597"/> <reference key="parent" ref="786677654"/> </object> <object class="IBObjectRecord"> <int key="objectID">403</int> <reference key="object" ref="596732606"/> <reference key="parent" ref="786677654"/> </object> <object class="IBObjectRecord"> <int key="objectID">404</int> <reference key="object" ref="393423671"/> <reference key="parent" ref="786677654"/> </object> <object class="IBObjectRecord"> <int key="objectID">405</int> <reference key="object" ref="18263474"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="257962622"/> <reference ref="644725453"/> <reference ref="1037576581"/> <reference ref="941806246"/> <reference ref="1045724900"/> </object> <reference key="parent" ref="769124883"/> </object> <object class="IBObjectRecord"> <int key="objectID">406</int> <reference key="object" ref="257962622"/> <reference key="parent" ref="18263474"/> </object> <object class="IBObjectRecord"> <int key="objectID">407</int> <reference key="object" ref="644725453"/> <reference key="parent" ref="18263474"/> </object> <object class="IBObjectRecord"> <int key="objectID">408</int> <reference key="object" ref="1037576581"/> <reference key="parent" ref="18263474"/> </object> <object class="IBObjectRecord"> <int key="objectID">409</int> <reference key="object" ref="941806246"/> <reference key="parent" ref="18263474"/> </object> <object class="IBObjectRecord"> <int key="objectID">410</int> <reference key="object" ref="1045724900"/> <reference key="parent" ref="18263474"/> </object> <object class="IBObjectRecord"> <int key="objectID">411</int> <reference key="object" ref="1058217995"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="706297211"/> <reference ref="568384683"/> <reference ref="663508465"/> </object> <reference key="parent" ref="691570813"/> </object> <object class="IBObjectRecord"> <int key="objectID">412</int> <reference key="object" ref="706297211"/> <reference key="parent" ref="1058217995"/> </object> <object class="IBObjectRecord"> <int key="objectID">413</int> <reference key="object" ref="568384683"/> <reference key="parent" ref="1058217995"/> </object> <object class="IBObjectRecord"> <int key="objectID">414</int> <reference key="object" ref="663508465"/> <reference key="parent" ref="1058217995"/> </object> <object class="IBObjectRecord"> <int key="objectID">415</int> <reference key="object" ref="175441468"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="252969304"/> <reference ref="766922938"/> <reference ref="677519740"/> <reference ref="238351151"/> </object> <reference key="parent" ref="767671776"/> </object> <object class="IBObjectRecord"> <int key="objectID">416</int> <reference key="object" ref="252969304"/> <reference key="parent" ref="175441468"/> </object> <object class="IBObjectRecord"> <int key="objectID">417</int> <reference key="object" ref="766922938"/> <reference key="parent" ref="175441468"/> </object> <object class="IBObjectRecord"> <int key="objectID">418</int> <reference key="object" ref="677519740"/> <reference key="parent" ref="175441468"/> </object> <object class="IBObjectRecord"> <int key="objectID">419</int> <reference key="object" ref="238351151"/> <reference key="parent" ref="175441468"/> </object> <object class="IBObjectRecord"> <int key="objectID">420</int> <reference key="object" ref="755631768"/> <reference key="parent" ref="0"/> </object> <object class="IBObjectRecord"> <int key="objectID">450</int> <reference key="object" ref="229445039"/> <reference key="parent" ref="0"/> </object> <object class="IBObjectRecord"> <int key="objectID">451</int> <reference key="object" ref="1016473779"/> <reference key="parent" ref="439893737"/> </object> <object class="IBObjectRecord"> <int key="objectID">452</int> <reference key="object" ref="610247741"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="1009897894"/> </object> <reference key="parent" ref="439893737"/> </object> <object class="IBObjectRecord"> <int key="objectID">453</int> <reference key="object" ref="1009897894"/> <reference key="parent" ref="610247741"/> </object> <object class="IBObjectRecord"> <int key="objectID">466</int> <reference key="object" ref="552917647"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> <reference ref="515024530"/> </object> <reference key="parent" ref="439893737"/> </object> <object class="IBObjectRecord"> <int key="objectID">467</int> <reference key="object" ref="515024530"/> <reference key="parent" ref="552917647"/> </object> </object> </object> <object class="NSMutableDictionary" key="flattenedProperties"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSArray" key="dict.sortedKeys"> <bool key="EncodedWithXMLCoder">YES</bool> <string>-3.IBPluginDependency</string> <string>103.IBPluginDependency</string> <string>103.ImportedFromIB2</string> <string>106.IBPluginDependency</string> <string>106.ImportedFromIB2</string> <string>106.editorWindowContentRectSynchronizationRect</string> <string>111.IBPluginDependency</string> <string>111.ImportedFromIB2</string> <string>112.IBPluginDependency</string> <string>112.ImportedFromIB2</string> <string>124.IBPluginDependency</string> <string>124.ImportedFromIB2</string> <string>125.IBPluginDependency</string> <string>125.ImportedFromIB2</string> <string>125.editorWindowContentRectSynchronizationRect</string> <string>126.IBPluginDependency</string> <string>126.ImportedFromIB2</string> <string>129.IBPluginDependency</string> <string>129.ImportedFromIB2</string> <string>130.IBPluginDependency</string> <string>130.ImportedFromIB2</string> <string>130.editorWindowContentRectSynchronizationRect</string> <string>131.IBPluginDependency</string> <string>131.ImportedFromIB2</string> <string>134.IBPluginDependency</string> <string>134.ImportedFromIB2</string> <string>136.IBPluginDependency</string> <string>136.ImportedFromIB2</string> <string>143.IBPluginDependency</string> <string>143.ImportedFromIB2</string> <string>144.IBPluginDependency</string> <string>144.ImportedFromIB2</string> <string>145.IBPluginDependency</string> <string>145.ImportedFromIB2</string> <string>149.IBPluginDependency</string> <string>149.ImportedFromIB2</string> <string>150.IBPluginDependency</string> <string>150.ImportedFromIB2</string> <string>19.IBPluginDependency</string> <string>19.ImportedFromIB2</string> <string>195.IBPluginDependency</string> <string>195.ImportedFromIB2</string> <string>196.IBPluginDependency</string> <string>196.ImportedFromIB2</string> <string>197.IBPluginDependency</string> <string>197.ImportedFromIB2</string> <string>198.IBPluginDependency</string> <string>198.ImportedFromIB2</string> <string>199.IBPluginDependency</string> <string>199.ImportedFromIB2</string> <string>200.IBPluginDependency</string> <string>200.ImportedFromIB2</string> <string>200.editorWindowContentRectSynchronizationRect</string> <string>201.IBPluginDependency</string> <string>201.ImportedFromIB2</string> <string>202.IBPluginDependency</string> <string>202.ImportedFromIB2</string> <string>203.IBPluginDependency</string> <string>203.ImportedFromIB2</string> <string>204.IBPluginDependency</string> <string>204.ImportedFromIB2</string> <string>205.IBPluginDependency</string> <string>205.ImportedFromIB2</string> <string>205.editorWindowContentRectSynchronizationRect</string> <string>206.IBPluginDependency</string> <string>206.ImportedFromIB2</string> <string>207.IBPluginDependency</string> <string>207.ImportedFromIB2</string> <string>208.IBPluginDependency</string> <string>208.ImportedFromIB2</string> <string>209.IBPluginDependency</string> <string>209.ImportedFromIB2</string> <string>210.IBPluginDependency</string> <string>210.ImportedFromIB2</string> <string>211.IBPluginDependency</string> <string>211.ImportedFromIB2</string> <string>212.IBPluginDependency</string> <string>212.ImportedFromIB2</string> <string>212.editorWindowContentRectSynchronizationRect</string> <string>213.IBPluginDependency</string> <string>213.ImportedFromIB2</string> <string>214.IBPluginDependency</string> <string>214.ImportedFromIB2</string> <string>215.IBPluginDependency</string> <string>215.ImportedFromIB2</string> <string>216.IBPluginDependency</string> <string>216.ImportedFromIB2</string> <string>217.IBPluginDependency</string> <string>217.ImportedFromIB2</string> <string>218.IBPluginDependency</string> <string>218.ImportedFromIB2</string> <string>219.IBPluginDependency</string> <string>219.ImportedFromIB2</string> <string>220.IBPluginDependency</string> <string>220.ImportedFromIB2</string> <string>220.editorWindowContentRectSynchronizationRect</string> <string>221.IBPluginDependency</string> <string>221.ImportedFromIB2</string> <string>23.IBPluginDependency</string> <string>23.ImportedFromIB2</string> <string>236.IBPluginDependency</string> <string>236.ImportedFromIB2</string> <string>239.IBPluginDependency</string> <string>239.ImportedFromIB2</string> <string>24.IBPluginDependency</string> <string>24.ImportedFromIB2</string> <string>24.editorWindowContentRectSynchronizationRect</string> <string>29.IBEditorWindowLastContentRect</string> <string>29.IBPluginDependency</string> <string>29.ImportedFromIB2</string> <string>29.WindowOrigin</string> <string>29.editorWindowContentRectSynchronizationRect</string> <string>295.IBPluginDependency</string> <string>296.IBPluginDependency</string> <string>296.editorWindowContentRectSynchronizationRect</string> <string>297.IBPluginDependency</string> <string>298.IBPluginDependency</string> <string>346.IBPluginDependency</string> <string>346.ImportedFromIB2</string> <string>348.IBPluginDependency</string> <string>348.ImportedFromIB2</string> <string>349.IBPluginDependency</string> <string>349.ImportedFromIB2</string> <string>349.editorWindowContentRectSynchronizationRect</string> <string>350.IBPluginDependency</string> <string>350.ImportedFromIB2</string> <string>351.IBPluginDependency</string> <string>351.ImportedFromIB2</string> <string>354.IBPluginDependency</string> <string>354.ImportedFromIB2</string> <string>371.IBEditorWindowLastContentRect</string> <string>371.IBPluginDependency</string> <string>371.IBWindowTemplateEditedContentRect</string> <string>371.NSWindowTemplate.visibleAtLaunch</string> <string>371.editorWindowContentRectSynchronizationRect</string> <string>371.windowTemplate.maxSize</string> <string>372.IBPluginDependency</string> <string>375.IBPluginDependency</string> <string>376.IBEditorWindowLastContentRect</string> <string>376.IBPluginDependency</string> <string>377.IBPluginDependency</string> <string>378.IBPluginDependency</string> <string>379.IBPluginDependency</string> <string>380.IBPluginDependency</string> <string>381.IBPluginDependency</string> <string>382.IBPluginDependency</string> <string>383.IBPluginDependency</string> <string>384.IBPluginDependency</string> <string>385.IBPluginDependency</string> <string>386.IBPluginDependency</string> <string>387.IBPluginDependency</string> <string>388.IBEditorWindowLastContentRect</string> <string>388.IBPluginDependency</string> <string>389.IBPluginDependency</string> <string>390.IBPluginDependency</string> <string>391.IBPluginDependency</string> <string>392.IBPluginDependency</string> <string>393.IBPluginDependency</string> <string>394.IBPluginDependency</string> <string>395.IBPluginDependency</string> <string>396.IBPluginDependency</string> <string>397.IBPluginDependency</string> <string>398.IBPluginDependency</string> <string>399.IBPluginDependency</string> <string>400.IBPluginDependency</string> <string>401.IBPluginDependency</string> <string>402.IBPluginDependency</string> <string>403.IBPluginDependency</string> <string>404.IBPluginDependency</string> <string>405.IBPluginDependency</string> <string>406.IBPluginDependency</string> <string>407.IBPluginDependency</string> <string>408.IBPluginDependency</string> <string>409.IBPluginDependency</string> <string>410.IBPluginDependency</string> <string>411.IBPluginDependency</string> <string>412.IBPluginDependency</string> <string>413.IBPluginDependency</string> <string>414.IBPluginDependency</string> <string>415.IBPluginDependency</string> <string>416.IBPluginDependency</string> <string>417.IBPluginDependency</string> <string>418.IBPluginDependency</string> <string>419.IBPluginDependency</string> <string>451.IBPluginDependency</string> <string>452.IBPluginDependency</string> <string>453.IBPluginDependency</string> <string>466.IBPluginDependency</string> <string>467.IBPluginDependency</string> <string>5.IBPluginDependency</string> <string>5.ImportedFromIB2</string> <string>56.IBPluginDependency</string> <string>56.ImportedFromIB2</string> <string>57.IBEditorWindowLastContentRect</string> <string>57.IBPluginDependency</string> <string>57.ImportedFromIB2</string> <string>57.editorWindowContentRectSynchronizationRect</string> <string>58.IBPluginDependency</string> <string>58.ImportedFromIB2</string> <string>72.IBPluginDependency</string> <string>72.ImportedFromIB2</string> <string>73.IBPluginDependency</string> <string>73.ImportedFromIB2</string> <string>74.IBPluginDependency</string> <string>74.ImportedFromIB2</string> <string>75.IBPluginDependency</string> <string>75.ImportedFromIB2</string> <string>77.IBPluginDependency</string> <string>77.ImportedFromIB2</string> <string>78.IBPluginDependency</string> <string>78.ImportedFromIB2</string> <string>79.IBPluginDependency</string> <string>79.ImportedFromIB2</string> <string>80.IBPluginDependency</string> <string>80.ImportedFromIB2</string> <string>81.IBPluginDependency</string> <string>81.ImportedFromIB2</string> <string>81.editorWindowContentRectSynchronizationRect</string> <string>82.IBPluginDependency</string> <string>82.ImportedFromIB2</string> <string>83.IBPluginDependency</string> <string>83.ImportedFromIB2</string> <string>92.IBPluginDependency</string> <string>92.ImportedFromIB2</string> </object> <object class="NSMutableArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>{{596, 852}, {216, 23}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>{{522, 812}, {146, 23}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>{{436, 809}, {64, 6}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>{{608, 612}, {275, 83}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>{{187, 434}, {243, 243}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>{{608, 612}, {167, 43}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>{{608, 612}, {241, 103}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>{{525, 802}, {197, 73}}</string> <string>{{207, 285}, {478, 20}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>{74, 862}</string> <string>{{6, 978}, {478, 20}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>{{475, 832}, {234, 43}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>{{608, 612}, {215, 63}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>{{274, 370}, {982, 692}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>{{274, 370}, {982, 692}}</string> <integer value="1"/> <string>{{33, 99}, {480, 360}}</string> <string>{3.40282e+38, 3.40282e+38}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>{{437, 242}, {86, 43}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>{{523, 2}, {178, 283}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>{{219, 102}, {245, 183}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>{{23, 794}, {245, 183}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>{{145, 474}, {199, 203}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> </object> </object> <object class="NSMutableDictionary" key="unlocalizedProperties"> <bool key="EncodedWithXMLCoder">YES</bool> <reference key="dict.sortedKeys" ref="0"/> <object class="NSMutableArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> </object> </object> <nil key="activeLocalization"/> <object class="NSMutableDictionary" key="localizations"> <bool key="EncodedWithXMLCoder">YES</bool> <reference key="dict.sortedKeys" ref="0"/> <object class="NSMutableArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> </object> </object> <nil key="sourceID"/> <int key="maxID">468</int> </object> <object class="IBClassDescriber" key="IBDocument.Classes"> <object class="NSMutableArray" key="referencedPartialClassDescriptions"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="IBPartialClassDescription"> <string key="className">AppController</string> <string key="superclassName">NSObject</string> <object class="NSMutableDictionary" key="actions"> <string key="NS.key.0">searchText:</string> <string key="NS.object.0">id</string> </object> <object class="NSMutableDictionary" key="outlets"> <string key="NS.key.0">mEditHost</string> <string key="NS.object.0">NSBox</string> </object> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBProjectSource</string> <string key="minorKey">AppController.h</string> </object> </object> </object> <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="IBPartialClassDescription"> <string key="className">NSActionCell</string> <string key="superclassName">NSCell</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSActionCell.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSApplication</string> <string key="superclassName">NSResponder</string> <object class="IBClassDescriptionSource" key="sourceIdentifier" id="905531705"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSApplication.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSApplication</string> <object class="IBClassDescriptionSource" key="sourceIdentifier" id="854027565"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSApplicationScripting.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSApplication</string> <object class="IBClassDescriptionSource" key="sourceIdentifier" id="562071960"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSColorPanel.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSApplication</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSHelpManager.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSApplication</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSPageLayout.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSApplication</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSUserInterfaceItemSearching.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSBox</string> <string key="superclassName">NSView</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSBox.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSBrowser</string> <string key="superclassName">NSControl</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSBrowser.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSButton</string> <string key="superclassName">NSControl</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSButton.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSButtonCell</string> <string key="superclassName">NSActionCell</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSButtonCell.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSCell</string> <string key="superclassName">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSCell.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSControl</string> <string key="superclassName">NSView</string> <object class="IBClassDescriptionSource" key="sourceIdentifier" id="10957210"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSControl.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSDocument</string> <string key="superclassName">NSObject</string> <object class="NSMutableDictionary" key="actions"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSArray" key="dict.sortedKeys"> <bool key="EncodedWithXMLCoder">YES</bool> <string>printDocument:</string> <string>revertDocumentToSaved:</string> <string>runPageLayout:</string> <string>saveDocument:</string> <string>saveDocumentAs:</string> <string>saveDocumentTo:</string> </object> <object class="NSMutableArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>id</string> <string>id</string> <string>id</string> <string>id</string> <string>id</string> <string>id</string> </object> </object> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSDocument.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSDocument</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSDocumentScripting.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSDocumentController</string> <string key="superclassName">NSObject</string> <object class="NSMutableDictionary" key="actions"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSArray" key="dict.sortedKeys"> <bool key="EncodedWithXMLCoder">YES</bool> <string>clearRecentDocuments:</string> <string>newDocument:</string> <string>openDocument:</string> <string>saveAllDocuments:</string> </object> <object class="NSMutableArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>id</string> <string>id</string> <string>id</string> <string>id</string> </object> </object> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSDocumentController.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSFontManager</string> <string key="superclassName">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier" id="60454901"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSFontManager.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSFormatter</string> <string key="superclassName">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSFormatter.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSMatrix</string> <string key="superclassName">NSControl</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSMatrix.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSMenu</string> <string key="superclassName">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier" id="687201532"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSMenu.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSMenuItem</string> <string key="superclassName">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier" id="283337664"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSMenuItem.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSMovieView</string> <string key="superclassName">NSView</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSMovieView.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSAccessibility.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <reference key="sourceIdentifier" ref="905531705"/> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <reference key="sourceIdentifier" ref="854027565"/> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <reference key="sourceIdentifier" ref="562071960"/> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <reference key="sourceIdentifier" ref="10957210"/> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSDictionaryController.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSDragging.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <reference key="sourceIdentifier" ref="60454901"/> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSFontPanel.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSKeyValueBinding.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <reference key="sourceIdentifier" ref="687201532"/> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSNibLoading.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSOutlineView.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSPasteboard.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSSavePanel.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier" id="1040540259"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSTableView.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSToolbarItem.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier" id="763667182"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSView.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSArchiver.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSClassDescription.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSError.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSObject.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSObjectScripting.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSPortCoder.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSScriptClassDescription.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSScriptKeyValueCoding.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSScriptObjectSpecifiers.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSScriptWhoseTests.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSThread.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSURL.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">Foundation.framework/Headers/NSURLDownload.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSResponder</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSInterfaceStyle.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSResponder</string> <string key="superclassName">NSObject</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSResponder.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSSearchField</string> <string key="superclassName">NSTextField</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSSearchField.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSSearchFieldCell</string> <string key="superclassName">NSTextFieldCell</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSSearchFieldCell.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSTableView</string> <string key="superclassName">NSControl</string> <reference key="sourceIdentifier" ref="1040540259"/> </object> <object class="IBPartialClassDescription"> <string key="className">NSText</string> <string key="superclassName">NSView</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSText.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSTextField</string> <string key="superclassName">NSControl</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSTextField.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSTextFieldCell</string> <string key="superclassName">NSActionCell</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSTextFieldCell.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSTextView</string> <string key="superclassName">NSText</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSTextView.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSView</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSClipView.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSView</string> <reference key="sourceIdentifier" ref="283337664"/> </object> <object class="IBPartialClassDescription"> <string key="className">NSView</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSRulerView.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSView</string> <string key="superclassName">NSResponder</string> <reference key="sourceIdentifier" ref="763667182"/> </object> <object class="IBPartialClassDescription"> <string key="className">NSWindow</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSDrawer.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSWindow</string> <string key="superclassName">NSResponder</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSWindow.h</string> </object> </object> <object class="IBPartialClassDescription"> <string key="className">NSWindow</string> <object class="IBClassDescriptionSource" key="sourceIdentifier"> <string key="majorKey">IBFrameworkSource</string> <string key="minorKey">AppKit.framework/Headers/NSWindowScripting.h</string> </object> </object> </object> </object> <int key="IBDocument.localizationMode">0</int> <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string> <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies"> <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string> <integer value="1050" key="NS.object.0"/> </object> <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults"> <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string> <integer value="1050" key="NS.object.0"/> </object> <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies"> <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string> <integer value="3000" key="NS.object.0"/> </object> <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool> <string key="IBDocument.LastKnownRelativeProjectPath">../ScintillaTest.xcodeproj</string> <int key="IBDocument.defaultPropertyAccessControl">3</int> <object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSArray" key="dict.sortedKeys"> <bool key="EncodedWithXMLCoder">YES</bool> <string>NSMenuCheckmark</string> <string>NSMenuMixedState</string> </object> <object class="NSMutableArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>{9, 8}</string> <string>{7, 2}</string> </object> </object> </data> </archive> |
Added cocoa/ScintillaTest/Info.plist.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> <string>English</string> <key>CFBundleExecutable</key> <string>${EXECUTABLE_NAME}</string> <key>CFBundleIconFile</key> <string></string> <key>CFBundleIdentifier</key> <string>com.sun.${PRODUCT_NAME:identifier}</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>${PRODUCT_NAME}</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> <string>1.0</string> <key>NSMainNibFile</key> <string>MainMenu</string> <key>NSPrincipalClass</key> <string>NSApplication</string> </dict> </plist> |
Added cocoa/ScintillaTest/Scintilla-Info.plist.
> > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> <string>English</string> <key>CFBundleExecutable</key> <string>${EXECUTABLE_NAME}</string> <key>CFBundleIdentifier</key> <string>com.sun.${PRODUCT_NAME:identifier}</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundlePackageType</key> <string>FMWK</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> <string>1.0</string> </dict> </plist> |
Added cocoa/ScintillaTest/ScintillaTest.xcodeproj/project.pbxproj.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 |
// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58140DA1D0A300B32029 /* MainMenu.xib */; }; 271FA52C0F850BE20033D021 /* AppController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 271FA52B0F850BE20033D021 /* AppController.mm */; }; 2791F4490FC1A8E9009DBCF9 /* TestData.sql in Resources */ = {isa = PBXBuildFile; fileRef = 2791F4480FC1A8E9009DBCF9 /* TestData.sql */; }; 27AF7EC30FC2C351007160EF /* Scintilla.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2744E5EA0FC16BE200E85C33 /* Scintilla.framework */; }; 27AF7ECA0FC2C388007160EF /* Scintilla.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2744E5EA0FC16BE200E85C33 /* Scintilla.framework */; }; 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 2744E5E90FC16BE200E85C33 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2744E5E20FC16BE200E85C33 /* ScintillaFramework.xcodeproj */; proxyType = 2; remoteGlobalIDString = 8DC2EF5B0486A6940098B216; remoteInfo = Scintilla; }; 27AF7EC60FC2C36A007160EF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2744E5E20FC16BE200E85C33 /* ScintillaFramework.xcodeproj */; proxyType = 1; remoteGlobalIDString = 8DC2EF4F0486A6940098B216; remoteInfo = Scintilla; }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ 272133C20F973596006BE49A /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( 27AF7ECA0FC2C388007160EF /* Scintilla.framework in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; }; 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; }; 1DDD58150DA1D0A300B32029 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = "<group>"; }; 271FA52A0F850BE20033D021 /* AppController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppController.h; sourceTree = "<group>"; }; 271FA52B0F850BE20033D021 /* AppController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AppController.mm; sourceTree = "<group>"; wrapsLines = 0; }; 2744E5E20FC16BE200E85C33 /* ScintillaFramework.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ScintillaFramework.xcodeproj; path = ../ScintillaFramework/ScintillaFramework.xcodeproj; sourceTree = SOURCE_ROOT; }; 2791F4480FC1A8E9009DBCF9 /* TestData.sql */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = TestData.sql; sourceTree = "<group>"; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; }; 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; }; 32CA4F630368D1EE00C91783 /* ScintillaTest_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScintillaTest_Prefix.pch; sourceTree = "<group>"; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 8D1107320486CEB800E47090 /* ScintillaTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ScintillaTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 8D11072E0486CEB800E47090 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 27AF7EC30FC2C351007160EF /* Scintilla.framework in Frameworks */, 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 080E96DDFE201D6D7F000001 /* Classes */ = { isa = PBXGroup; children = ( 271FA52A0F850BE20033D021 /* AppController.h */, 271FA52B0F850BE20033D021 /* AppController.mm */, ); name = Classes; sourceTree = "<group>"; }; 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { isa = PBXGroup; children = ( 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, ); name = "Linked Frameworks"; sourceTree = "<group>"; }; 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { isa = PBXGroup; children = ( 29B97324FDCFA39411CA2CEA /* AppKit.framework */, 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */, 29B97325FDCFA39411CA2CEA /* Foundation.framework */, ); name = "Other Frameworks"; sourceTree = "<group>"; }; 19C28FACFE9D520D11CA2CBB /* Products */ = { isa = PBXGroup; children = ( 8D1107320486CEB800E47090 /* ScintillaTest.app */, ); name = Products; sourceTree = "<group>"; }; 2744E5E30FC16BE200E85C33 /* Products */ = { isa = PBXGroup; children = ( 2744E5EA0FC16BE200E85C33 /* Scintilla.framework */, ); name = Products; sourceTree = "<group>"; }; 29B97314FDCFA39411CA2CEA /* ScintillaTest */ = { isa = PBXGroup; children = ( 2744E5E20FC16BE200E85C33 /* ScintillaFramework.xcodeproj */, 080E96DDFE201D6D7F000001 /* Classes */, 29B97315FDCFA39411CA2CEA /* Other Sources */, 29B97317FDCFA39411CA2CEA /* Resources */, 29B97323FDCFA39411CA2CEA /* Frameworks */, 19C28FACFE9D520D11CA2CBB /* Products */, ); name = ScintillaTest; sourceTree = "<group>"; }; 29B97315FDCFA39411CA2CEA /* Other Sources */ = { isa = PBXGroup; children = ( 32CA4F630368D1EE00C91783 /* ScintillaTest_Prefix.pch */, 29B97316FDCFA39411CA2CEA /* main.m */, ); name = "Other Sources"; sourceTree = "<group>"; }; 29B97317FDCFA39411CA2CEA /* Resources */ = { isa = PBXGroup; children = ( 2791F4480FC1A8E9009DBCF9 /* TestData.sql */, 8D1107310486CEB800E47090 /* Info.plist */, 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, 1DDD58140DA1D0A300B32029 /* MainMenu.xib */, ); name = Resources; sourceTree = "<group>"; }; 29B97323FDCFA39411CA2CEA /* Frameworks */ = { isa = PBXGroup; children = ( 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, ); name = Frameworks; sourceTree = "<group>"; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 8D1107260486CEB800E47090 /* ScintillaTest */ = { isa = PBXNativeTarget; buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "ScintillaTest" */; buildPhases = ( 8D1107290486CEB800E47090 /* Resources */, 8D11072C0486CEB800E47090 /* Sources */, 8D11072E0486CEB800E47090 /* Frameworks */, 272133C20F973596006BE49A /* CopyFiles */, ); buildRules = ( ); dependencies = ( 27AF7EC70FC2C36A007160EF /* PBXTargetDependency */, ); name = ScintillaTest; productInstallPath = "$(HOME)/Applications"; productName = ScintillaTest; productReference = 8D1107320486CEB800E47090 /* ScintillaTest.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0450; }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ScintillaTest" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 29B97314FDCFA39411CA2CEA /* ScintillaTest */; projectDirPath = ""; projectReferences = ( { ProductGroup = 2744E5E30FC16BE200E85C33 /* Products */; ProjectRef = 2744E5E20FC16BE200E85C33 /* ScintillaFramework.xcodeproj */; }, ); projectRoot = ""; targets = ( 8D1107260486CEB800E47090 /* ScintillaTest */, ); }; /* End PBXProject section */ /* Begin PBXReferenceProxy section */ 2744E5EA0FC16BE200E85C33 /* Scintilla.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; path = Scintilla.framework; remoteRef = 2744E5E90FC16BE200E85C33 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ 8D1107290486CEB800E47090 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */, 1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */, 2791F4490FC1A8E9009DBCF9 /* TestData.sql in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 8D11072C0486CEB800E47090 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 8D11072D0486CEB800E47090 /* main.m in Sources */, 271FA52C0F850BE20033D021 /* AppController.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 27AF7EC70FC2C36A007160EF /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Scintilla; targetProxy = 27AF7EC60FC2C36A007160EF /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( 089C165DFE840E0CC02AAC07 /* English */, ); name = InfoPlist.strings; sourceTree = "<group>"; }; 1DDD58140DA1D0A300B32029 /* MainMenu.xib */ = { isa = PBXVariantGroup; children = ( 1DDD58150DA1D0A300B32029 /* English */, ); name = MainMenu.xib; sourceTree = "<group>"; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ C01FCF4B08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_DYNAMIC_NO_PIC = NO; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = ScintillaTest_Prefix.pch; GCC_PREPROCESSOR_DEFINITIONS = ( SCI_LEXER, SCI_NAMESPACE, ); HEADER_SEARCH_PATHS = "../..//**"; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Applications"; LIBRARY_SEARCH_PATHS = "$(inherited)"; OTHER_LDFLAGS = ""; PRODUCT_NAME = ScintillaTest; SDKROOT = macosx10.7; USER_HEADER_SEARCH_PATHS = ""; }; name = Debug; }; C01FCF4C08A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = ScintillaTest_Prefix.pch; GCC_PREPROCESSOR_DEFINITIONS = ( SCI_LEXER, SCI_NAMESPACE, ); HEADER_SEARCH_PATHS = "../..//**"; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Applications"; LIBRARY_SEARCH_PATHS = "$(inherited)"; OTHER_LDFLAGS = ""; PRODUCT_NAME = ScintillaTest; SDKROOT = macosx10.7; USER_HEADER_SEARCH_PATHS = ""; }; name = Release; }; C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_OPTIMIZATION_LEVEL = 0; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ""; SDKROOT = macosx10.7; }; name = Debug; }; C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT)"; GCC_C_LANGUAGE_STANDARD = c99; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; OTHER_LDFLAGS = ""; SDKROOT = macosx10.7; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "ScintillaTest" */ = { isa = XCConfigurationList; buildConfigurations = ( C01FCF4B08A954540054247B /* Debug */, C01FCF4C08A954540054247B /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ScintillaTest" */ = { isa = XCConfigurationList; buildConfigurations = ( C01FCF4F08A954540054247B /* Debug */, C01FCF5008A954540054247B /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; } |
Added cocoa/ScintillaTest/ScintillaTest_Prefix.pch.
> > > > > > > |
1 2 3 4 5 6 7 |
// // Prefix header for all source files of the 'ScintillaTest' target in the 'ScintillaTest' project // #ifdef __OBJC__ #import <Cocoa/Cocoa.h> #endif |
Added cocoa/ScintillaTest/TestData.sql.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
-- MySQL Administrator dump 1.4 -- -- ------------------------------------------------------ -- Server version 5.0.45 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI_QUOTES' */; /** * Foldable multiline comment. */ -- { -- Create schema sakila -- } CREATE DATABASE IF NOT EXISTS sakila; USE sakila; DROP TABLE IF EXISTS "sakila"."actor_info"; DROP VIEW IF EXISTS "sakila"."actor_info"; CREATE TABLE "sakila"."actor_info" ( "actor_id" smallint(5) unsigned, "first_name" varchar(45), "last_name" varchar(45), "film_info" varchar(341) ); DROP TABLE IF EXISTS "sakila"."actor"; CREATE TABLE "sakila"."actor" ( "actor_id" smallint(5) unsigned NOT NULL auto_increment, "first_name" varchar(45) NOT NULL, "last_name" varchar(45) NOT NULL, "last_update" timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, PRIMARY KEY ("actor_id"), KEY "idx_actor_last_name" ("last_name") ) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8; INSERT INTO "sakila"."actor" VALUES (1,'PENELOPE','GUINESS','2006-02-15 04:34:33'), (2,'NICK','WAHLBERG','2006-02-15 04:34:33'), (3,'ED','CHASE','2006-02-15 04:34:33'), (4,'JENNIFER','DAVIS','2006-02-15 04:34:33'), (149,'RUSSELL','TEMPLE','2006-02-15 04:34:33'), (150,'JAYNE','NOLTE','2006-02-15 04:34:33'), (151,'GEOFFREY','HESTON','2006-02-15 04:34:33'), (152,'BEN','HARRIS','2006-02-15 04:34:33'), (153,'MINNIE','KILMER','2006-02-15 04:34:33'), (154,'MERYL','GIBSON','2006-02-15 04:34:33'), (155,'IAN','TANDY','2006-02-15 04:34:33'), (156,'FAY','WOOD','2006-02-15 04:34:33'), (157,'GRETA','MALDEN','2006-02-15 04:34:33'), (158,'VIVIEN','BASINGER','2006-02-15 04:34:33'), (159,'LAURA','BRODY','2006-02-15 04:34:33'), (160,'CHRIS','DEPP','2006-02-15 04:34:33'), (161,'HARVEY','HOPE','2006-02-15 04:34:33'), (162,'OPRAH','KILMER','2006-02-15 04:34:33'), (163,'CHRISTOPHER','WEST','2006-02-15 04:34:33'), (164,'HUMPHREY','WILLIS','2006-02-15 04:34:33'), (165,'AL','GARLAND','2006-02-15 04:34:33'), (166,'NICK','DEGENERES','2006-02-15 04:34:33'), (167,'LAURENCE','BULLOCK','2006-02-15 04:34:33'), (168,'WILL','WILSON','2006-02-15 04:34:33'), (169,'KENNETH','HOFFMAN','2006-02-15 04:34:33'), (170,'MENA','HOPPER','2006-02-15 04:34:33'), (171,'OLYMPIA','PFEIFFER','2006-02-15 04:34:33'), (190,'AUDREY','BAILEY','2006-02-15 04:34:33'), (191,'GREGORY','GOODING','2006-02-15 04:34:33'), (192,'JOHN','SUVARI','2006-02-15 04:34:33'), (193,'BURT','TEMPLE','2006-02-15 04:34:33'), (194,'MERYL','ALLEN','2006-02-15 04:34:33'), (195,'JAYNE','SILVERSTONE','2006-02-15 04:34:33'), (196,'BELA','WALKEN','2006-02-15 04:34:33'), (197,'REESE','WEST','2006-02-15 04:34:33'), (198,'MARY','KEITEL','2006-02-15 04:34:33'), (199,'JULIA','FAWCETT','2006-02-15 04:34:33'), (200,'THORA','TEMPLE','2006-02-15 04:34:33'); DROP TRIGGER /*!50030 IF EXISTS */ "sakila"."payment_date"; DELIMITER $$ CREATE DEFINER = "root"@"localhost" TRIGGER "sakila"."payment_date" BEFORE INSERT ON "payment" FOR EACH ROW SET NEW.payment_date = NOW() $$ DELIMITER ; DROP TABLE IF EXISTS "sakila"."sales_by_store"; DROP VIEW IF EXISTS "sakila"."sales_by_store"; CREATE ALGORITHM=UNDEFINED DEFINER="root"@"localhost" SQL SECURITY DEFINER VIEW "sakila"."sales_by_store" AS select concat("c"."city",_utf8',',"cy"."country") AS "store",concat("m"."first_name",_utf8' ',"m"."last_name") AS "manager",sum("p"."amount") AS "total_sales" from ((((((("sakila"."payment" "p" join "sakila"."rental" "r" on(("p"."rental_id" = "r"."rental_id"))) join "sakila"."inventory" "i" on(("r"."inventory_id" = "i"."inventory_id"))) join "sakila"."store" "s" on(("i"."store_id" = "s"."store_id"))) join "sakila"."address" "a" on(("s"."address_id" = "a"."address_id"))) join "sakila"."city" "c" on(("a"."city_id" = "c"."city_id"))) join "sakila"."country" "cy" on(("c"."country_id" = "cy"."country_id"))) join "sakila"."staff" "m" on(("s"."manager_staff_id" = "m"."staff_id"))) group by "s"."store_id" order by "cy"."country","c"."city"; -- -- View structure for view `staff_list` -- CREATE VIEW staff_list AS SELECT s.staff_id AS ID, CONCAT(s.first_name, _utf8' ', s.last_name) AS name, a.address AS address, a.postal_code AS `zip code`, a.phone AS phone, city.city AS city, country.country AS country, s.store_id AS SID FROM staff AS s JOIN address AS a ON s.address_id = a.address_id JOIN city ON a.city_id = city.city_id JOIN country ON city.country_id = country.country_id; -- -- View structure for view `actor_info` -- CREATE DEFINER=CURRENT_USER SQL SECURITY INVOKER VIEW actor_info AS SELECT a.actor_id, a.first_name, a.last_name, GROUP_CONCAT(DISTINCT CONCAT(c.name, ': ', (SELECT GROUP_CONCAT(f.title ORDER BY f.title SEPARATOR ', ') FROM sakila.film f INNER JOIN sakila.film_category fc ON f.film_id = fc.film_id INNER JOIN sakila.film_actor fa ON f.film_id = fa.film_id WHERE fc.category_id = c.category_id AND fa.actor_id = a.actor_id ) ) ORDER BY c.name SEPARATOR '; ') AS film_info FROM sakila.actor a LEFT JOIN sakila.film_actor fa ON a.actor_id = fa.actor_id LEFT JOIN sakila.film_category fc ON fa.film_id = fc.film_id LEFT JOIN sakila.category c ON fc.category_id = c.category_id GROUP BY a.actor_id, a.first_name, a.last_name; DELIMITER $$ CREATE FUNCTION get_customer_balance(p_customer_id INT, p_effective_date DATETIME) RETURNS DECIMAL(5,2) DETERMINISTIC READS SQL DATA BEGIN #OK, WE NEED TO CALCULATE THE CURRENT BALANCE GIVEN A CUSTOMER_ID AND A DATE #THAT WE WANT THE BALANCE TO BE EFFECTIVE FOR. THE BALANCE IS: # 1) RENTAL FEES FOR ALL PREVIOUS RENTALS # 2) ONE DOLLAR FOR EVERY DAY THE PREVIOUS RENTALS ARE OVERDUE # 3) IF A FILM IS MORE THAN RENTAL_DURATION * 2 OVERDUE, CHARGE THE REPLACEMENT_COST # 4) SUBTRACT ALL PAYMENTS MADE BEFORE THE DATE SPECIFIED DECLARE v_rentfees DECIMAL(5,2); #FEES PAID TO RENT THE VIDEOS INITIALLY DECLARE v_overfees INTEGER; #LATE FEES FOR PRIOR RENTALS DECLARE v_payments DECIMAL(5,2); #SUM OF PAYMENTS MADE PREVIOUSLY SELECT IFNULL(SUM(film.rental_rate),0) INTO v_rentfees FROM film, inventory, rental WHERE film.film_id = inventory.film_id AND inventory.inventory_id = rental.inventory_id AND rental.rental_date <= p_effective_date AND rental.customer_id = p_customer_id; SELECT IFNULL(SUM(IF((TO_DAYS(rental.return_date) - TO_DAYS(rental.rental_date)) > film.rental_duration, ((TO_DAYS(rental.return_date) - TO_DAYS(rental.rental_date)) - film.rental_duration),0)),0) INTO v_overfees FROM rental, inventory, film WHERE film.film_id = inventory.film_id AND inventory.inventory_id = rental.inventory_id AND rental.rental_date <= p_effective_date AND rental.customer_id = p_customer_id; SELECT IFNULL(SUM(payment.amount),0) INTO v_payments FROM payment WHERE payment.payment_date <= p_effective_date AND payment.customer_id = p_customer_id; RETURN v_rentfees + v_overfees - v_payments; END $$ DELIMITER ; DELIMITER $$ CREATE FUNCTION inventory_in_stock(p_inventory_id INT) RETURNS BOOLEAN READS SQL DATA BEGIN DECLARE v_rentals INT; DECLARE v_out INT; #AN ITEM IS IN-STOCK IF THERE ARE EITHER NO ROWS IN THE rental TABLE #FOR THE ITEM OR ALL ROWS HAVE return_date POPULATED SELECT COUNT(*) INTO v_rentals FROM rental WHERE inventory_id = p_inventory_id; IF v_rentals = 0 THEN RETURN TRUE; END IF; SELECT COUNT(rental_id) INTO v_out FROM inventory LEFT JOIN rental USING(inventory_id) WHERE inventory.inventory_id = p_inventory_id AND rental.return_date IS NULL; IF v_out > 0 THEN RETURN FALSE; ELSE RETURN TRUE; END IF; END $$ DELIMITER ; |
Added cocoa/ScintillaTest/main.m.
> > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/** * main.m * ScintillaTest * * Created by Mike Lischke on 02.04.09. * Copyright Sun Microsystems, Inc 2009. All rights reserved. * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). */ #import <Cocoa/Cocoa.h> int main(int argc, char *argv[]) { return NSApplicationMain(argc, (const char **) argv); } |
Added cocoa/ScintillaView.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
/** * Declaration of the native Cocoa View that serves as container for the scintilla parts. * * Created by Mike Lischke. * * Copyright 2011, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright 2009, 2011 Sun Microsystems, Inc. All rights reserved. * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). */ #import <Cocoa/Cocoa.h> #import "Platform.h" #import "Scintilla.h" #import "SciLexer.h" #import "InfoBarCommunicator.h" #import "ScintillaCocoa.h" @class ScintillaView; extern NSString *SCIUpdateUINotification; @protocol ScintillaNotificationProtocol - (void)notification: (Scintilla::SCNotification*)notification; @end /** * MarginView draws line numbers and other margins next to the text view. */ @interface MarginView : NSRulerView { @private int marginWidth; ScintillaView *owner; NSMutableArray *currentCursors; } @property (assign) int marginWidth; @property (assign) ScintillaView *owner; - (id)initWithScrollView:(NSScrollView *)aScrollView; @end /** * InnerView is the Cocoa interface to the Scintilla backend. It handles text input and * provides a canvas for painting the output. */ @interface InnerView : NSView <NSTextInput> { @private ScintillaView* mOwner; NSCursor* mCurrentCursor; NSTrackingRectTag mCurrentTrackingRect; // Set when we are in composition mode and partial input is displayed. NSRange mMarkedTextRange; BOOL undoCollectionWasActive; } @property (nonatomic, assign) ScintillaView* owner; - (void) dealloc; - (void) removeMarkedText; - (void) setCursor: (Scintilla::Window::Cursor) cursor; - (BOOL) canUndo; - (BOOL) canRedo; @end @interface ScintillaView : NSView <InfoBarCommunicator> { @private // The back end is kind of a controller and model in one. // It uses the content view for display. Scintilla::ScintillaCocoa* mBackend; // This is the actual content to which the backend renders itself. InnerView* mContent; NSScrollView *scrollView; MarginView *marginView; CGFloat zoomDelta; // Area to display additional controls (e.g. zoom info, caret position, status info). NSView <InfoBarCommunicator>* mInfoBar; BOOL mInfoBarAtTop; int mInitialInfoBarWidth; id<ScintillaNotificationProtocol> mDelegate; } @property (nonatomic, readonly) Scintilla::ScintillaCocoa* backend; @property (nonatomic, assign) id<ScintillaNotificationProtocol> delegate; @property (nonatomic, readonly) NSScrollView *scrollView; - (void) dealloc; - (void) positionSubViews; - (void) sendNotification: (NSString*) notificationName; - (void) notify: (NotificationType) type message: (NSString*) message location: (NSPoint) location value: (float) value; - (void) setCallback: (id <InfoBarCommunicator>) callback; - (void) suspendDrawing: (BOOL) suspend; // Scroller handling - (void) setMarginWidth: (int) width; - (void) scrollerAction: (id) sender; - (InnerView*) content; // NSTextView compatibility layer. - (NSString*) string; - (void) setString: (NSString*) aString; - (void) insertText: (NSString*) aString; - (void) setEditable: (BOOL) editable; - (BOOL) isEditable; - (NSRange) selectedRange; - (NSString*) selectedString; - (void)setFontName: (NSString*) font size: (int) size bold: (BOOL) bold italic: (BOOL) italic; // Native call through to the backend. + (sptr_t) directCall: (ScintillaView*) sender message: (unsigned int) message wParam: (uptr_t) wParam lParam: (sptr_t) lParam; // Back end properties getters and setters. - (void) setGeneralProperty: (int) property parameter: (long) parameter value: (long) value; - (void) setGeneralProperty: (int) property value: (long) value; - (long) getGeneralProperty: (int) property; - (long) getGeneralProperty: (int) property parameter: (long) parameter; - (long) getGeneralProperty: (int) property parameter: (long) parameter extra: (long) extra; - (long) getGeneralProperty: (int) property ref: (const void*) ref; - (void) setColorProperty: (int) property parameter: (long) parameter value: (NSColor*) value; - (void) setColorProperty: (int) property parameter: (long) parameter fromHTML: (NSString*) fromHTML; - (NSColor*) getColorProperty: (int) property parameter: (long) parameter; - (void) setReferenceProperty: (int) property parameter: (long) parameter value: (const void*) value; - (const void*) getReferenceProperty: (int) property parameter: (long) parameter; - (void) setStringProperty: (int) property parameter: (long) parameter value: (NSString*) value; - (NSString*) getStringProperty: (int) property parameter: (long) parameter; - (void) setLexerProperty: (NSString*) name value: (NSString*) value; - (NSString*) getLexerProperty: (NSString*) name; - (void) registerNotifyCallback: (intptr_t) windowid value: (Scintilla::SciNotifyFunc) callback; - (void) setInfoBar: (NSView <InfoBarCommunicator>*) aView top: (BOOL) top; - (void) setStatusText: (NSString*) text; - (BOOL) findAndHighlightText: (NSString*) searchText matchCase: (BOOL) matchCase wholeWord: (BOOL) wholeWord scrollTo: (BOOL) scrollTo wrap: (BOOL) wrap; - (BOOL) findAndHighlightText: (NSString*) searchText matchCase: (BOOL) matchCase wholeWord: (BOOL) wholeWord scrollTo: (BOOL) scrollTo wrap: (BOOL) wrap backwards: (BOOL) backwards; - (int) findAndReplaceText: (NSString*) searchText byText: (NSString*) newText matchCase: (BOOL) matchCase wholeWord: (BOOL) wholeWord doAll: (BOOL) doAll; @end |
Added cocoa/ScintillaView.mm.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 |
/** * Implementation of the native Cocoa View that serves as container for the scintilla parts. * * Created by Mike Lischke. * * Copyright 2011, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright 2009, 2011 Sun Microsystems, Inc. All rights reserved. * This file is dual licensed under LGPL v2.1 and the Scintilla license (http://www.scintilla.org/License.txt). */ #import "ScintillaView.h" using namespace Scintilla; // Two additional cursors we need, which aren't provided by Cocoa. static NSCursor* reverseArrowCursor; static NSCursor* waitCursor; // The scintilla indicator used for keyboard input. #define INPUT_INDICATOR INDIC_MAX - 1 NSString *SCIUpdateUINotification = @"SCIUpdateUI"; /** * Provide an NSCursor object that matches the Window::Cursor enumeration. */ static NSCursor *cursorFromEnum(Window::Cursor cursor) { switch (cursor) { case Window::cursorText: return [NSCursor IBeamCursor]; case Window::cursorArrow: return [NSCursor arrowCursor]; case Window::cursorWait: return waitCursor; case Window::cursorHoriz: return [NSCursor resizeLeftRightCursor]; case Window::cursorVert: return [NSCursor resizeUpDownCursor]; case Window::cursorReverseArrow: return reverseArrowCursor; case Window::cursorUp: default: return [NSCursor arrowCursor]; } } @implementation MarginView @synthesize marginWidth, owner; - (id)initWithScrollView:(NSScrollView *)aScrollView { self = [super initWithScrollView:aScrollView orientation:NSVerticalRuler]; if (self != nil) { owner = nil; marginWidth = 20; currentCursors = [[NSMutableArray arrayWithCapacity:0] retain]; for (size_t i=0; i<5; i++) { [currentCursors addObject: [reverseArrowCursor retain]]; } [self setClientView:[aScrollView documentView]]; } return self; } - (void) dealloc { [currentCursors release]; [super dealloc]; } - (void) setFrame: (NSRect) frame { [super setFrame: frame]; [[self window] invalidateCursorRectsForView: self]; } - (CGFloat)requiredThickness { return marginWidth; } - (void)drawHashMarksAndLabelsInRect:(NSRect)aRect { if (owner) { NSRect contentRect = [[[self scrollView] contentView] bounds]; NSRect marginRect = [self bounds]; // Ensure paint to bottom of view to avoid glitches if (marginRect.size.height > contentRect.size.height) { // Legacy scroll bar mode leaves a poorly painted corner aRect = marginRect; } owner.backend->PaintMargin(aRect); } } - (void) mouseDown: (NSEvent *) theEvent { owner.backend->MouseDown(theEvent); } - (void) mouseDragged: (NSEvent *) theEvent { owner.backend->MouseMove(theEvent); } - (void) mouseMoved: (NSEvent *) theEvent { owner.backend->MouseMove(theEvent); } - (void) mouseUp: (NSEvent *) theEvent { owner.backend->MouseUp(theEvent); } /** * This method is called to give us the opportunity to define our mouse sensitive rectangle. */ - (void) resetCursorRects { [super resetCursorRects]; int x = 0; NSRect marginRect = [self bounds]; size_t co = [currentCursors count]; for (size_t i=0; i<co; i++) { int cursType = owner.backend->WndProc(SCI_GETMARGINCURSORN, i, 0); int width =owner.backend->WndProc(SCI_GETMARGINWIDTHN, i, 0); NSCursor *cc = cursorFromEnum(static_cast<Window::Cursor>(cursType)); [currentCursors replaceObjectAtIndex:i withObject: cc]; marginRect.origin.x = x; marginRect.size.width = width; [self addCursorRect: marginRect cursor: cc]; [cc setOnMouseEntered: YES]; x += width; } } @end @implementation InnerView @synthesize owner = mOwner; //-------------------------------------------------------------------------------------------------- - (NSView*) initWithFrame: (NSRect) frame { self = [super initWithFrame: frame]; if (self != nil) { // Some initialization for our view. mCurrentCursor = [[NSCursor arrowCursor] retain]; mCurrentTrackingRect = 0; mMarkedTextRange = NSMakeRange(NSNotFound, 0); [self registerForDraggedTypes: [NSArray arrayWithObjects: NSStringPboardType, ScintillaRecPboardType, NSFilenamesPboardType, nil]]; } return self; } //-------------------------------------------------------------------------------------------------- /** * When the view is resized we need to update our tracking rectangle and let the backend know. */ - (void) setFrame: (NSRect) frame { [super setFrame: frame]; // Make the content also a tracking rectangle for mouse events. if (mCurrentTrackingRect != 0) [self removeTrackingRect: mCurrentTrackingRect]; mCurrentTrackingRect = [self addTrackingRect: [self bounds] owner: self userData: nil assumeInside: YES]; mOwner.backend->Resize(); } //-------------------------------------------------------------------------------------------------- /** * Called by the backend if a new cursor must be set for the view. */ - (void) setCursor: (Window::Cursor) cursor { [mCurrentCursor autorelease]; mCurrentCursor = cursorFromEnum(cursor); [mCurrentCursor retain]; // Trigger recreation of the cursor rectangle(s). [[self window] invalidateCursorRectsForView: self]; } //-------------------------------------------------------------------------------------------------- /** * This method is called to give us the opportunity to define our mouse sensitive rectangle. */ - (void) resetCursorRects { [super resetCursorRects]; // We only have one cursor rect: our bounds. [self addCursorRect: [self bounds] cursor: mCurrentCursor]; [mCurrentCursor setOnMouseEntered: YES]; } //-------------------------------------------------------------------------------------------------- /** * Gets called by the runtime when the view needs repainting. */ - (void) drawRect: (NSRect) rect { CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; if (!mOwner.backend->Draw(rect, context)) { dispatch_async(dispatch_get_main_queue(), ^{ [self setNeedsDisplay:YES]; }); } } //-------------------------------------------------------------------------------------------------- /** * Windows uses a client coordinate system where the upper left corner is the origin in a window * (and so does Scintilla). We have to adjust for that. However by returning YES here, we are * already done with that. * Note that because of returning YES here most coordinates we use now (e.g. for painting, * invalidating rectangles etc.) are given with +Y pointing down! */ - (BOOL) isFlipped { return YES; } //-------------------------------------------------------------------------------------------------- - (BOOL) isOpaque { return YES; } //-------------------------------------------------------------------------------------------------- /** * Implement the "click through" behavior by telling the caller we accept the first mouse event too. */ - (BOOL) acceptsFirstMouse: (NSEvent *) theEvent { #pragma unused(theEvent) return YES; } //-------------------------------------------------------------------------------------------------- /** * Make this view accepting events as first responder. */ - (BOOL) acceptsFirstResponder { return YES; } //-------------------------------------------------------------------------------------------------- /** * Called by the framework if it wants to show a context menu for the editor. */ - (NSMenu*) menuForEvent: (NSEvent*) theEvent { if (![mOwner respondsToSelector: @selector(menuForEvent:)]) return mOwner.backend->CreateContextMenu(theEvent); else return [mOwner menuForEvent: theEvent]; } //-------------------------------------------------------------------------------------------------- // Adoption of NSTextInput protocol. - (NSAttributedString*) attributedSubstringFromRange: (NSRange) range { return nil; } //-------------------------------------------------------------------------------------------------- - (NSUInteger) characterIndexForPoint: (NSPoint) point { return NSNotFound; } //-------------------------------------------------------------------------------------------------- - (NSInteger) conversationIdentifier { return (NSInteger) self; } //-------------------------------------------------------------------------------------------------- - (void) doCommandBySelector: (SEL) selector { if ([self respondsToSelector: @selector(selector)]) [self performSelector: selector withObject: nil]; } //-------------------------------------------------------------------------------------------------- - (NSRect) firstRectForCharacterRange: (NSRange) range { return NSZeroRect; } //-------------------------------------------------------------------------------------------------- - (BOOL) hasMarkedText { return mMarkedTextRange.length > 0; } //-------------------------------------------------------------------------------------------------- /** * General text input. Used to insert new text at the current input position, replacing the current * selection if there is any. */ - (void) insertText: (id) aString { // Remove any previously marked text first. [self removeMarkedText]; NSString* newText = @""; if ([aString isKindOfClass:[NSString class]]) newText = (NSString*) aString; else if ([aString isKindOfClass:[NSAttributedString class]]) newText = (NSString*) [aString string]; mOwner.backend->InsertText(newText); } //-------------------------------------------------------------------------------------------------- - (NSRange) markedRange { return mMarkedTextRange; } //-------------------------------------------------------------------------------------------------- - (NSRange) selectedRange { long begin = [mOwner getGeneralProperty: SCI_GETSELECTIONSTART parameter: 0]; long end = [mOwner getGeneralProperty: SCI_GETSELECTIONEND parameter: 0]; return NSMakeRange(begin, end - begin); } //-------------------------------------------------------------------------------------------------- /** * Called by the input manager to set text which might be combined with further input to form * the final text (e.g. composition of ^ and a to â). * * @param aString The text to insert, either what has been marked already or what is selected already * or simply added at the current insertion point. Depending on what is available. * @param range The range of the new text to select (given relative to the insertion point of the new text). */ - (void) setMarkedText: (id) aString selectedRange: (NSRange) range { NSString* newText = @""; if ([aString isKindOfClass:[NSString class]]) newText = (NSString*) aString; else if ([aString isKindOfClass:[NSAttributedString class]]) newText = (NSString*) [aString string]; long currentPosition = [mOwner getGeneralProperty: SCI_GETCURRENTPOS parameter: 0]; // Replace marked text if there is one. if (mMarkedTextRange.length > 0) { [mOwner setGeneralProperty: SCI_SETSELECTIONSTART value: mMarkedTextRange.location]; [mOwner setGeneralProperty: SCI_SETSELECTIONEND value: mMarkedTextRange.location + mMarkedTextRange.length]; currentPosition = mMarkedTextRange.location; } // Keep Scintilla from collecting undo actions for the composition task. undoCollectionWasActive = [mOwner getGeneralProperty: SCI_GETUNDOCOLLECTION] != 0; [mOwner setGeneralProperty: SCI_SETUNDOCOLLECTION value: 0]; // Note: Scintilla internally works almost always with bytes instead chars, so we need to take // this into account when determining selection ranges and such. std::string raw_text = [newText UTF8String]; int lengthInserted = mOwner.backend->InsertText(newText); mMarkedTextRange.location = currentPosition; mMarkedTextRange.length = lengthInserted; if (lengthInserted > 0) { // Mark the just inserted text. Keep the marked range for later reset. [mOwner setGeneralProperty: SCI_SETINDICATORCURRENT value: INPUT_INDICATOR]; [mOwner setGeneralProperty: SCI_INDICATORFILLRANGE parameter: mMarkedTextRange.location value: mMarkedTextRange.length]; } else { // Re-enable undo action collection if composition ended (indicated by an empty mark string). if (undoCollectionWasActive) [mOwner setGeneralProperty: SCI_SETUNDOCOLLECTION value: range.length == 0]; } // Select the part which is indicated in the given range. It does not scroll the caret into view. if (range.length > 0) { [mOwner setGeneralProperty: SCI_SETSELECTIONSTART value: currentPosition + range.location]; [mOwner setGeneralProperty: SCI_SETSELECTIONEND value: currentPosition + range.location + range.length]; } } //-------------------------------------------------------------------------------------------------- - (void) unmarkText { if (mMarkedTextRange.length > 0) { [mOwner setGeneralProperty: SCI_SETINDICATORCURRENT value: INPUT_INDICATOR]; [mOwner setGeneralProperty: SCI_INDICATORCLEARRANGE parameter: mMarkedTextRange.location value: mMarkedTextRange.length]; mMarkedTextRange = NSMakeRange(NSNotFound, 0); // Reenable undo action collection, after we are done with text composition. if (undoCollectionWasActive) [mOwner setGeneralProperty: SCI_SETUNDOCOLLECTION value: 1]; } } //-------------------------------------------------------------------------------------------------- /** * Removes any currently marked text. */ - (void) removeMarkedText { if (mMarkedTextRange.length > 0) { // We have already marked text. Replace that. [mOwner setGeneralProperty: SCI_SETSELECTIONSTART value: mMarkedTextRange.location]; [mOwner setGeneralProperty: SCI_SETSELECTIONEND value: mMarkedTextRange.location + mMarkedTextRange.length]; mOwner.backend->InsertText(@""); mMarkedTextRange = NSMakeRange(NSNotFound, 0); // Reenable undo action collection, after we are done with text composition. if (undoCollectionWasActive) [mOwner setGeneralProperty: SCI_SETUNDOCOLLECTION value: 1]; } } //-------------------------------------------------------------------------------------------------- - (NSArray*) validAttributesForMarkedText { return nil; } // End of the NSTextInput protocol adoption. //-------------------------------------------------------------------------------------------------- /** * Generic input method. It is used to pass on keyboard input to Scintilla. The control itself only * handles shortcuts. The input is then forwarded to the Cocoa text input system, which in turn does * its own input handling (character composition via NSTextInput protocol): */ - (void) keyDown: (NSEvent *) theEvent { if (mMarkedTextRange.length == 0) mOwner.backend->KeyboardInput(theEvent); NSArray* events = [NSArray arrayWithObject: theEvent]; [self interpretKeyEvents: events]; } //-------------------------------------------------------------------------------------------------- - (void) mouseDown: (NSEvent *) theEvent { mOwner.backend->MouseDown(theEvent); } //-------------------------------------------------------------------------------------------------- - (void) mouseDragged: (NSEvent *) theEvent { mOwner.backend->MouseMove(theEvent); } //-------------------------------------------------------------------------------------------------- - (void) mouseUp: (NSEvent *) theEvent { mOwner.backend->MouseUp(theEvent); } //-------------------------------------------------------------------------------------------------- - (void) mouseMoved: (NSEvent *) theEvent { mOwner.backend->MouseMove(theEvent); } //-------------------------------------------------------------------------------------------------- - (void) mouseEntered: (NSEvent *) theEvent { mOwner.backend->MouseEntered(theEvent); } //-------------------------------------------------------------------------------------------------- - (void) mouseExited: (NSEvent *) theEvent { mOwner.backend->MouseExited(theEvent); } //-------------------------------------------------------------------------------------------------- /** * Mouse wheel with command key magnifies text. */ - (void) scrollWheel: (NSEvent *) theEvent { if (([theEvent modifierFlags] & NSCommandKeyMask) != 0) { mOwner.backend->MouseWheel(theEvent); } else { [super scrollWheel:theEvent]; } } //-------------------------------------------------------------------------------------------------- /** * Ensure scrolling is aligned to whole lines instead of starting part-way through a line */ - (NSRect)adjustScroll:(NSRect)proposedVisibleRect { NSRect rc = proposedVisibleRect; // Snap to lines NSRect contentRect = [self bounds]; if ((rc.origin.y > 0) && (NSMaxY(rc) < contentRect.size.height)) { // Only snap for positions inside the document - allow outside // for overshoot. int lineHeight = mOwner.backend->WndProc(SCI_TEXTHEIGHT, 0, 0); rc.origin.y = roundf(rc.origin.y / lineHeight) * lineHeight; } return rc; } //-------------------------------------------------------------------------------------------------- /** * The editor is getting the foreground control (the one getting the input focus). */ - (BOOL) becomeFirstResponder { mOwner.backend->WndProc(SCI_SETFOCUS, 1, 0); return YES; } //-------------------------------------------------------------------------------------------------- /** * The editor is losing the input focus. */ - (BOOL) resignFirstResponder { mOwner.backend->WndProc(SCI_SETFOCUS, 0, 0); return YES; } //-------------------------------------------------------------------------------------------------- /** * Called when an external drag operation enters the view. */ - (NSDragOperation) draggingEntered: (id <NSDraggingInfo>) sender { return mOwner.backend->DraggingEntered(sender); } //-------------------------------------------------------------------------------------------------- /** * Called frequently during an external drag operation if we are the target. */ - (NSDragOperation) draggingUpdated: (id <NSDraggingInfo>) sender { return mOwner.backend->DraggingUpdated(sender); } //-------------------------------------------------------------------------------------------------- /** * Drag image left the view. Clean up if necessary. */ - (void) draggingExited: (id <NSDraggingInfo>) sender { mOwner.backend->DraggingExited(sender); } //-------------------------------------------------------------------------------------------------- - (BOOL) prepareForDragOperation: (id <NSDraggingInfo>) sender { #pragma unused(sender) return YES; } //-------------------------------------------------------------------------------------------------- - (BOOL) performDragOperation: (id <NSDraggingInfo>) sender { return mOwner.backend->PerformDragOperation(sender); } //-------------------------------------------------------------------------------------------------- /** * Returns operations we allow as drag source. */ - (NSDragOperation) draggingSourceOperationMaskForLocal: (BOOL) flag { return NSDragOperationCopy | NSDragOperationMove | NSDragOperationDelete; } //-------------------------------------------------------------------------------------------------- /** * Finished a drag: may need to delete selection. */ - (void)draggedImage:(NSImage *)image endedAt:(NSPoint)screenPoint operation:(NSDragOperation)operation { if (operation == NSDragOperationDelete) { mOwner.backend->WndProc(SCI_CLEAR, 0, 0); } } //-------------------------------------------------------------------------------------------------- /** * Drag operation is done. Notify editor. */ - (void) concludeDragOperation: (id <NSDraggingInfo>) sender { // Clean up is the same as if we are no longer the drag target. mOwner.backend->DraggingExited(sender); } //-------------------------------------------------------------------------------------------------- // NSResponder actions. - (void) selectAll: (id) sender { #pragma unused(sender) mOwner.backend->SelectAll(); } - (void) deleteBackward: (id) sender { #pragma unused(sender) mOwner.backend->DeleteBackward(); } - (void) cut: (id) sender { #pragma unused(sender) mOwner.backend->Cut(); } - (void) copy: (id) sender { #pragma unused(sender) mOwner.backend->Copy(); } - (void) paste: (id) sender { #pragma unused(sender) mOwner.backend->Paste(); } - (void) undo: (id) sender { #pragma unused(sender) mOwner.backend->Undo(); } - (void) redo: (id) sender { #pragma unused(sender) mOwner.backend->Redo(); } - (BOOL) canUndo { return mOwner.backend->CanUndo(); } - (BOOL) canRedo { return mOwner.backend->CanRedo(); } - (BOOL) isEditable { return mOwner.backend->WndProc(SCI_GETREADONLY, 0, 0) == 0; } //-------------------------------------------------------------------------------------------------- - (void) dealloc { [mCurrentCursor release]; [super dealloc]; } @end //-------------------------------------------------------------------------------------------------- @implementation ScintillaView @synthesize backend = mBackend; @synthesize delegate = mDelegate; @synthesize scrollView; /** * ScintillaView is a composite control made from an NSView and an embedded NSView that is * used as canvas for the output (by the backend, using its CGContext), plus other elements * (scrollers, info bar). */ //-------------------------------------------------------------------------------------------------- /** * Initialize custom cursor. */ + (void) initialize { if (self == [ScintillaView class]) { NSBundle* bundle = [NSBundle bundleForClass: [ScintillaView class]]; NSString* path = [bundle pathForResource: @"mac_cursor_busy" ofType: @"png" inDirectory: nil]; NSImage* image = [[[NSImage alloc] initWithContentsOfFile: path] autorelease]; waitCursor = [[NSCursor alloc] initWithImage: image hotSpot: NSMakePoint(2, 2)]; path = [bundle pathForResource: @"mac_cursor_flipped" ofType: @"png" inDirectory: nil]; image = [[[NSImage alloc] initWithContentsOfFile: path] autorelease]; reverseArrowCursor = [[NSCursor alloc] initWithImage: image hotSpot: NSMakePoint(12, 2)]; } } //-------------------------------------------------------------------------------------------------- /** * Receives zoom messages, for example when a "pinch zoom" is performed on the trackpad. */ - (void) magnifyWithEvent: (NSEvent *) event { #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 zoomDelta += event.magnification * 10.0; if (fabsf(zoomDelta)>=1.0) { long zoomFactor = [self getGeneralProperty: SCI_GETZOOM] + zoomDelta; [self setGeneralProperty: SCI_SETZOOM parameter: zoomFactor value:0]; zoomDelta = 0.0; } #endif } - (void) beginGestureWithEvent: (NSEvent *) event { zoomDelta = 0.0; } //-------------------------------------------------------------------------------------------------- /** * Sends a new notification of the given type to the default notification center. */ - (void) sendNotification: (NSString*) notificationName { NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; [center postNotificationName: notificationName object: self]; } //-------------------------------------------------------------------------------------------------- /** * Called by a connected component (usually the info bar) if something changed there. * * @param type The type of the notification. * @param message Carries the new status message if the type is a status message change. * @param location Carries the new location (e.g. caret) if the type is a caret change or similar type. * @param location Carries the new zoom value if the type is a zoom change. */ - (void) notify: (NotificationType) type message: (NSString*) message location: (NSPoint) location value: (float) value { switch (type) { case IBNZoomChanged: { // Compute point increase/decrease based on default font size. long fontSize = [self getGeneralProperty: SCI_STYLEGETSIZE parameter: STYLE_DEFAULT]; int zoom = (int) (fontSize * (value - 1)); [self setGeneralProperty: SCI_SETZOOM value: zoom]; break; } default: break; }; } //-------------------------------------------------------------------------------------------------- - (void) setCallback: (id <InfoBarCommunicator>) callback { // Not used. Only here to satisfy protocol. } //-------------------------------------------------------------------------------------------------- /** * Prevents drawing of the inner view to avoid flickering when doing many visual updates * (like clearing all marks and setting new ones etc.). */ - (void) suspendDrawing: (BOOL) suspend { if (suspend) [[self window] disableFlushWindow]; else [[self window] enableFlushWindow]; } //-------------------------------------------------------------------------------------------------- /** * Notification function used by Scintilla to call us back (e.g. for handling clicks on the * folder margin or changes in the editor). * A delegate can be set to receive all notifications. If set no handling takes place here, except * for action pertaining to internal stuff (like the info bar). */ static void notification(intptr_t windowid, unsigned int iMessage, uintptr_t wParam, uintptr_t lParam) { // WM_NOTIFY means we got a parent notification with a special notification structure. // Here we don't really differentiate between parent and own notifications and handle both. ScintillaView* editor; switch (iMessage) { case WM_NOTIFY: { // Parent notification. Details are passed as SCNotification structure. SCNotification* scn = reinterpret_cast<SCNotification*>(lParam); ScintillaCocoa *psc = reinterpret_cast<ScintillaCocoa*>(scn->nmhdr.hwndFrom); editor = reinterpret_cast<InnerView*>(psc->ContentView()).owner; if (editor.delegate != nil) { [editor.delegate notification: scn]; if (scn->nmhdr.code != SCN_ZOOM && scn->nmhdr.code != SCN_UPDATEUI) return; } switch (scn->nmhdr.code) { case SCN_MARGINCLICK: { if (scn->margin == 2) { // Click on the folder margin. Toggle the current line if possible. long line = [editor getGeneralProperty: SCI_LINEFROMPOSITION parameter: scn->position]; [editor setGeneralProperty: SCI_TOGGLEFOLD value: line]; } break; }; case SCN_MODIFIED: { // Decide depending on the modification type what to do. // There can be more than one modification carried by one notification. if (scn->modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT)) [editor sendNotification: NSTextDidChangeNotification]; break; } case SCN_ZOOM: { // A zoom change happend. Notify info bar if there is one. float zoom = [editor getGeneralProperty: SCI_GETZOOM parameter: 0]; long fontSize = [editor getGeneralProperty: SCI_STYLEGETSIZE parameter: STYLE_DEFAULT]; float factor = (zoom / fontSize) + 1; [editor->mInfoBar notify: IBNZoomChanged message: nil location: NSZeroPoint value: factor]; break; } case SCN_UPDATEUI: { // Triggered whenever changes in the UI state need to be reflected. // These can be: caret changes, selection changes etc. NSPoint caretPosition = editor->mBackend->GetCaretPosition(); [editor->mInfoBar notify: IBNCaretChanged message: nil location: caretPosition value: 0]; [editor sendNotification: SCIUpdateUINotification]; [editor sendNotification: NSTextViewDidChangeSelectionNotification]; break; } } break; } case WM_COMMAND: { // Notifications for the editor itself. ScintillaCocoa* backend = reinterpret_cast<ScintillaCocoa*>(lParam); editor = backend->TopContainer(); switch (wParam >> 16) { case SCEN_KILLFOCUS: [editor sendNotification: NSTextDidEndEditingNotification]; break; case SCEN_SETFOCUS: // Nothing to do for now. break; } break; } }; } //-------------------------------------------------------------------------------------------------- /** * Initialization of the view. Used to setup a few other things we need. */ - (id) initWithFrame: (NSRect) frame { self = [super initWithFrame:frame]; if (self) { mContent = [[[InnerView alloc] init] autorelease]; mContent.owner = self; // Initialize the scrollers but don't show them yet. // Pick an arbitrary size, just to make NSScroller selecting the proper scroller direction // (horizontal or vertical). NSRect scrollerRect = NSMakeRect(0, 0, 100, 10); scrollView = [[[NSScrollView alloc] initWithFrame: scrollerRect] autorelease]; [scrollView setDocumentView: mContent]; [scrollView setHasVerticalScroller:YES]; [scrollView setHasHorizontalScroller:YES]; [scrollView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; //[scrollView setScrollerStyle:NSScrollerStyleLegacy]; //[scrollView setScrollerKnobStyle:NSScrollerKnobStyleDark]; //[scrollView setHorizontalScrollElasticity:NSScrollElasticityNone]; [self addSubview: scrollView]; marginView = [[MarginView alloc] initWithScrollView:scrollView]; marginView.owner = self; [marginView setRuleThickness:[marginView requiredThickness]]; [scrollView setVerticalRulerView:marginView]; [scrollView setHasHorizontalRuler:NO]; [scrollView setHasVerticalRuler:YES]; [scrollView setRulersVisible:YES]; mBackend = new ScintillaCocoa(mContent, marginView); // Establish a connection from the back end to this container so we can handle situations // which require our attention. mBackend->RegisterNotifyCallback(nil, notification); // Setup a special indicator used in the editor to provide visual feedback for // input composition, depending on language, keyboard etc. [self setColorProperty: SCI_INDICSETFORE parameter: INPUT_INDICATOR fromHTML: @"#FF0000"]; [self setGeneralProperty: SCI_INDICSETUNDER parameter: INPUT_INDICATOR value: 1]; [self setGeneralProperty: SCI_INDICSETSTYLE parameter: INPUT_INDICATOR value: INDIC_PLAIN]; [self setGeneralProperty: SCI_INDICSETALPHA parameter: INPUT_INDICATOR value: 100]; NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(applicationDidResignActive:) name:NSApplicationDidResignActiveNotification object:nil]; [center addObserver:self selector:@selector(applicationDidBecomeActive:) name:NSApplicationDidBecomeActiveNotification object:nil]; [[scrollView contentView] setPostsBoundsChangedNotifications:YES]; [center addObserver:self selector:@selector(scrollerAction:) name:NSViewBoundsDidChangeNotification object:[scrollView contentView]]; } return self; } //-------------------------------------------------------------------------------------------------- - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; delete mBackend; [super dealloc]; } //-------------------------------------------------------------------------------------------------- - (void) applicationDidResignActive: (NSNotification *)note { #pragma unused(note) mBackend->ActiveStateChanged(false); } //-------------------------------------------------------------------------------------------------- - (void) applicationDidBecomeActive: (NSNotification *)note { #pragma unused(note) mBackend->ActiveStateChanged(true); } //-------------------------------------------------------------------------------------------------- - (void) viewDidMoveToWindow { [super viewDidMoveToWindow]; [self positionSubViews]; // Enable also mouse move events for our window (and so this view). [[self window] setAcceptsMouseMovedEvents: YES]; } //-------------------------------------------------------------------------------------------------- /** * Used to position and size the parts of the editor (content, scrollers, info bar). */ - (void) positionSubViews { int scrollerWidth = [NSScroller scrollerWidth]; NSSize size = [self frame].size; NSRect barFrame = {0, size.height - scrollerWidth, size.width, static_cast<CGFloat>(scrollerWidth)}; BOOL infoBarVisible = mInfoBar != nil && ![mInfoBar isHidden]; // Horizontal offset of the content. Almost always 0 unless the vertical scroller // is on the left side. int contentX = 0; NSRect scrollRect = {contentX, 0, size.width, size.height}; // Info bar frame. if (infoBarVisible) { scrollRect.size.height -= scrollerWidth; // Initial value already is as if the bar is at top. if (!mInfoBarAtTop) { scrollRect.origin.y += scrollerWidth; barFrame.origin.y = 0; } } if (!NSEqualRects([scrollView frame], scrollRect)) { [scrollView setFrame: scrollRect]; } if (infoBarVisible) [mInfoBar setFrame: barFrame]; } //-------------------------------------------------------------------------------------------------- /** * Set the width of the margin. */ - (void) setMarginWidth: (int) width { if (marginView.ruleThickness != width) { marginView.marginWidth = width; [marginView setRuleThickness:[marginView requiredThickness]]; } } //-------------------------------------------------------------------------------------------------- /** * Triggered by one of the scrollers when it gets manipulated by the user. Notify the backend * about the change. */ - (void) scrollerAction: (id) sender { mBackend->UpdateForScroll(); } //-------------------------------------------------------------------------------------------------- /** * Used to reposition our content depending on the size of the view. */ - (void) setFrame: (NSRect) newFrame { NSRect previousFrame = [self frame]; [super setFrame: newFrame]; [self positionSubViews]; if (!NSEqualRects(previousFrame, newFrame)) { mBackend->Resize(); } } //-------------------------------------------------------------------------------------------------- /** * Getter for the currently selected text in raw form (no formatting information included). * If there is no text available an empty string is returned. */ - (NSString*) selectedString { NSString *result = @""; char *buffer(0); const long length = mBackend->WndProc(SCI_GETSELTEXT, 0, 0); if (length > 0) { buffer = new char[length + 1]; try { mBackend->WndProc(SCI_GETSELTEXT, length + 1, (sptr_t) buffer); result = [NSString stringWithUTF8String: buffer]; delete[] buffer; } catch (...) { delete[] buffer; buffer = 0; } } return result; } //-------------------------------------------------------------------------------------------------- /** * Getter for the current text in raw form (no formatting information included). * If there is no text available an empty string is returned. */ - (NSString*) string { NSString *result = @""; char *buffer(0); const long length = mBackend->WndProc(SCI_GETLENGTH, 0, 0); if (length > 0) { buffer = new char[length + 1]; try { mBackend->WndProc(SCI_GETTEXT, length + 1, (sptr_t) buffer); result = [NSString stringWithUTF8String: buffer]; delete[] buffer; } catch (...) { delete[] buffer; buffer = 0; } } return result; } //-------------------------------------------------------------------------------------------------- /** * Setter for the current text (no formatting included). */ - (void) setString: (NSString*) aString { const char* text = [aString UTF8String]; mBackend->WndProc(SCI_SETTEXT, 0, (long) text); } //-------------------------------------------------------------------------------------------------- - (void) insertString: (NSString*) aString atOffset: (int)offset { const char* text = [aString UTF8String]; mBackend->WndProc(SCI_ADDTEXT, offset, (long) text); } //-------------------------------------------------------------------------------------------------- - (void) setEditable: (BOOL) editable { mBackend->WndProc(SCI_SETREADONLY, editable ? 0 : 1, 0); } //-------------------------------------------------------------------------------------------------- - (BOOL) isEditable { return mBackend->WndProc(SCI_GETREADONLY, 0, 0) == 0; } //-------------------------------------------------------------------------------------------------- - (InnerView*) content { return mContent; } //-------------------------------------------------------------------------------------------------- /** * Direct call into the backend to allow uninterpreted access to it. The values to be passed in and * the result heavily depend on the message that is used for the call. Refer to the Scintilla * documentation to learn what can be used here. */ + (sptr_t) directCall: (ScintillaView*) sender message: (unsigned int) message wParam: (uptr_t) wParam lParam: (sptr_t) lParam { return ScintillaCocoa::DirectFunction(sender->mBackend, message, wParam, lParam); } //-------------------------------------------------------------------------------------------------- /** * This is a helper method to set properties in the backend, with native parameters. * * @param property Main property like SCI_STYLESETFORE for which a value is to be set. * @param parameter Additional info for this property like a parameter or index. * @param value The actual value. It depends on the property what this parameter means. */ - (void) setGeneralProperty: (int) property parameter: (long) parameter value: (long) value { mBackend->WndProc(property, parameter, value); } //-------------------------------------------------------------------------------------------------- /** * A simplified version for setting properties which only require one parameter. * * @param property Main property like SCI_STYLESETFORE for which a value is to be set. * @param value The actual value. It depends on the property what this parameter means. */ - (void) setGeneralProperty: (int) property value: (long) value { mBackend->WndProc(property, value, 0); } //-------------------------------------------------------------------------------------------------- /** * This is a helper method to get a property in the backend, with native parameters. * * @param property Main property like SCI_STYLESETFORE for which a value is to get. * @param parameter Additional info for this property like a parameter or index. * @param extra Yet another parameter if needed. * @result A generic value which must be interpreted depending on the property queried. */ - (long) getGeneralProperty: (int) property parameter: (long) parameter extra: (long) extra { return mBackend->WndProc(property, parameter, extra); } //-------------------------------------------------------------------------------------------------- /** * Convenience function to avoid unneeded extra parameter. */ - (long) getGeneralProperty: (int) property parameter: (long) parameter { return mBackend->WndProc(property, parameter, 0); } //-------------------------------------------------------------------------------------------------- /** * Convenience function to avoid unneeded parameters. */ - (long) getGeneralProperty: (int) property { return mBackend->WndProc(property, 0, 0); } //-------------------------------------------------------------------------------------------------- /** * Use this variant if you have to pass in a reference to something (e.g. a text range). */ - (long) getGeneralProperty: (int) property ref: (const void*) ref { return mBackend->WndProc(property, 0, (sptr_t) ref); } //-------------------------------------------------------------------------------------------------- /** * Specialized property setter for colors. */ - (void) setColorProperty: (int) property parameter: (long) parameter value: (NSColor*) value { if ([value colorSpaceName] != NSDeviceRGBColorSpace) value = [value colorUsingColorSpaceName: NSDeviceRGBColorSpace]; long red = [value redComponent] * 255; long green = [value greenComponent] * 255; long blue = [value blueComponent] * 255; long color = (blue << 16) + (green << 8) + red; mBackend->WndProc(property, parameter, color); } //-------------------------------------------------------------------------------------------------- /** * Another color property setting, which allows to specify the color as string like in HTML * documents (i.e. with leading # and either 3 hex digits or 6). */ - (void) setColorProperty: (int) property parameter: (long) parameter fromHTML: (NSString*) fromHTML { if ([fromHTML length] > 3 && [fromHTML characterAtIndex: 0] == '#') { bool longVersion = [fromHTML length] > 6; int index = 1; char value[3] = {0, 0, 0}; value[0] = [fromHTML characterAtIndex: index++]; if (longVersion) value[1] = [fromHTML characterAtIndex: index++]; else value[1] = value[0]; unsigned rawRed; [[NSScanner scannerWithString: [NSString stringWithUTF8String: value]] scanHexInt: &rawRed]; value[0] = [fromHTML characterAtIndex: index++]; if (longVersion) value[1] = [fromHTML characterAtIndex: index++]; else value[1] = value[0]; unsigned rawGreen; [[NSScanner scannerWithString: [NSString stringWithUTF8String: value]] scanHexInt: &rawGreen]; value[0] = [fromHTML characterAtIndex: index++]; if (longVersion) value[1] = [fromHTML characterAtIndex: index++]; else value[1] = value[0]; unsigned rawBlue; [[NSScanner scannerWithString: [NSString stringWithUTF8String: value]] scanHexInt: &rawBlue]; long color = (rawBlue << 16) + (rawGreen << 8) + rawRed; mBackend->WndProc(property, parameter, color); } } //-------------------------------------------------------------------------------------------------- /** * Specialized property getter for colors. */ - (NSColor*) getColorProperty: (int) property parameter: (long) parameter { long color = mBackend->WndProc(property, parameter, 0); float red = (color & 0xFF) / 255.0; float green = ((color >> 8) & 0xFF) / 255.0; float blue = ((color >> 16) & 0xFF) / 255.0; NSColor* result = [NSColor colorWithDeviceRed: red green: green blue: blue alpha: 1]; return result; } //-------------------------------------------------------------------------------------------------- /** * Specialized property setter for references (pointers, addresses). */ - (void) setReferenceProperty: (int) property parameter: (long) parameter value: (const void*) value { mBackend->WndProc(property, parameter, (sptr_t) value); } //-------------------------------------------------------------------------------------------------- /** * Specialized property getter for references (pointers, addresses). */ - (const void*) getReferenceProperty: (int) property parameter: (long) parameter { return (const void*) mBackend->WndProc(property, parameter, 0); } //-------------------------------------------------------------------------------------------------- /** * Specialized property setter for string values. */ - (void) setStringProperty: (int) property parameter: (long) parameter value: (NSString*) value { const char* rawValue = [value UTF8String]; mBackend->WndProc(property, parameter, (sptr_t) rawValue); } //-------------------------------------------------------------------------------------------------- /** * Specialized property getter for string values. */ - (NSString*) getStringProperty: (int) property parameter: (long) parameter { const char* rawValue = (const char*) mBackend->WndProc(property, parameter, 0); return [NSString stringWithUTF8String: rawValue]; } //-------------------------------------------------------------------------------------------------- /** * Specialized property setter for lexer properties, which are commonly passed as strings. */ - (void) setLexerProperty: (NSString*) name value: (NSString*) value { const char* rawName = [name UTF8String]; const char* rawValue = [value UTF8String]; mBackend->WndProc(SCI_SETPROPERTY, (sptr_t) rawName, (sptr_t) rawValue); } //-------------------------------------------------------------------------------------------------- /** * Specialized property getter for references (pointers, addresses). */ - (NSString*) getLexerProperty: (NSString*) name { const char* rawName = [name UTF8String]; const char* result = (const char*) mBackend->WndProc(SCI_SETPROPERTY, (sptr_t) rawName, 0); return [NSString stringWithUTF8String: result]; } //-------------------------------------------------------------------------------------------------- /** * Sets the notification callback */ - (void) registerNotifyCallback: (intptr_t) windowid value: (Scintilla::SciNotifyFunc) callback { mBackend->RegisterNotifyCallback(windowid, callback); } //-------------------------------------------------------------------------------------------------- /** * Sets the new control which is displayed as info bar at the top or bottom of the editor. * Set newBar to nil if you want to hide the bar again. * When aligned to bottom position then the info bar and the horizontal scroller share the available * space. The info bar will then only get the width it is currently set to less a minimal amount * reserved for the scroller. At the top position it gets the full width of the control. * The info bar's height is set to the height of the scrollbar. */ - (void) setInfoBar: (NSView <InfoBarCommunicator>*) newBar top: (BOOL) top { if (mInfoBar != newBar) { [mInfoBar removeFromSuperview]; mInfoBar = newBar; mInfoBarAtTop = top; if (mInfoBar != nil) { [self addSubview: mInfoBar]; [mInfoBar setCallback: self]; // Keep the initial width as reference for layout changes. mInitialInfoBarWidth = [mInfoBar frame].size.width; } [self positionSubViews]; } } //-------------------------------------------------------------------------------------------------- /** * Sets the edit's info bar status message. This call only has an effect if there is an info bar. */ - (void) setStatusText: (NSString*) text { if (mInfoBar != nil) [mInfoBar notify: IBNStatusChanged message: text location: NSZeroPoint value: 0]; } //-------------------------------------------------------------------------------------------------- - (NSRange) selectedRange { return [mContent selectedRange]; } //-------------------------------------------------------------------------------------------------- - (void)insertText: (NSString*)text { [mContent insertText: text]; } //-------------------------------------------------------------------------------------------------- /** * For backwards compatibility. */ - (BOOL) findAndHighlightText: (NSString*) searchText matchCase: (BOOL) matchCase wholeWord: (BOOL) wholeWord scrollTo: (BOOL) scrollTo wrap: (BOOL) wrap { return [self findAndHighlightText: searchText matchCase: matchCase wholeWord: wholeWord scrollTo: scrollTo wrap: wrap backwards: NO]; } //-------------------------------------------------------------------------------------------------- /** * Searches and marks the first occurance of the given text and optionally scrolls it into view. * * @result YES if something was found, NO otherwise. */ - (BOOL) findAndHighlightText: (NSString*) searchText matchCase: (BOOL) matchCase wholeWord: (BOOL) wholeWord scrollTo: (BOOL) scrollTo wrap: (BOOL) wrap backwards: (BOOL) backwards { int searchFlags= 0; if (matchCase) searchFlags |= SCFIND_MATCHCASE; if (wholeWord) searchFlags |= SCFIND_WHOLEWORD; int selectionStart = [self getGeneralProperty: SCI_GETSELECTIONSTART parameter: 0]; int selectionEnd = [self getGeneralProperty: SCI_GETSELECTIONEND parameter: 0]; // Sets the start point for the comming search to the begin of the current selection. // For forward searches we have therefore to set the selection start to the current selection end // for proper incremental search. This does not harm as we either get a new selection if something // is found or the previous selection is restored. if (!backwards) [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: selectionEnd]; [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; sptr_t result; const char* textToSearch = [searchText UTF8String]; // The following call will also set the selection if something was found. if (backwards) { result = [ScintillaView directCall: self message: SCI_SEARCHPREV wParam: searchFlags lParam: (sptr_t) textToSearch]; if (result < 0 && wrap) { // Try again from the end of the document if nothing could be found so far and // wrapped search is set. [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: [self getGeneralProperty: SCI_GETTEXTLENGTH parameter: 0]]; [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; result = [ScintillaView directCall: self message: SCI_SEARCHNEXT wParam: searchFlags lParam: (sptr_t) textToSearch]; } } else { result = [ScintillaView directCall: self message: SCI_SEARCHNEXT wParam: searchFlags lParam: (sptr_t) textToSearch]; if (result < 0 && wrap) { // Try again from the start of the document if nothing could be found so far and // wrapped search is set. [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: 0]; [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; result = [ScintillaView directCall: self message: SCI_SEARCHNEXT wParam: searchFlags lParam: (sptr_t) textToSearch]; } } if (result >= 0) { if (scrollTo) [self setGeneralProperty: SCI_SCROLLCARET value: 0]; } else { // Restore the former selection if we did not find anything. [self setGeneralProperty: SCI_SETSELECTIONSTART value: selectionStart]; [self setGeneralProperty: SCI_SETSELECTIONEND value: selectionEnd]; } return (result >= 0) ? YES : NO; } //-------------------------------------------------------------------------------------------------- /** * Searches the given text and replaces * * @result Number of entries replaced, 0 if none. */ - (int) findAndReplaceText: (NSString*) searchText byText: (NSString*) newText matchCase: (BOOL) matchCase wholeWord: (BOOL) wholeWord doAll: (BOOL) doAll { // The current position is where we start searching for single occurences. Otherwise we start at // the beginning of the document. int startPosition; if (doAll) startPosition = 0; // Start at the beginning of the text if we replace all occurrences. else // For a signle replacement we start at the current caret position. startPosition = [self getGeneralProperty: SCI_GETCURRENTPOS]; int endPosition = [self getGeneralProperty: SCI_GETTEXTLENGTH]; int searchFlags= 0; if (matchCase) searchFlags |= SCFIND_MATCHCASE; if (wholeWord) searchFlags |= SCFIND_WHOLEWORD; [self setGeneralProperty: SCI_SETSEARCHFLAGS value: searchFlags]; [self setGeneralProperty: SCI_SETTARGETSTART value: startPosition]; [self setGeneralProperty: SCI_SETTARGETEND value: endPosition]; const char* textToSearch = [searchText UTF8String]; int sourceLength = strlen(textToSearch); // Length in bytes. const char* replacement = [newText UTF8String]; int targetLength = strlen(replacement); // Length in bytes. sptr_t result; int replaceCount = 0; if (doAll) { while (true) { result = [ScintillaView directCall: self message: SCI_SEARCHINTARGET wParam: sourceLength lParam: (sptr_t) textToSearch]; if (result < 0) break; replaceCount++; [ScintillaView directCall: self message: SCI_REPLACETARGET wParam: targetLength lParam: (sptr_t) replacement]; // The replacement changes the target range to the replaced text. Continue after that til the end. // The text length might be changed by the replacement so make sure the target end is the actual // text end. [self setGeneralProperty: SCI_SETTARGETSTART value: [self getGeneralProperty: SCI_GETTARGETEND]]; [self setGeneralProperty: SCI_SETTARGETEND value: [self getGeneralProperty: SCI_GETTEXTLENGTH]]; } } else { result = [ScintillaView directCall: self message: SCI_SEARCHINTARGET wParam: sourceLength lParam: (sptr_t) textToSearch]; replaceCount = (result < 0) ? 0 : 1; if (replaceCount > 0) { [ScintillaView directCall: self message: SCI_REPLACETARGET wParam: targetLength lParam: (sptr_t) replacement]; // For a single replace we set the new selection to the replaced text. [self setGeneralProperty: SCI_SETSELECTIONSTART value: [self getGeneralProperty: SCI_GETTARGETSTART]]; [self setGeneralProperty: SCI_SETSELECTIONEND value: [self getGeneralProperty: SCI_GETTARGETEND]]; } } return replaceCount; } //-------------------------------------------------------------------------------------------------- - (void) setFontName: (NSString*) font size: (int) size bold: (BOOL) bold italic: (BOOL) italic { for (int i = 0; i < 128; i++) { [self setGeneralProperty: SCI_STYLESETFONT parameter: i value: (sptr_t)[font UTF8String]]; [self setGeneralProperty: SCI_STYLESETSIZE parameter: i value: size]; [self setGeneralProperty: SCI_STYLESETBOLD parameter: i value: bold]; [self setGeneralProperty: SCI_STYLESETITALIC parameter: i value: italic]; } } //-------------------------------------------------------------------------------------------------- @end |
Added cocoa/checkbuildosx.sh.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# Script to build Scintilla for OS X with most supported build files. # Current directory should be scintilla/cocoa before running. cd ../.. # ************************************************************ # Target 1: build framework and test app with Xcode targetting OS X 10.7 # Clean both then build both -- if perform clean in ScintillaTest, also cleans ScintillaFramework # which can cause double build cd scintilla/cocoa/ScintillaFramework xcodebuild clean cd ../ScintillaTest xcodebuild clean cd ../ScintillaFramework xcodebuild -sdk macosx10.7 cd ../ScintillaTest xcodebuild -sdk macosx10.7 cd ../../.. # ************************************************************ # Target 2: build framework and test app with Xcode targetting OS X 10.6 cd scintilla/cocoa/ScintillaFramework xcodebuild clean cd ../ScintillaTest xcodebuild clean cd ../ScintillaFramework xcodebuild -sdk macosx10.6 cd ../ScintillaTest xcodebuild -sdk macosx10.6 cd ../../.. # ************************************************************ # Target 3: build framework and test app with Xcode targetting OS X 10.5 cd scintilla/cocoa/ScintillaFramework xcodebuild clean cd ../ScintillaTest xcodebuild clean cd ../ScintillaFramework xcodebuild -sdk macosx10.5 cd ../ScintillaTest xcodebuild -sdk macosx10.5 cd ../../.. # ************************************************************ # Target 4: Qt builds # Requires Qt development libraries and qmake to be installed cd scintilla/qt cd ScintillaEditBase qmake xcodebuild clean xcodebuild cd .. cd ScintillaEdit python WidgetGen.py qmake xcodebuild clean xcodebuild cd .. cd ScintillaEditPy python sepbuild.py cd .. cd ../.. # ************************************************************ # Target 5: build framework and test app with make cd scintilla/cocoa make -f Framework.mk clean make -f Framework.mk all make -f SciTest.mk all cd ../.. |
Added cocoa/common.mk.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
### shared variables and targets between Framework.mk and SciTest.mk ### # build directories BLD=build APP_BLD=$(BLD)/Application FRM_BLD=$(BLD)/Framework ifdef DBG CFLAGS=-g -O0 else CFLAGS=-Os endif # compiler and compiler options ARCH=-arch i386 $(CFLAGS) CC=gcc -x c++ $(ARCH) CO=gcc -x objective-c++ $(ARCH) CCX=$(CC) $(gDEFs) $(INCS) CCO=$(CO) $(gDEFs) $(INCS) # include directories and global #define gDEFs=-DSCI_NAMESPACE -DSCI_LEXER # source directories SRC_DIRS=../src ./ScintillaFramework ./ScintillaTest ./ \ ../lexers ../lexlib INC_DIRS=$(SRC_DIRS) ../include INCS=$(addprefix -I,$(INC_DIRS)) vpath %.m $(SRC_DIRS) vpath %.mm $(SRC_DIRS) vpath %.cpp $(SRC_DIRS) vpath %.cxx $(SRC_DIRS) vpath %.c $(SRC_DIRS) vpath %.h $(INC_DIRS) # clean everything clean: -rm -rf $(BLD) # build application objective-c++ files $(APP_BLD)/%.o : %.mm $(CCO) -c $< -o $@ # build application objective-c files $(APP_BLD)/%.o : %.m $(CCO) -c $< -o $@ # build framework c++ files $(FRM_BLD)/%.o : %.cxx $(CCX) -c $< -o $@ # build framework objective-c++ files $(FRM_BLD)/%.o : %.mm $(CCO) -c $< -o $@ |
Added cocoa/res/info_bar_bg.png.
cannot compute difference between binary files
Added cocoa/res/mac_cursor_busy.png.
cannot compute difference between binary files
Added cocoa/res/mac_cursor_flipped.png.
cannot compute difference between binary files
Added delbin.bat.
> |
1 |
del /S /Q *.a *.aps *.bsc *.dll *.dsw *.exe *.idb *.ilc *.ild *.ilf *.ilk *.ils *.lib *.map *.ncb *.obj *.o *.opt *.pdb *.plg *.res *.sbr *.tds *.exp *.tlog >NUL:
|
Added delcvs.bat.
> |
1 |
del /S /Q .cvsignore
|
Added doc/CommandValues.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <!--Generated by scite/scripts/commandsdoc.py --> <style type="text/css"> table { border: 1px solid #1F1F1F; border-collapse: collapse; } td { border: 1px solid; border-color: #E0E0E0 #000000; padding: 1px 5px 1px 5px; } th { border: 1px solid #1F1F1F; padding: 1px 5px 1px 5px; } thead { background-color: #000000; color: #FFFFFF; } </style> <body> <h2>SciTE menu commands</h2> <table> <thead><td>Command</td><td>Menu text</td></thead> <tr><td>IDM_NEW</td><td>New</td></tr> <tr><td>IDM_OPEN</td><td>Open</td></tr> <tr><td>IDM_OPENSELECTED</td><td>Open Selected Filename</td></tr> <tr><td>IDM_REVERT</td><td>Revert</td></tr> <tr><td>IDM_CLOSE</td><td>Close</td></tr> <tr><td>IDM_SAVE</td><td>Save</td></tr> <tr><td>IDM_SAVEAS</td><td>Save As</td></tr> <tr><td>IDM_SAVEACOPY</td><td>Save a Copy</td></tr> <tr><td>IDM_COPYPATH</td><td>Copy Path</td></tr> <tr><td>IDM_ENCODING_DEFAULT</td><td>Code Page Property</td></tr> <tr><td>IDM_ENCODING_UCS2BE</td><td>UTF-16 Big Endian</td></tr> <tr><td>IDM_ENCODING_UCS2LE</td><td>UTF-16 Little Endian</td></tr> <tr><td>IDM_ENCODING_UTF8</td><td>UTF-8 with BOM</td></tr> <tr><td>IDM_ENCODING_UCOOKIE</td><td>UTF-8</td></tr> <tr><td>IDM_SAVEASHTML</td><td>As HTML</td></tr> <tr><td>IDM_SAVEASRTF</td><td>As RTF</td></tr> <tr><td>IDM_SAVEASPDF</td><td>As PDF</td></tr> <tr><td>IDM_SAVEASTEX</td><td>As LaTeX</td></tr> <tr><td>IDM_SAVEASXML</td><td>As XML</td></tr> <tr><td>IDM_PRINTSETUP</td><td>Page Setup</td></tr> <tr><td>IDM_PRINT</td><td>Print</td></tr> <tr><td>IDM_LOADSESSION</td><td>Load Session</td></tr> <tr><td>IDM_SAVESESSION</td><td>Save Session</td></tr> <tr><td>IDM_QUIT</td><td>Exit</td></tr> <tr><td>IDM_UNDO</td><td>Undo</td></tr> <tr><td>IDM_REDO</td><td>Redo</td></tr> <tr><td>IDM_CUT</td><td>Cut</td></tr> <tr><td>IDM_COPY</td><td>Copy</td></tr> <tr><td>IDM_PASTE</td><td>Paste</td></tr> <tr><td>IDM_DUPLICATE</td><td>Duplicate</td></tr> <tr><td>IDM_CLEAR</td><td>Delete</td></tr> <tr><td>IDM_SELECTALL</td><td>Select All</td></tr> <tr><td>IDM_COPYASRTF</td><td>Copy as RTF</td></tr> <tr><td>IDM_MATCHBRACE</td><td>Match Brace</td></tr> <tr><td>IDM_SELECTTOBRACE</td><td>Select to Brace</td></tr> <tr><td>IDM_SHOWCALLTIP</td><td>Show Calltip</td></tr> <tr><td>IDM_COMPLETE</td><td>Complete Symbol</td></tr> <tr><td>IDM_COMPLETEWORD</td><td>Complete Word</td></tr> <tr><td>IDM_ABBREV</td><td>Expand Abbreviation</td></tr> <tr><td>IDM_INS_ABBREV</td><td>Insert Abbreviation</td></tr> <tr><td>IDM_BLOCK_COMMENT</td><td>Block Comment or Uncomment</td></tr> <tr><td>IDM_BOX_COMMENT</td><td>Box Comment</td></tr> <tr><td>IDM_STREAM_COMMENT</td><td>Stream Comment</td></tr> <tr><td>IDM_UPRCASE</td><td>Make Selection Uppercase</td></tr> <tr><td>IDM_LWRCASE</td><td>Make Selection Lowercase</td></tr> <tr><td>IDM_JOIN</td><td>Join</td></tr> <tr><td>IDM_SPLIT</td><td>Split</td></tr> <tr><td>IDM_FIND</td><td>Find</td></tr> <tr><td>IDM_FINDNEXT</td><td>Find Next</td></tr> <tr><td>IDM_FINDNEXTBACK</td><td>Find Previous</td></tr> <tr><td>IDM_FINDINFILES</td><td>Find in Files</td></tr> <tr><td>IDM_REPLACE</td><td>Replace</td></tr> <tr><td>IDM_INCSEARCH</td><td>Incremental Search</td></tr> <tr><td>IDM_GOTO</td><td>Go to</td></tr> <tr><td>IDM_BOOKMARK_NEXT</td><td>Next Bookmark</td></tr> <tr><td>IDM_BOOKMARK_PREV</td><td>Previous Bookmark</td></tr> <tr><td>IDM_BOOKMARK_TOGGLE</td><td>Toggle Bookmark</td></tr> <tr><td>IDM_BOOKMARK_CLEARALL</td><td>Clear All Bookmarks</td></tr> <tr><td>IDM_EXPAND</td><td>Toggle current fold</td></tr> <tr><td>IDM_TOGGLE_FOLDALL</td><td>Toggle all folds</td></tr> <tr><td>IDM_FULLSCREEN</td><td>Full Screen</td></tr> <tr><td>IDM_VIEWTOOLBAR</td><td>Tool Bar</td></tr> <tr><td>IDM_VIEWTABBAR</td><td>Tab Bar</td></tr> <tr><td>IDM_VIEWSTATUSBAR</td><td>Status Bar</td></tr> <tr><td>IDM_VIEWSPACE</td><td>Whitespace</td></tr> <tr><td>IDM_VIEWEOL</td><td>End of Line</td></tr> <tr><td>IDM_VIEWGUIDES</td><td>Indentation Guides</td></tr> <tr><td>IDM_LINENUMBERMARGIN</td><td>Line Numbers</td></tr> <tr><td>IDM_SELMARGIN</td><td>Margin</td></tr> <tr><td>IDM_FOLDMARGIN</td><td>Fold Margin</td></tr> <tr><td>IDM_TOGGLEOUTPUT</td><td>Output</td></tr> <tr><td>IDM_TOGGLEPARAMETERS</td><td>Parameters</td></tr> <tr><td>IDM_COMPILE</td><td>Compile</td></tr> <tr><td>IDM_BUILD</td><td>Build</td></tr> <tr><td>IDM_GO</td><td>Go</td></tr> <tr><td>IDM_STOPEXECUTE</td><td>Stop Executing</td></tr> <tr><td>IDM_NEXTMSG</td><td>Next Message</td></tr> <tr><td>IDM_PREVMSG</td><td>Previous Message</td></tr> <tr><td>IDM_CLEAROUTPUT</td><td>Clear Output</td></tr> <tr><td>IDM_SWITCHPANE</td><td>Switch Pane</td></tr> <tr><td>IDM_ONTOP</td><td>Always On Top</td></tr> <tr><td>IDM_OPENFILESHERE</td><td>Open Files Here</td></tr> <tr><td>IDM_SPLITVERTICAL</td><td>Vertical Split</td></tr> <tr><td>IDM_WRAP</td><td>Wrap</td></tr> <tr><td>IDM_WRAPOUTPUT</td><td>Wrap Output</td></tr> <tr><td>IDM_READONLY</td><td>Read-Only</td></tr> <tr><td>IDM_EOL_CRLF</td><td>CR + LF</td></tr> <tr><td>IDM_EOL_CR</td><td>CR</td></tr> <tr><td>IDM_EOL_LF</td><td>LF</td></tr> <tr><td>IDM_EOL_CONVERT</td><td>Convert Line End Characters</td></tr> <tr><td>IDM_TABSIZE</td><td>Change Indentation Settings</td></tr> <tr><td>IDM_MONOFONT</td><td>Use Monospaced Font</td></tr> <tr><td>IDM_OPENLOCALPROPERTIES</td><td>Open Local Options File</td></tr> <tr><td>IDM_OPENDIRECTORYPROPERTIES</td><td>Open Directory Options File</td></tr> <tr><td>IDM_OPENUSERPROPERTIES</td><td>Open User Options File</td></tr> <tr><td>IDM_OPENGLOBALPROPERTIES</td><td>Open Global Options File</td></tr> <tr><td>IDM_OPENABBREVPROPERTIES</td><td>Open Abbreviations File</td></tr> <tr><td>IDM_OPENLUAEXTERNALFILE</td><td>Open Lua Startup Script</td></tr> <tr><td>IDM_PREVFILE</td><td>Previous</td></tr> <tr><td>IDM_NEXTFILE</td><td>Next</td></tr> <tr><td>IDM_CLOSEALL</td><td>Close All</td></tr> <tr><td>IDM_SAVEALL</td><td>Save All</td></tr> <tr><td>IDM_HELP</td><td>Help</td></tr> <tr><td>IDM_HELP_SCITE</td><td>Sc1 Help</td></tr> <tr><td>IDM_ABOUT</td><td>About Sc1</td></tr> <tr><td>IDM_HELP_SCITE</td><td>SciTE Help</td></tr> <tr><td>IDM_ABOUT</td><td>About SciTE</td></tr> </table> <h2>Scintilla key commands</h2> <table> <thead><td>Command</td><td>Name</td><td>Explanation</td></thead> <tr><td>2547</td><td>AnnotationClearAll</td><td>Clear the annotations from all lines</td></tr> <tr><td>2101</td><td>AutoCCancel</td><td>Remove the auto-completion list from the screen.</td></tr> <tr><td>2104</td><td>AutoCComplete</td><td>User has selected an item so remove the list and insert the selection.</td></tr> <tr><td>2328</td><td>BackTab</td><td>Dedent the selected lines.</td></tr> <tr><td>2078</td><td>BeginUndoAction</td><td>Start a sequence of actions that is undone and redone as a unit. May be nested.</td></tr> <tr><td>2201</td><td>CallTipCancel</td><td>Remove the call tip from the screen.</td></tr> <tr><td>2325</td><td>Cancel</td><td>Cancel any modes such as call tip or auto-completion list display.</td></tr> <tr><td>2304</td><td>CharLeft</td><td>Move caret left one character.</td></tr> <tr><td>2305</td><td>CharLeftExtend</td><td>Move caret left one character extending selection to new caret position.</td></tr> <tr><td>2428</td><td>CharLeftRectExtend</td><td>Move caret left one character, extending rectangular selection to new caret position.</td></tr> <tr><td>2306</td><td>CharRight</td><td>Move caret right one character.</td></tr> <tr><td>2307</td><td>CharRightExtend</td><td>Move caret right one character extending selection to new caret position.</td></tr> <tr><td>2429</td><td>CharRightRectExtend</td><td>Move caret right one character, extending rectangular selection to new caret position.</td></tr> <tr><td>2399</td><td>ChooseCaretX</td><td>Set the last x chosen value to be the caret x position.</td></tr> <tr><td>2180</td><td>Clear</td><td>Clear the selection.</td></tr> <tr><td>2004</td><td>ClearAll</td><td>Delete all text in the document.</td></tr> <tr><td>2072</td><td>ClearAllCmdKeys</td><td>Drop all key mappings.</td></tr> <tr><td>2005</td><td>ClearDocumentStyle</td><td>Set all style bytes to 0, remove all folding information.</td></tr> <tr><td>2408</td><td>ClearRegisteredImages</td><td>Clear all the registered XPM images.</td></tr> <tr><td>2571</td><td>ClearSelections</td><td>Clear selections to a single empty stream selection</td></tr> <tr><td>2178</td><td>Copy</td><td>Copy the selection to the clipboard.</td></tr> <tr><td>2519</td><td>CopyAllowLine</td><td>Copy the selection, if selection empty copy the line with the caret</td></tr> <tr><td>2177</td><td>Cut</td><td>Cut the selection to the clipboard.</td></tr> <tr><td>2395</td><td>DelLineLeft</td><td>Delete back from the current position to the start of the line.</td></tr> <tr><td>2396</td><td>DelLineRight</td><td>Delete forwards from the current position to the end of the line.</td></tr> <tr><td>2335</td><td>DelWordLeft</td><td>Delete the word to the left of the caret.</td></tr> <tr><td>2336</td><td>DelWordRight</td><td>Delete the word to the right of the caret.</td></tr> <tr><td>2518</td><td>DelWordRightEnd</td><td>Delete the word to the right of the caret, but not the trailing non-word characters.</td></tr> <tr><td>2326</td><td>DeleteBack</td><td>Delete the selection or if no selection, the character before the caret.</td></tr> <tr><td>2344</td><td>DeleteBackNotLine</td><td>Delete the selection or if no selection, the character before the caret. Will not delete the character before at the start of a line.</td></tr> <tr><td>2318</td><td>DocumentEnd</td><td>Move caret to last position in document.</td></tr> <tr><td>2319</td><td>DocumentEndExtend</td><td>Move caret to last position in document extending selection to new caret position.</td></tr> <tr><td>2316</td><td>DocumentStart</td><td>Move caret to first position in document.</td></tr> <tr><td>2317</td><td>DocumentStartExtend</td><td>Move caret to first position in document extending selection to new caret position.</td></tr> <tr><td>2324</td><td>EditToggleOvertype</td><td>Switch from insert to overtype mode or the reverse.</td></tr> <tr><td>2175</td><td>EmptyUndoBuffer</td><td>Delete the undo history.</td></tr> <tr><td>2079</td><td>EndUndoAction</td><td>End a sequence of actions that is undone and redone as a unit.</td></tr> <tr><td>2642</td><td>FindIndicatorHide</td><td>On OS X, hide the find indicator.</td></tr> <tr><td>2330</td><td>FormFeed</td><td>Insert a Form Feed character.</td></tr> <tr><td>4023</td><td>FreeSubStyles</td><td>Free allocated sub styles</td></tr> <tr><td>2400</td><td>GrabFocus</td><td>Set the focus to this Scintilla widget.</td></tr> <tr><td>2312</td><td>Home</td><td>Move caret to first position on line.</td></tr> <tr><td>2345</td><td>HomeDisplay</td><td>Move caret to first position on display line.</td></tr> <tr><td>2346</td><td>HomeDisplayExtend</td><td>Move caret to first position on display line extending selection to new caret position.</td></tr> <tr><td>2313</td><td>HomeExtend</td><td>Move caret to first position on line extending selection to new caret position.</td></tr> <tr><td>2430</td><td>HomeRectExtend</td><td>Move caret to first position on line, extending rectangular selection to new caret position.</td></tr> <tr><td>2349</td><td>HomeWrap</td><td>These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)? except they behave differently when word-wrap is enabled: They go first to the start / end of the display line, like (Home|LineEnd)Display The difference is that, the cursor is already at the point, it goes on to the start or end of the document line, as appropriate for (Home|LineEnd|VCHome)(Extend)?.</td></tr> <tr><td>2450</td><td>HomeWrapExtend</td><td>These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)? except they behave differently when word-wrap is enabled: They go first to the start / end of the display line, like (Home|LineEnd)Display The difference is that, the cursor is already at the point, it goes on to the start or end of the document line, as appropriate for (Home|LineEnd|VCHome)(Extend)?.</td></tr> <tr><td>2455</td><td>LineCopy</td><td>Copy the line containing the caret.</td></tr> <tr><td>2337</td><td>LineCut</td><td>Cut the line containing the caret.</td></tr> <tr><td>2338</td><td>LineDelete</td><td>Delete the line containing the caret.</td></tr> <tr><td>2300</td><td>LineDown</td><td>Move caret down one line.</td></tr> <tr><td>2301</td><td>LineDownExtend</td><td>Move caret down one line extending selection to new caret position.</td></tr> <tr><td>2426</td><td>LineDownRectExtend</td><td>Move caret down one line, extending rectangular selection to new caret position.</td></tr> <tr><td>2404</td><td>LineDuplicate</td><td>Duplicate the current line.</td></tr> <tr><td>2314</td><td>LineEnd</td><td>Move caret to last position on line.</td></tr> <tr><td>2347</td><td>LineEndDisplay</td><td>Move caret to last position on display line.</td></tr> <tr><td>2348</td><td>LineEndDisplayExtend</td><td>Move caret to last position on display line extending selection to new caret position.</td></tr> <tr><td>2315</td><td>LineEndExtend</td><td>Move caret to last position on line extending selection to new caret position.</td></tr> <tr><td>2432</td><td>LineEndRectExtend</td><td>Move caret to last position on line, extending rectangular selection to new caret position.</td></tr> <tr><td>2451</td><td>LineEndWrap</td><td>These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)? except they behave differently when word-wrap is enabled: They go first to the start / end of the display line, like (Home|LineEnd)Display The difference is that, the cursor is already at the point, it goes on to the start or end of the document line, as appropriate for (Home|LineEnd|VCHome)(Extend)?.</td></tr> <tr><td>2452</td><td>LineEndWrapExtend</td><td>These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)? except they behave differently when word-wrap is enabled: They go first to the start / end of the display line, like (Home|LineEnd)Display The difference is that, the cursor is already at the point, it goes on to the start or end of the document line, as appropriate for (Home|LineEnd|VCHome)(Extend)?.</td></tr> <tr><td>2342</td><td>LineScrollDown</td><td>Scroll the document down, keeping the caret visible.</td></tr> <tr><td>2343</td><td>LineScrollUp</td><td>Scroll the document up, keeping the caret visible.</td></tr> <tr><td>2339</td><td>LineTranspose</td><td>Switch the current line with the previous.</td></tr> <tr><td>2302</td><td>LineUp</td><td>Move caret up one line.</td></tr> <tr><td>2303</td><td>LineUpExtend</td><td>Move caret up one line extending selection to new caret position.</td></tr> <tr><td>2427</td><td>LineUpRectExtend</td><td>Move caret up one line, extending rectangular selection to new caret position.</td></tr> <tr><td>2288</td><td>LinesJoin</td><td>Join the lines in the target.</td></tr> <tr><td>2340</td><td>LowerCase</td><td>Transform the selection to lower case.</td></tr> <tr><td>2536</td><td>MarginTextClearAll</td><td>Clear the margin text on all lines</td></tr> <tr><td>2401</td><td>MoveCaretInsideView</td><td>Move the caret inside current view if it's not there already.</td></tr> <tr><td>2621</td><td>MoveSelectedLinesDown</td><td>Move the selected lines down one line, shifting the line below before the selection</td></tr> <tr><td>2620</td><td>MoveSelectedLinesUp</td><td>Move the selected lines up one line, shifting the line above after the selection</td></tr> <tr><td>2329</td><td>NewLine</td><td>Insert a new line, may use a CRLF, CR or LF depending on EOL mode.</td></tr> <tr><td>2172</td><td>Null</td><td>Null operation.</td></tr> <tr><td>2322</td><td>PageDown</td><td>Move caret one page down.</td></tr> <tr><td>2323</td><td>PageDownExtend</td><td>Move caret one page down extending selection to new caret position.</td></tr> <tr><td>2434</td><td>PageDownRectExtend</td><td>Move caret one page down, extending rectangular selection to new caret position.</td></tr> <tr><td>2320</td><td>PageUp</td><td>Move caret one page up.</td></tr> <tr><td>2321</td><td>PageUpExtend</td><td>Move caret one page up extending selection to new caret position.</td></tr> <tr><td>2433</td><td>PageUpRectExtend</td><td>Move caret one page up, extending rectangular selection to new caret position.</td></tr> <tr><td>2413</td><td>ParaDown</td><td>Move caret between paragraphs (delimited by empty lines).</td></tr> <tr><td>2414</td><td>ParaDownExtend</td><td>Move caret between paragraphs (delimited by empty lines).</td></tr> <tr><td>2415</td><td>ParaUp</td><td>Move caret between paragraphs (delimited by empty lines).</td></tr> <tr><td>2416</td><td>ParaUpExtend</td><td>Move caret between paragraphs (delimited by empty lines).</td></tr> <tr><td>2179</td><td>Paste</td><td>Paste the contents of the clipboard into the document replacing the selection.</td></tr> <tr><td>2011</td><td>Redo</td><td>Redoes the next action on the undo history.</td></tr> <tr><td>2552</td><td>ReleaseAllExtendedStyles</td><td>Release all extended (>255) style numbers</td></tr> <tr><td>2606</td><td>RotateSelection</td><td>Set the main selection to the next selection.</td></tr> <tr><td>2169</td><td>ScrollCaret</td><td>Ensure the caret is visible.</td></tr> <tr><td>2629</td><td>ScrollToEnd</td><td>Scroll to end of document.</td></tr> <tr><td>2628</td><td>ScrollToStart</td><td>Scroll to start of document.</td></tr> <tr><td>2366</td><td>SearchAnchor</td><td>Sets the current caret position to be the search anchor.</td></tr> <tr><td>2013</td><td>SelectAll</td><td>Select all the text in the document.</td></tr> <tr><td>2469</td><td>SelectionDuplicate</td><td>Duplicate the selection. If selection empty duplicate the line containing the caret.</td></tr> <tr><td>2444</td><td>SetCharsDefault</td><td>Reset the set of characters for whitespace and word characters to the defaults.</td></tr> <tr><td>2014</td><td>SetSavePoint</td><td>Remember the current position in the undo history as the position at which the document was saved.</td></tr> <tr><td>3001</td><td>StartRecord</td><td>Start notifying the container of all key presses and commands.</td></tr> <tr><td>3002</td><td>StopRecord</td><td>Stop notifying the container of all key presses and commands.</td></tr> <tr><td>2437</td><td>StutteredPageDown</td><td>Move caret to bottom of page, or one page down if already at bottom of page.</td></tr> <tr><td>2438</td><td>StutteredPageDownExtend</td><td>Move caret to bottom of page, or one page down if already at bottom of page, extending selection to new caret position.</td></tr> <tr><td>2435</td><td>StutteredPageUp</td><td>Move caret to top of page, or one page up if already at top of page.</td></tr> <tr><td>2436</td><td>StutteredPageUpExtend</td><td>Move caret to top of page, or one page up if already at top of page, extending selection to new caret position.</td></tr> <tr><td>2050</td><td>StyleClearAll</td><td>Clear all the styles and make equivalent to the global default style.</td></tr> <tr><td>2058</td><td>StyleResetDefault</td><td>Reset the default style to its state at startup</td></tr> <tr><td>2607</td><td>SwapMainAnchorCaret</td><td>Swap that caret and anchor of the main selection.</td></tr> <tr><td>2327</td><td>Tab</td><td>If selection is empty or all on one line replace the selection with a tab character. If more than one line selected, indent the lines.</td></tr> <tr><td>2287</td><td>TargetFromSelection</td><td>Make the target range start and end be the same as the selection range start and end.</td></tr> <tr><td>2459</td><td>ToggleCaretSticky</td><td>Switch between sticky and non-sticky: meant to be bound to a key.</td></tr> <tr><td>2176</td><td>Undo</td><td>Undo one action in the undo history.</td></tr> <tr><td>2341</td><td>UpperCase</td><td>Transform the selection to upper case.</td></tr> <tr><td>2331</td><td>VCHome</td><td>Move caret to before first visible character on line. If already there move to first character on line.</td></tr> <tr><td>2652</td><td>VCHomeDisplay</td><td>Move caret to before first visible character on display line. If already there move to first character on display line.</td></tr> <tr><td>2653</td><td>VCHomeDisplayExtend</td><td>Like VCHomeDisplay but extending selection to new caret position.</td></tr> <tr><td>2332</td><td>VCHomeExtend</td><td>Like VCHome but extending selection to new caret position.</td></tr> <tr><td>2431</td><td>VCHomeRectExtend</td><td>Move caret to before first visible character on line. If already there move to first character on line. In either case, extend rectangular selection to new caret position.</td></tr> <tr><td>2453</td><td>VCHomeWrap</td><td>These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)? except they behave differently when word-wrap is enabled: They go first to the start / end of the display line, like (Home|LineEnd)Display The difference is that, the cursor is already at the point, it goes on to the start or end of the document line, as appropriate for (Home|LineEnd|VCHome)(Extend)?.</td></tr> <tr><td>2454</td><td>VCHomeWrapExtend</td><td>These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)? except they behave differently when word-wrap is enabled: They go first to the start / end of the display line, like (Home|LineEnd)Display The difference is that, the cursor is already at the point, it goes on to the start or end of the document line, as appropriate for (Home|LineEnd|VCHome)(Extend)?.</td></tr> <tr><td>2619</td><td>VerticalCentreCaret</td><td>Centre current line in window.</td></tr> <tr><td>2308</td><td>WordLeft</td><td>Move caret left one word.</td></tr> <tr><td>2439</td><td>WordLeftEnd</td><td>Move caret left one word, position cursor at end of word.</td></tr> <tr><td>2440</td><td>WordLeftEndExtend</td><td>Move caret left one word, position cursor at end of word, extending selection to new caret position.</td></tr> <tr><td>2309</td><td>WordLeftExtend</td><td>Move caret left one word extending selection to new caret position.</td></tr> <tr><td>2390</td><td>WordPartLeft</td><td>Move to the previous change in capitalisation.</td></tr> <tr><td>2391</td><td>WordPartLeftExtend</td><td>Move to the previous change in capitalisation extending selection to new caret position.</td></tr> <tr><td>2392</td><td>WordPartRight</td><td>Move to the change next in capitalisation.</td></tr> <tr><td>2393</td><td>WordPartRightExtend</td><td>Move to the next change in capitalisation extending selection to new caret position.</td></tr> <tr><td>2310</td><td>WordRight</td><td>Move caret right one word.</td></tr> <tr><td>2441</td><td>WordRightEnd</td><td>Move caret right one word, position cursor at end of word.</td></tr> <tr><td>2442</td><td>WordRightEndExtend</td><td>Move caret right one word, position cursor at end of word, extending selection to new caret position.</td></tr> <tr><td>2311</td><td>WordRightExtend</td><td>Move caret right one word extending selection to new caret position.</td></tr> <tr><td>2333</td><td>ZoomIn</td><td>Magnify the displayed text by increasing the sizes by 1 point.</td></tr> <tr><td>2334</td><td>ZoomOut</td><td>Make the displayed text smaller by decreasing the sizes by 1 point.</td></tr> </table> </body> </html> |
Added doc/Design.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="HTML Tidy, see www.w3.org" /> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title> Scintilla and SciTE </title> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5">Scintilla Component Design</font></a> </td> </tr> </table> <h2> Top level structure </h2> <p> Scintilla consists of three major layers of C++ code </p> <ul> <li> Portability Library </li> <li> Core Code </li> <li> Platform Events and API </li> </ul> <p> The primary purpose of this structure is to separate the platform dependent code from the platform independent core code. This makes it easier to port Scintilla to a new platform and ensures that most readers of the code do not have to deal with platform details. To minimise portability problems and avoid code bloat, a conservative subset of C++ is used in Scintilla with no exception handling, run time type information or use of the standard C++ library and with limited use of templates. </p> <p> The currently supported platforms, Windows, GTK+/Linux and wxWindows are fairly similar in many ways. Each has windows, menus and bitmaps. These features generally work in similar ways so each has a way to move a window or draw a red line. Sometimes one platform requires a sequence of calls rather than a single call. At other times, the differences are more profound. Reading the Windows clipboard occurs synchronously but reading the GTK+ clipboard requires a request call that will be asynchronously answered with a message containing the clipboard data. The wxWindows platform is available from the <a href="http://wxwindows.org/">wxWindows site</a> </p> <br /> <h3> Portability Library </h3> <p> This is a fairly small and thin layer over the platform's native capabilities. </p> <p> The portability library is defined in Platform.h and is implemented once for each platform. PlatWin.cxx defines the Windows variants of the methods and PlatGTK.cxx the GTK+ variants. </p> <p> Several of the classes here hold platform specific object identifiers and act as proxies to these platform objects. Most client code can thus manipulate the platform objects without caring which is the current platform. Sometimes client code needs access to the underlying object identifiers and this is provided by the GetID method. The underlying types of the platform specific identifiers are typedefed to common names to allow them to be transferred around in client code where needed. </p> <h4> Point, PRectangle </h4> <p> These are simple classes provided to hold the commonly used geometric primitives. A PRectangle follows the Mac / Windows convention of not including its bottom and right sides instead of including all its sides as is normal in GTK+. It is not called Rectangle as this may be the name of a macro on Windows. </p> <h4> Colour, ColourPair, Palette </h4> <p> Colour holds a platform specific colour identifier - COLORREF for Windows and GdkColor for GTK+. The red, green and blue components that make up the colour are limited to the 8 bits of precision available on Windows. ColourPairs are used because not all possible colours are always available. Using an 8 bit colour mode, which is a common setting for both Windows and GTK+, only 256 colours are possible on the display. Thus when an application asks for a dull red, say #400000, it may only be allocated an already available colour such as #800000 or #330000. With 16 or 2 colour modes even less choice is available and the application will have to use the limited set of already available colours. </p> A Palette object holds a set of colour pairs and can make the appropriate calls to ask to allocate these colours and to see what the platform has decided will be allowed. <h4> Font </h4> <p> Font holds a platform specific font identifier - HFONT for Windows, GdkFont* for GTK+. It does not own the identifier and so will not delete the platform font object in its destructor. Client code should call Destroy at appropriate times. </p> <h4> Surface </h4> <p> Surface is an abstraction over each platform's concept of somewhere that graphical drawing operations can be done. It may wrap an already created drawing place such as a window or be used to create a bitmap that can be drawn into and later copied onto another surface. On Windows it wraps a HDC and possibly a HBITMAP. On GTK+ it wraps a GdkDrawable* and possibly a GdkPixmap*. Other platform specific objects are created (and correctly destroyed) whenever required to perform drawing actions. </p> <p> Drawing operations provided include drawing filled and unfilled polygons, lines, rectangles, ellipses and text. The height and width of text as well as other details can be measured. Operations can be clipped to a rectangle. Most of the calls are stateless with all parameters being passed at each call. The exception to this is line drawing which is performed by calling MoveTo and then LineTo. </p> <h4> Window </h4> <p> Window acts as a proxy to a platform window allowing operations such as showing, moving, redrawing, and destroying to be performed. It contains a platform specific window identifier - HWND for Windows, GtkWidget* for GTK+. </p> <h4> ListBox </h4> <p> ListBox is a subclass of Window and acts as a proxy to a platform listbox adding methods for operations such as adding, retrieving, and selecting items. </p> <h4> Menu </h4> <p> Menu is a small helper class for constructing popup menus. It contains the platform specific menu identifier - HMENU for Windows, GtkItemFactory* for GTK+. Most of the work in constructing menus requires access to platform events and so is done in the Platform Events and API layer. </p> <h4> Platform </h4> <p> The Platform class is used to access the facilities of the platform. System wide parameters such as double click speed and chrome colour are available from Platform. Utility functions such as DebugPrintf are also available from Platform. </p> <h3> Core Code </h3> <p> The bulk of Scintilla's code is platform independent. This is made up of the CellBuffer, ContractionState, Document, Editor, Indicator, LineMarker, Style, ViewStyle, KeyMap, ScintillaBase, CallTip, and AutoComplete primary classes. </p> <h4> CellBuffer </h4> <p> A CellBuffer holds text and styling information, the undo stack, the assignment of line markers to lines, and the fold structure. </p> <p> A cell contains a character byte and its associated style byte. The current state of the cell buffer is the sequence of cells that make up the text and a sequence of line information containing the starting position of each line and any markers assigned to each line. </p> <p> The undo stack holds a sequence of actions on the cell buffer. Each action is one of a text insertion, a text deletion or an undo start action. The start actions are used to group sequences of text insertions and deletions together so they can be undone together. To perform an undo operation, each insertion or deletion is undone in reverse sequence. Similarly, redo reapplies each action to the buffer in sequence. Whenever a character is inserted in the buffer either directly through a call such as InsertString or through undo or redo, its styling byte is initially set to zero. Client code is responsible for styling each character whenever convenient. Styling information is not stored in undo actions. </p> <h4> Document </h4> <p> A document contains a CellBuffer and deals with some higher level abstractions such as words, DBCS character sequences and line end character sequences. It is responsible for managing the styling process and for notifying other objects when changes occur to the document. </p> <h4> Editor </h4> <p> The Editor object is central to Scintilla. It is responsible for displaying a document and responding to user actions and requests from the container. It uses ContractionState, Indicator, LineMarker, Style, and ViewStyle objects to display the document and a KeyMap class to map key presses to functions. The visibility of each line is kept in the ContractionState which is also responsible for mapping from display lines to documents lines and vice versa. </p> <p> There may be multiple Editor objects attached to one Document object. Changes to a document are broadcast to the editors through the DocWatcher mechanism. </p> <h4> ScintillaBase </h4> <p> ScintillaBase is a subclass of Editor and adds extra windowing features including display of calltips, autocompletion lists and context menus. These features use CallTip and AutoComplete objects. This class is optional so a lightweight implementation of Scintilla may bypass it if the added functionality is not required. </p> <h3> Platform Events and API </h3> <p> Each platform uses different mechanisms for receiving events. On Windows, events are received through messages and COM. On GTK+, callback functions are used. </p> <p> For each platform, a class is derived from ScintillaBase (and thus from Editor). This is ScintillaWin on Windows and ScintillaGTK on GTK+. These classes are responsible for connecting to the platforms event mechanism and also to implement some virtual methods in Editor and ScintillaBase which are different on the platforms. For example, this layer has to support this difference between the synchronous Windows clipboard and the asynchronous GTK+ clipboard. </p> <p> The external API is defined in this layer as each platform has different preferred styles of API - messages on Windows and function calls on GTK+. This also allows multiple APIs to be defined on a platform. The currently available API on GTK+ is similar to the Windows API and does not follow platform conventions well. A second API could be implemented here that did follow platform conventions. </p> </body> </html> |
Added doc/Icons.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="HTML Tidy, see www.w3.org" /> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title> Scintilla icons </title> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5">Scintilla and SciTE</font></a> </td> </tr> </table> <h2> Icons </h2> <p> These images may be used under the same license as Scintilla. </p> <p> Drawn by Iago Rubio, Philippe Lhoste, and Neil Hodgson. </p> <p> <a href="http://prdownloads.sourceforge.net/scintilla/icons1.zip?download">zip format</a> (70K) </p> <table> <tr> <td>For autocompletion lists</td> <td colspan="3">For margin markers</td> </tr> <tr> <td>12x12</td> <td>16x16</td> <td>24x24</td> <td>32x32</td> </tr> <tr> <td valign="top"><img src="12.png" /></td> <td valign="top"><img src="16.png" /></td> <td valign="top"><img src="24.png" /></td> <td valign="top"><img src="32.png" /></td> </tr> </table> </body> </html> |
Added doc/Lexer.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
How to write a scintilla lexer A lexer for a particular language determines how a specified range of text shall be colored. Writing a lexer is relatively straightforward because the lexer need only color given text. The harder job of determining how much text actually needs to be colored is handled by Scintilla itself, that is, the lexer's caller. Parameters The lexer for language LLL has the following prototype: static void ColouriseLLLDoc ( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler); The styler parameter is an Accessor object. The lexer must use this object to access the text to be colored. The lexer gets the character at position i using styler.SafeGetCharAt(i); The startPos and length parameters indicate the range of text to be recolored; the lexer must determine the proper color for all characters in positions startPos through startPos+length. The initStyle parameter indicates the initial state, that is, the state at the character before startPos. States also indicate the coloring to be used for a particular range of text. Note: the character at StartPos is assumed to start a line, so if a newline terminates the initStyle state the lexer should enter its default state (or whatever state should follow initStyle). The keywordlists parameter specifies the keywords that the lexer must recognize. A WordList class object contains methods that make simplify the recognition of keywords. Present lexers use a helper function called classifyWordLLL to recognize keywords. These functions show how to use the keywordlists parameter to recognize keywords. This documentation will not discuss keywords further. The lexer code The task of a lexer can be summarized briefly: for each range r of characters that are to be colored the same, the lexer should call styler.ColourTo(i, state) where i is the position of the last character of the range r. The lexer should set the state variable to the coloring state of the character at position i and continue until the entire text has been colored. Note 1: the styler (Accessor) object remembers the i parameter in the previous calls to styler.ColourTo, so the single i parameter suffices to indicate a range of characters. Note 2: As a side effect of calling styler.ColourTo(i,state), the coloring states of all characters in the range are remembered so that Scintilla may set the initStyle parameter correctly on future calls to the lexer. Lexer organization There are at least two ways to organize the code of each lexer. Present lexers use what might be called a "character-based" approach: the outer loop iterates over characters, like this: lengthDoc = startPos + length ; for (unsigned int i = startPos; i < lengthDoc; i++) { chNext = styler.SafeGetCharAt(i + 1); << handle special cases >> switch(state) { // Handlers examine only ch and chNext. // Handlers call styler.ColorTo(i,state) if the state changes. case state_1: << handle ch in state 1 >> case state_2: << handle ch in state 2 >> ... case state_n: << handle ch in state n >> } chPrev = ch; } styler.ColourTo(lengthDoc - 1, state); An alternative would be to use a "state-based" approach. The outer loop would iterate over states, like this: lengthDoc = startPos+lenth ; for ( unsigned int i = startPos ;; ) { char ch = styler.SafeGetCharAt(i); int new_state = 0 ; switch ( state ) { // scanners set new_state if they set the next state. case state_1: << scan to the end of state 1 >> break ; case state_2: << scan to the end of state 2 >> break ; case default_state: << scan to the next non-default state and set new_state >> } styler.ColourTo(i, state); if ( i >= lengthDoc ) break ; if ( ! new_state ) { ch = styler.SafeGetCharAt(i); << set state based on ch in the default state >> } } styler.ColourTo(lengthDoc - 1, state); This approach might seem to be more natural. State scanners are simpler than character scanners because less needs to be done. For example, there is no need to test for the start of a C string inside the scanner for a C comment. Also this way makes it natural to define routines that could be used by more than one scanner; for example, a scanToEndOfLine routine. However, the special cases handled in the main loop in the character-based approach would have to be handled by each state scanner, so both approaches have advantages. These special cases are discussed below. Special case: Lead characters Lead bytes are part of DBCS processing for languages such as Japanese using an encoding such as Shift-JIS. In these encodings, extended (16-bit) characters are encoded as a lead byte followed by a trail byte. Lead bytes are rarely of any lexical significance, normally only being allowed within strings and comments. In such contexts, lexers should ignore ch if styler.IsLeadByte(ch) returns TRUE. Note: UTF-8 is simpler than Shift-JIS, so no special handling is applied for it. All UTF-8 extended characters are >= 128 and none are lexically significant in programming languages which, so far, use only characters in ASCII for operators, comment markers, etc. Special case: Folding Folding may be performed in the lexer function. It is better to use a separate folder function as that avoids some troublesome interaction between styling and folding. The folder function will be run after the lexer function if folding is enabled. The rest of this section explains how to perform folding within the lexer function. During initialization, lexers that support folding set bool fold = styler.GetPropertyInt("fold"); If folding is enabled in the editor, fold will be TRUE and the lexer should call: styler.SetLevel(line, level); at the end of each line and just before exiting. The line parameter is simply the count of the number of newlines seen. It's initial value is styler.GetLine(startPos) and it is incremented (after calling styler.SetLevel) whenever a newline is seen. The level parameter is the desired indentation level in the low 12 bits, along with flag bits in the upper four bits. The indentation level depends on the language. For C++, it is incremented when the lexer sees a '{' and decremented when the lexer sees a '}' (outside of strings and comments, of course). The following flag bits, defined in Scintilla.h, may be set or cleared in the flags parameter. The SC_FOLDLEVELWHITEFLAG flag is set if the lexer considers that the line contains nothing but whitespace. The SC_FOLDLEVELHEADERFLAG flag indicates that the line is a fold point. This normally means that the next line has a greater level than present line. However, the lexer may have some other basis for determining a fold point. For example, a lexer might create a header line for the first line of a function definition rather than the last. The SC_FOLDLEVELNUMBERMASK mask denotes the level number in the low 12 bits of the level param. This mask may be used to isolate either flags or level numbers. For example, the C++ lexer contains the following code when a newline is seen: if (fold) { int lev = levelPrev; // Set the "all whitespace" bit if the line is blank. if (visChars == 0) lev |= SC_FOLDLEVELWHITEFLAG; // Set the "header" bit if needed. if ((levelCurrent > levelPrev) && (visChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; styler.SetLevel(lineCurrent, lev); // reinitialize the folding vars describing the present line. lineCurrent++; visChars = 0; // Number of non-whitespace characters on the line. levelPrev = levelCurrent; } The following code appears in the C++ lexer just before exit: // Fill in the real level of the next line, keeping the current flags // as they will be filled in later. if (fold) { // Mask off the level number, leaving only the previous flags. int flagsNext = styler.LevelAt(lineCurrent); flagsNext &= ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } Don't worry about performance The writer of a lexer may safely ignore performance considerations: the cost of redrawing the screen is several orders of magnitude greater than the cost of function calls, etc. Moreover, Scintilla performs all the important optimizations; Scintilla ensures that a lexer will be called only to recolor text that actually needs to be recolored. Finally, it is not necessary to avoid extra calls to styler.ColourTo: the sytler object buffers calls to ColourTo to avoid multiple updates of the screen. Page contributed by Edward K. Ream |
Added doc/PaneAPI.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 |
<?xml version="1.0" encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="HTML Tidy, see www.w3.org" /> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html" /> <title> SciTE Pane API </title> <style type="text/css"> table { border: 1px solid #1F1F1F; border-collapse: collapse; font-family: Verdana, Arial, Helvetica } p { font-family: Verdana, Arial, Helvetica } td { border: 1px solid #1F1F1F; padding: 1px 5px 1px 5px; } th { border: 1px solid #1F1F1F; padding: 1px 5px 1px 5px; } .windowsonly { background: #EBF3FF; } .gtkonly { background: #FFFFE7; } .osxonly { background: #FFE7E7; } .example { color: #008000; font-weight: bold; } .comment { font-style:italic; font-size: 80%; } DIV.example { background: #F7FCF7; border: 1px solid #C0D7C0; margin: 0.3em 3em; padding: 0.3em 0.6em; font-size: 80%; } h2 { border: 2px solid #FFCC00; background-color: #FFF7EE; padding: 2px 5px; font-family: Verdana, Arial, Helvetica font-size: 180%; } h3 { border: 2px solid #FFCC00; background-color: #FFF7EE; padding: 2px 5px; } .header{ border: 1px solid #CCCCCC; } .headerlinks { padding: 7px; background-color: #CCCCCC; border: 0px solid #FF0000; font-size: 120%; } </style> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" style="border:0px solid #FF0000" border="0" summary="banner"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5"> SciTE Lua scripting of edit and output panes using Scintilla API</font></a> </td> </tr> </table> <h1>Scintilla API calls</h1> <p>Both the edit and output panes are Scintilla controls and can be scripted using Scintilla's API.</p> <p>The API is presented here as it is called from Lua for the edit pane. All of the same features are available for the output pane by substituting 'output' for 'editor'.</p> <p>In Lua methods are called with the ':' operator and properties accessed with the '.' operator. Properties are both readable and writeable by default and are otherwise marked "read-only" or "write-only".</p> <!-- <Autogenerated> --> <h2>Text retrieval and modification</h2> <p>string editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETTEXT'>GetText</a>()<span class="comment"> -- Retrieve all the text in the document. Returns number of characters retrieved.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETTEXT'>SetText</a>(string text)<span class="comment"> -- Replace the contents of the document with the argument text.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSAVEPOINT'>SetSavePoint</a>()<span class="comment"> -- Remember the current position in the undo history as the position at which the document was saved.</span></p> <p>string editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETLINE'>GetLine</a>(int line)<span class="comment"> -- Retrieve the contents of a line. Returns the length of the line.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_REPLACESEL'>ReplaceSel</a>(string text)<span class="comment"> -- Replace the selected text with the argument text.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETREADONLY'>ReadOnly</a><span class="comment"> -- Set to read only or read write.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ALLOCATE'>Allocate</a>(int bytes)<span class="comment"> -- Enlarge the document to a particular size of text bytes.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ADDTEXT'>AddText</a>(string text)<span class="comment"> -- Add text to the document at current position.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_APPENDTEXT'>AppendText</a>(string text)<span class="comment"> -- Append a string to the end of the document without changing the selection.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_INSERTTEXT'>InsertText</a>(position pos, string text)<span class="comment"> -- Insert string at a position.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CLEARALL'>ClearAll</a>()<span class="comment"> -- Delete all text in the document.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_DELETERANGE'>DeleteRange</a>(position pos, int deleteLength)<span class="comment"> -- Delete a range of text in the document.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CLEARDOCUMENTSTYLE'>ClearDocumentStyle</a>()<span class="comment"> -- Set all style bytes to 0, remove all folding information.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETCHARAT'>CharAt</a>[position pos] read-only</p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETSTYLEAT'>StyleAt</a>[position pos] read-only</p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSTYLEBITS'>StyleBits</a><span class="comment"> -- Divide each styling byte into lexical class bits (default: 5) and indicator bits (default: 3). If a lexer requires more than 32 lexical states, then this is used to expand the possible states.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_RELEASEALLEXTENDEDSTYLES'>ReleaseAllExtendedStyles</a>()<span class="comment"> -- Release all extended (>255) style numbers</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ALLOCATEEXTENDEDSTYLES'>AllocateExtendedStyles</a>(int numberStyles)<span class="comment"> -- Allocate some extended (>255) style numbers and return the start of the range</span></p> <p>string editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_TARGETASUTF8'>TargetAsUTF8</a>()<span class="comment"> -- Returns the target converted to UTF8. Return the length in bytes.</span></p> <p>string editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ENCODEDFROMUTF8'>EncodedFromUTF8</a>(string utf8)<span class="comment"> -- Translates a UTF8 string into the document encoding. Return the length of the result in bytes. On error return 0.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETLENGTHFORENCODE'>SetLengthForEncode</a>(int bytes)<span class="comment"> -- Set the length of the utf8 argument for calling EncodedFromUTF8. Set to -1 and the string will be measured to the first nul.</span></p> <h2>Searching</h2> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SEARCHANCHOR'>SearchAnchor</a>()<span class="comment"> -- Sets the current caret position to be the search anchor.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SEARCHNEXT'>SearchNext</a>(int flags, string text)<span class="comment"> -- Find some text starting at the search anchor. Does not ensure the selection is visible.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SEARCHPREV'>SearchPrev</a>(int flags, string text)<span class="comment"> -- Find some text starting at the search anchor and moving backwards. Does not ensure the selection is visible.</span></p> <p>position editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETTARGETSTART'>TargetStart</a><span class="comment"> -- Sets the position that starts the target which is used for updating the document without affecting the scroll position.</span></p> <p>position editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETTARGETEND'>TargetEnd</a><span class="comment"> -- Sets the position that ends the target which is used for updating the document without affecting the scroll position.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_TARGETFROMSELECTION'>TargetFromSelection</a>()<span class="comment"> -- Make the target range start and end be the same as the selection range start and end.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSEARCHFLAGS'>SearchFlags</a><span class="comment"> -- Set the search flags used by SearchInTarget.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SEARCHINTARGET'>SearchInTarget</a>(string text)<span class="comment"> -- Search for a counted string in the target and set the target to the found range. Text is counted so it can contain NULs. Returns length of range or -1 for failure in which case target is not moved.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_REPLACETARGET'>ReplaceTarget</a>(string text)<span class="comment"> -- Replace the target text with the argument text. Text is counted so it can contain NULs. Returns the length of the replacement text.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_REPLACETARGETRE'>ReplaceTargetRE</a>(string text)<span class="comment"> -- Replace the target text with the argument text after \d processing. Text is counted so it can contain NULs. Looks for \d where d is between 1 and 9 and replaces these with the strings matched in the last search operation which were surrounded by \( and \). Returns the length of the replacement text including any change caused by processing the \d patterns.</span></p> <p>string editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETTAG'>Tag</a>[int tagNumber] read-only</p> <h2>Overtype</h2> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETOVERTYPE'>Overtype</a><span class="comment"> -- Set to overtype (true) or insert mode.</span></p> <h2>Cut, copy and paste</h2> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CUT'>Cut</a>()<span class="comment"> -- Cut the selection to the clipboard.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_COPY'>Copy</a>()<span class="comment"> -- Copy the selection to the clipboard.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_PASTE'>Paste</a>()<span class="comment"> -- Paste the contents of the clipboard into the document replacing the selection.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CLEAR'>Clear</a>()<span class="comment"> -- Clear the selection.</span></p> <p>bool editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CANPASTE'>CanPaste</a>()<span class="comment"> -- Will a paste succeed?</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_COPYALLOWLINE'>CopyAllowLine</a>()<span class="comment"> -- Copy the selection, if selection empty copy the line with the caret</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_COPYRANGE'>CopyRange</a>(position start, position end)<span class="comment"> -- Copy a range of text to the clipboard. Positions are clipped into the document.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_COPYTEXT'>CopyText</a>(string text)<span class="comment"> -- Copy argument text to the clipboard.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETPASTECONVERTENDINGS'>PasteConvertEndings</a><span class="comment"> -- Enable/Disable convert-on-paste for line endings</span></p> <h2>Error handling</h2> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSTATUS'>Status</a><span class="comment"> -- Change error status - 0 = OK.</span></p> <h2>Undo and Redo</h2> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_UNDO'>Undo</a>()<span class="comment"> -- Undo one action in the undo history.</span></p> <p>bool editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CANUNDO'>CanUndo</a>()<span class="comment"> -- Are there any undoable actions in the undo history?</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_REDO'>Redo</a>()<span class="comment"> -- Redoes the next action on the undo history.</span></p> <p>bool editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CANREDO'>CanRedo</a>()<span class="comment"> -- Are there any redoable actions in the undo history?</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_EMPTYUNDOBUFFER'>EmptyUndoBuffer</a>()<span class="comment"> -- Delete the undo history.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETUNDOCOLLECTION'>UndoCollection</a><span class="comment"> -- Choose between collecting actions into the undo history and discarding them.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_BEGINUNDOACTION'>BeginUndoAction</a>()<span class="comment"> -- Start a sequence of actions that is undone and redone as a unit. May be nested.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ENDUNDOACTION'>EndUndoAction</a>()<span class="comment"> -- End a sequence of actions that is undone and redone as a unit.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ADDUNDOACTION'>AddUndoAction</a>(int token, int flags)<span class="comment"> -- Add a container action to the undo stack</span></p> <h2>Selection and information</h2> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETTEXTLENGTH'>TextLength</a> read-only</p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETLENGTH'>Length</a> read-only</p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETLINECOUNT'>LineCount</a> read-only</p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETFIRSTVISIBLELINE'>FirstVisibleLine</a><span class="comment"> -- Scroll so that a display line is at the top of the display.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_LINESONSCREEN'>LinesOnScreen</a> read-only</p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETMODIFY'>Modify</a> read-only</p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSEL'>SetSel</a>(position start, position end)<span class="comment"> -- Select a range of text.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GOTOPOS'>GotoPos</a>(position pos)<span class="comment"> -- Set caret to a position and ensure it is visible.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GOTOLINE'>GotoLine</a>(int line)<span class="comment"> -- Set caret to start of a line and ensure it is visible.</span></p> <p>position editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETCURRENTPOS'>CurrentPos</a><span class="comment"> -- Sets the position of the caret.</span></p> <p>position editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETANCHOR'>Anchor</a><span class="comment"> -- Set the selection anchor to a position. The anchor is the opposite end of the selection from the caret.</span></p> <p>position editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSELECTIONSTART'>SelectionStart</a><span class="comment"> -- Sets the position that starts the selection - this becomes the anchor.</span></p> <p>position editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSELECTIONEND'>SelectionEnd</a><span class="comment"> -- Sets the position that ends the selection - this becomes the currentPosition.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETEMPTYSELECTION'>SetEmptySelection</a>(position pos)<span class="comment"> -- Set caret to a position, while removing any existing selection.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SELECTALL'>SelectAll</a>()<span class="comment"> -- Select all the text in the document.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_LINEFROMPOSITION'>LineFromPosition</a>(position pos)<span class="comment"> -- Retrieve the line containing a position.</span></p> <p>position editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_POSITIONFROMLINE'>PositionFromLine</a>(int line)<span class="comment"> -- Retrieve the position at the start of a line.</span></p> <p>position editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETLINEENDPOSITION'>LineEndPosition</a>[int line] read-only</p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_LINELENGTH'>LineLength</a>(int line)<span class="comment"> -- How many characters are on a line, including end of line characters?</span></p> <p>string editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETSELTEXT'>GetSelText</a>()<span class="comment"> -- Retrieve the selected text. Return the length of the text.</span></p> <p>string editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETCURLINE'>GetCurLine</a>()<span class="comment"> -- Retrieve the text of the line containing the caret. Returns the index of the caret on the line.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SELECTIONISRECTANGLE'>SelectionIsRectangle</a> read-only</p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSELECTIONMODE'>SelectionMode</a><span class="comment"> -- Set the selection mode to stream (SC_SEL_STREAM) or rectangular (SC_SEL_RECTANGLE/SC_SEL_THIN) or by lines (SC_SEL_LINES).</span></p> <p>position editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETLINESELSTARTPOSITION'>GetLineSelStartPosition</a>(int line)<span class="comment"> -- Retrieve the position of the start of the selection at the given line (INVALID_POSITION if no selection on this line).</span></p> <p>position editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETLINESELENDPOSITION'>GetLineSelEndPosition</a>(int line)<span class="comment"> -- Retrieve the position of the end of the selection at the given line (INVALID_POSITION if no selection on this line).</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MOVECARETINSIDEVIEW'>MoveCaretInsideView</a>()<span class="comment"> -- Move the caret inside current view if it's not there already.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_WORDENDPOSITION'>WordEndPosition</a>(position pos, bool onlyWordCharacters)<span class="comment"> -- Get position of end of word.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_WORDSTARTPOSITION'>WordStartPosition</a>(position pos, bool onlyWordCharacters)<span class="comment"> -- Get position of start of word.</span></p> <p>position editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_POSITIONBEFORE'>PositionBefore</a>(position pos)<span class="comment"> -- Given a valid document position, return the previous position taking code page into account. Returns 0 if passed 0.</span></p> <p>position editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_POSITIONAFTER'>PositionAfter</a>(position pos)<span class="comment"> -- Given a valid document position, return the next position taking code page into account. Maximum value returned is the last position in the document.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_COUNTCHARACTERS'>CountCharacters</a>(int startPos, int endPos)<span class="comment"> -- Count characters between two positions.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_TEXTWIDTH'>TextWidth</a>(int style, string text)<span class="comment"> -- Measure the pixel width of some text in a particular style. NUL terminated text argument. Does not handle tab or control characters.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_TEXTHEIGHT'>TextHeight</a>(int line)<span class="comment"> -- Retrieve the height of a particular line of text in pixels.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETCOLUMN'>Column</a>[position pos] read-only</p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_FINDCOLUMN'>FindColumn</a>(int line, int column)<span class="comment"> -- Find the position of a column on a line taking into account tabs and multi-byte characters. If beyond end of line, return line end position.</span></p> <p>position editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_POSITIONFROMPOINT'>PositionFromPoint</a>(int x, int y)<span class="comment"> -- Find the position from a point within the window.</span></p> <p>position editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_POSITIONFROMPOINTCLOSE'>PositionFromPointClose</a>(int x, int y)<span class="comment"> -- Find the position from a point within the window but return INVALID_POSITION if not close to text.</span></p> <p>position editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CHARPOSITIONFROMPOINT'>CharPositionFromPoint</a>(int x, int y)<span class="comment"> -- Find the position of a character from a point within the window.</span></p> <p>position editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CHARPOSITIONFROMPOINTCLOSE'>CharPositionFromPointClose</a>(int x, int y)<span class="comment"> -- Find the position of a character from a point within the window. Return INVALID_POSITION if not close to text.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_POINTXFROMPOSITION'>PointXFromPosition</a>(position pos)<span class="comment"> -- Retrieve the x value of the point in the window where a position is displayed.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_POINTYFROMPOSITION'>PointYFromPosition</a>(position pos)<span class="comment"> -- Retrieve the y value of the point in the window where a position is displayed.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_HIDESELECTION'>HideSelection</a>(bool normal)<span class="comment"> -- Draw the selection in normal style or with selection highlighted.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CHOOSECARETX'>ChooseCaretX</a>()<span class="comment"> -- Set the last x chosen value to be the caret x position.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MOVESELECTEDLINESUP'>MoveSelectedLinesUp</a>()<span class="comment"> -- Move the selected lines up one line, shifting the line above after the selection</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MOVESELECTEDLINESDOWN'>MoveSelectedLinesDown</a>()<span class="comment"> -- Move the selected lines down one line, shifting the line below before the selection</span></p> <h2>Multiple Selection and Virtual Space</h2> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETMULTIPLESELECTION'>MultipleSelection</a><span class="comment"> -- Set whether multiple selections can be made</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETADDITIONALSELECTIONTYPING'>AdditionalSelectionTyping</a><span class="comment"> -- Set whether typing can be performed into multiple selections</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETMULTIPASTE'>MultiPaste</a><span class="comment"> -- Change the effect of pasting when there are multiple selections.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETVIRTUALSPACEOPTIONS'>VirtualSpaceOptions</a><span class="comment"> -- Returns the position at the end of the selection.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETRECTANGULARSELECTIONMODIFIER'>RectangularSelectionModifier</a><span class="comment"> -- On GTK+, allow selecting the modifier key to use for mouse-based rectangular selection. Often the window manager requires Alt+Mouse Drag for moving windows. Valid values are SCMOD_CTRL(default), SCMOD_ALT, or SCMOD_SUPER.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETSELECTIONS'>Selections</a> read-only</p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETSELECTIONEMPTY'>SelectionEmpty</a> read-only</p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CLEARSELECTIONS'>ClearSelections</a>()<span class="comment"> -- Clear selections to a single empty stream selection</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSELECTION'>SetSelection</a>(int caret, int anchor)<span class="comment"> -- Set a simple selection</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ADDSELECTION'>AddSelection</a>(int caret, int anchor)<span class="comment"> -- Add a selection</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETMAINSELECTION'>MainSelection</a><span class="comment"> -- Set the main selection</span></p> <p>position editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSELECTIONNCARET'>SelectionNCaret</a>[int selection]<span class="comment"> -- Which selection is the main selection</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSELECTIONNCARETVIRTUALSPACE'>SelectionNCaretVirtualSpace</a>[int selection]<span class="comment"> -- Which selection is the main selection</span></p> <p>position editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSELECTIONNANCHOR'>SelectionNAnchor</a>[int selection]<span class="comment"> -- Which selection is the main selection</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSELECTIONNANCHORVIRTUALSPACE'>SelectionNAnchorVirtualSpace</a>[int selection]<span class="comment"> -- Which selection is the main selection</span></p> <p>position editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSELECTIONNSTART'>SelectionNStart</a>[int selection]<span class="comment"> -- Sets the position that starts the selection - this becomes the anchor.</span></p> <p>position editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSELECTIONNEND'>SelectionNEnd</a>[int selection]<span class="comment"> -- Sets the position that ends the selection - this becomes the currentPosition.</span></p> <p>position editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETRECTANGULARSELECTIONCARET'>RectangularSelectionCaret</a><span class="comment"> -- Returns the position at the end of the selection.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETRECTANGULARSELECTIONCARETVIRTUALSPACE'>RectangularSelectionCaretVirtualSpace</a><span class="comment"> -- Returns the position at the end of the selection.</span></p> <p>position editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETRECTANGULARSELECTIONANCHOR'>RectangularSelectionAnchor</a><span class="comment"> -- Returns the position at the end of the selection.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETRECTANGULARSELECTIONANCHORVIRTUALSPACE'>RectangularSelectionAnchorVirtualSpace</a><span class="comment"> -- Returns the position at the end of the selection.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETADDITIONALSELALPHA'>AdditionalSelAlpha</a><span class="comment"> -- Set the alpha of the selection.</span></p> <p>colour editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETADDITIONALSELFORE'>AdditionalSelFore</a> write-only<span class="comment"> -- Set the foreground colour of additional selections. Must have previously called SetSelFore with non-zero first argument for this to have an effect.</span></p> <p>colour editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETADDITIONALSELBACK'>AdditionalSelBack</a> write-only<span class="comment"> -- Set the background colour of additional selections. Must have previously called SetSelBack with non-zero first argument for this to have an effect.</span></p> <p>colour editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETADDITIONALCARETFORE'>AdditionalCaretFore</a><span class="comment"> -- Set the foreground colour of additional carets.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETADDITIONALCARETSBLINK'>AdditionalCaretsBlink</a><span class="comment"> -- Set whether additional carets will blink</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETADDITIONALCARETSVISIBLE'>AdditionalCaretsVisible</a><span class="comment"> -- Set whether additional carets are visible</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SWAPMAINANCHORCARET'>SwapMainAnchorCaret</a>()<span class="comment"> -- Swap that caret and anchor of the main selection.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ROTATESELECTION'>RotateSelection</a>()<span class="comment"> -- Set the main selection to the next selection.</span></p> <h2>Scrolling and automatic scrolling</h2> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_LINESCROLL'>LineScroll</a>(int columns, int lines)<span class="comment"> -- Scroll horizontally and vertically.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SCROLLCARET'>ScrollCaret</a>()<span class="comment"> -- Ensure the caret is visible.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETXCARETPOLICY'>SetXCaretPolicy</a>(int caretPolicy, int caretSlop)<span class="comment"> -- Set the way the caret is kept visible when going sideways. The exclusion zone is given in pixels.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETYCARETPOLICY'>SetYCaretPolicy</a>(int caretPolicy, int caretSlop)<span class="comment"> -- Set the way the line the caret is on is kept visible. The exclusion zone is given in lines.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETVISIBLEPOLICY'>SetVisiblePolicy</a>(int visiblePolicy, int visibleSlop)<span class="comment"> -- Set the way the display area is determined when a particular line is to be moved to by Find, FindNext, GotoLine, etc.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETHSCROLLBAR'>HScrollBar</a><span class="comment"> -- Show or hide the horizontal scroll bar.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETVSCROLLBAR'>VScrollBar</a><span class="comment"> -- Show or hide the vertical scroll bar.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETXOFFSET'>XOffset</a><span class="comment"> -- Get and Set the xOffset (ie, horizontal scroll position).</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSCROLLWIDTH'>ScrollWidth</a><span class="comment"> -- Sets the document width assumed for scrolling.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSCROLLWIDTHTRACKING'>ScrollWidthTracking</a><span class="comment"> -- Sets whether the maximum width line displayed is used to set scroll width.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETENDATLASTLINE'>EndAtLastLine</a><span class="comment"> -- Sets the scroll range so that maximum scroll position has the last line at the bottom of the view (default). Setting this to false allows scrolling one page below the last line.</span></p> <h2>White space</h2> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETVIEWWS'>ViewWS</a><span class="comment"> -- Make white space characters invisible, always visible or visible outside indentation.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETWHITESPACEFORE'>SetWhitespaceFore</a>(bool useSetting, colour fore)<span class="comment"> -- Set the foreground colour of all whitespace and whether to use this setting.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETWHITESPACEBACK'>SetWhitespaceBack</a>(bool useSetting, colour back)<span class="comment"> -- Set the background colour of all whitespace and whether to use this setting.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETWHITESPACESIZE'>WhitespaceSize</a><span class="comment"> -- Set the size of the dots used to mark space characters.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETEXTRAASCENT'>ExtraAscent</a><span class="comment"> -- Set extra ascent for each line</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETEXTRADESCENT'>ExtraDescent</a><span class="comment"> -- Set extra descent for each line</span></p> <h2>Cursor</h2> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETCURSOR'>Cursor</a><span class="comment"> -- Sets the cursor to one of the SC_CURSOR* values.</span></p> <h2>Mouse capture</h2> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETMOUSEDOWNCAPTURES'>MouseDownCaptures</a><span class="comment"> -- Set whether the mouse is captured when its button is pressed.</span></p> <h2>Line endings</h2> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETEOLMODE'>EOLMode</a><span class="comment"> -- Set the current end of line mode.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CONVERTEOLS'>ConvertEOLs</a>(int eolMode)<span class="comment"> -- Convert all line endings in the document to one mode.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETVIEWEOL'>ViewEOL</a><span class="comment"> -- Make the end of line characters visible or invisible.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETLINEENDTYPESSUPPORTED'>LineEndTypesSupported</a> read-only</p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETLINEENDTYPESALLOWED'>LineEndTypesAllowed</a><span class="comment"> -- Set the line end types that the application wants to use. May not be used if incompatible with lexer or encoding.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETLINEENDTYPESACTIVE'>LineEndTypesActive</a> read-only</p> <h2>Styling</h2> <p>position editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETENDSTYLED'>EndStyled</a> read-only</p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STARTSTYLING'>StartStyling</a>(position pos, int mask)<span class="comment"> -- Set the current styling position to pos and the styling mask to mask. The styling mask can be used to protect some bits in each styling byte from modification.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSTYLING'>SetStyling</a>(int length, int style)<span class="comment"> -- Change style from current styling position for length characters to a style and move the current styling position to after this newly styled segment.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSTYLINGEX'>SetStylingEx</a>(string styles)<span class="comment"> -- Set the styles for a segment of the document.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETLINESTATE'>LineState</a>[int line]<span class="comment"> -- Used to hold extra styling information for each line.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETMAXLINESTATE'>MaxLineState</a> read-only</p> <h2>Style definition</h2> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STYLERESETDEFAULT'>StyleResetDefault</a>()<span class="comment"> -- Reset the default style to its state at startup</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STYLECLEARALL'>StyleClearAll</a>()<span class="comment"> -- Clear all the styles and make equivalent to the global default style.</span></p> <p>string editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STYLESETFONT'>StyleFont</a>[int style]<span class="comment"> -- Set the font of a style.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STYLESETSIZE'>StyleSize</a>[int style]<span class="comment"> -- Set the size of characters of a style.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STYLESETSIZEFRACTIONAL'>StyleSizeFractional</a>[int style]<span class="comment"> -- Set the size of characters of a style. Size is in points multiplied by 100.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STYLESETBOLD'>StyleBold</a>[int style]<span class="comment"> -- Set a style to be bold or not.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STYLESETWEIGHT'>StyleWeight</a>[int style]<span class="comment"> -- Set the weight of characters of a style.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STYLESETITALIC'>StyleItalic</a>[int style]<span class="comment"> -- Set a style to be italic or not.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STYLESETUNDERLINE'>StyleUnderline</a>[int style]<span class="comment"> -- Set a style to be underlined or not.</span></p> <p>colour editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STYLESETFORE'>StyleFore</a>[int style]<span class="comment"> -- Set the foreground colour of a style.</span></p> <p>colour editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STYLESETBACK'>StyleBack</a>[int style]<span class="comment"> -- Set the background colour of a style.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STYLESETEOLFILLED'>StyleEOLFilled</a>[int style]<span class="comment"> -- Set a style to have its end of line filled or not.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STYLESETCHARACTERSET'>StyleCharacterSet</a>[int style]<span class="comment"> -- Set the character set of the font in a style.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STYLESETCASE'>StyleCase</a>[int style]<span class="comment"> -- Set a style to be mixed case, or to force upper or lower case.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STYLESETVISIBLE'>StyleVisible</a>[int style]<span class="comment"> -- Set a style to be visible or not.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STYLESETCHANGEABLE'>StyleChangeable</a>[int style]<span class="comment"> -- Set a style to be changeable or not (read only). Experimental feature, currently buggy.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STYLESETHOTSPOT'>StyleHotSpot</a>[int style]<span class="comment"> -- Set a style to be a hotspot or not.</span></p> <h2>Caret, selection, and hotspot styles</h2> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSELFORE'>SetSelFore</a>(bool useSetting, colour fore)<span class="comment"> -- Set the foreground colour of the main and additional selections and whether to use this setting.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSELBACK'>SetSelBack</a>(bool useSetting, colour back)<span class="comment"> -- Set the background colour of the main and additional selections and whether to use this setting.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSELALPHA'>SelAlpha</a><span class="comment"> -- Set the alpha of the selection.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETSELEOLFILLED'>SelEOLFilled</a><span class="comment"> -- Set the selection to have its end of line filled or not.</span></p> <p>colour editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETCARETFORE'>CaretFore</a><span class="comment"> -- Set the foreground colour of the caret.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETCARETLINEVISIBLE'>CaretLineVisible</a><span class="comment"> -- Display the background of the line containing the caret in a different colour.</span></p> <p>colour editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETCARETLINEBACK'>CaretLineBack</a><span class="comment"> -- Set the colour of the background of the line containing the caret.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETCARETLINEBACKALPHA'>CaretLineBackAlpha</a><span class="comment"> -- Set background alpha of the caret line.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETCARETLINEVISIBLEALWAYS'>CaretLineVisibleAlways</a><span class="comment"> -- Sets the caret line to always visible.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETCARETPERIOD'>CaretPeriod</a><span class="comment"> -- Get the time in milliseconds that the caret is on and off. 0 = steady on.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETCARETSTYLE'>CaretStyle</a><span class="comment"> -- Set the style of the caret to be drawn.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETCARETWIDTH'>CaretWidth</a><span class="comment"> -- Set the width of the insert mode caret.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETHOTSPOTACTIVEFORE'>SetHotspotActiveFore</a>(bool useSetting, colour fore)<span class="comment"> -- Set a fore colour for active hotspots.</span></p> <p>colour editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETHOTSPOTACTIVEFORE'>GetHotspotActiveFore</a>()<span class="comment"> -- Get the fore colour for active hotspots.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETHOTSPOTACTIVEBACK'>SetHotspotActiveBack</a>(bool useSetting, colour back)<span class="comment"> -- Set a back colour for active hotspots.</span></p> <p>colour editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETHOTSPOTACTIVEBACK'>GetHotspotActiveBack</a>()<span class="comment"> -- Get the back colour for active hotspots.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETHOTSPOTACTIVEUNDERLINE'>HotspotActiveUnderline</a><span class="comment"> -- Enable / Disable underlining active hotspots.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETHOTSPOTSINGLELINE'>HotspotSingleLine</a><span class="comment"> -- Limit hotspots to single line so hotspots on two lines don't merge.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETCONTROLCHARSYMBOL'>ControlCharSymbol</a><span class="comment"> -- Change the way control characters are displayed: If symbol is < 32, keep the drawn way, else, use the given character.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETCARETSTICKY'>CaretSticky</a><span class="comment"> -- Stop the caret preferred x position changing when the user types.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_TOGGLECARETSTICKY'>ToggleCaretSticky</a>()<span class="comment"> -- Switch between sticky and non-sticky: meant to be bound to a key.</span></p> <h2>Margins</h2> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETMARGINTYPEN'>MarginTypeN</a>[int margin]<span class="comment"> -- Set a margin to be either numeric or symbolic.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETMARGINWIDTHN'>MarginWidthN</a>[int margin]<span class="comment"> -- Set the width of a margin to a width expressed in pixels.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETMARGINMASKN'>MarginMaskN</a>[int margin]<span class="comment"> -- Set a mask that determines which markers are displayed in a margin.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETMARGINSENSITIVEN'>MarginSensitiveN</a>[int margin]<span class="comment"> -- Make a margin sensitive or insensitive to mouse clicks.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETMARGINCURSORN'>MarginCursorN</a>[int margin]<span class="comment"> -- Set the cursor shown when the mouse is inside a margin.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETMARGINLEFT'>MarginLeft</a><span class="comment"> -- Sets the size in pixels of the left margin.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETMARGINRIGHT'>MarginRight</a><span class="comment"> -- Sets the size in pixels of the right margin.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETFOLDMARGINCOLOUR'>SetFoldMarginColour</a>(bool useSetting, colour back)<span class="comment"> -- Set the colours used as a chequerboard pattern in the fold margin</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETFOLDMARGINHICOLOUR'>SetFoldMarginHiColour</a>(bool useSetting, colour fore)<span class="comment"> -- Set the colours used as a chequerboard pattern in the fold margin</span></p> <p>string editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARGINSETTEXT'>MarginText</a>[int line]<span class="comment"> -- Set the text in the text margin for a line</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARGINSETSTYLE'>MarginStyle</a>[int line]<span class="comment"> -- Set the style number for the text margin for a line</span></p> <p>string editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARGINSETSTYLES'>MarginStyles</a>[int line]<span class="comment"> -- Set the style in the text margin for a line</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARGINTEXTCLEARALL'>MarginTextClearAll</a>()<span class="comment"> -- Clear the margin text on all lines</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARGINSETSTYLEOFFSET'>MarginStyleOffset</a><span class="comment"> -- Get the start of the range of style numbers used for margin text</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETMARGINOPTIONS'>MarginOptions</a><span class="comment"> -- Set the margin options.</span></p> <h2>Annotations</h2> <p>string editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ANNOTATIONSETTEXT'>AnnotationText</a>[int line]<span class="comment"> -- Set the annotation text for a line</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ANNOTATIONSETSTYLE'>AnnotationStyle</a>[int line]<span class="comment"> -- Set the style number for the annotations for a line</span></p> <p>string editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ANNOTATIONSETSTYLES'>AnnotationStyles</a>[int line]<span class="comment"> -- Set the annotation styles for a line</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ANNOTATIONGETLINES'>AnnotationLines</a>[int line] read-only</p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ANNOTATIONCLEARALL'>AnnotationClearAll</a>()<span class="comment"> -- Clear the annotations from all lines</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ANNOTATIONSETVISIBLE'>AnnotationVisible</a><span class="comment"> -- Set the visibility for the annotations for a view</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ANNOTATIONSETSTYLEOFFSET'>AnnotationStyleOffset</a><span class="comment"> -- Get the start of the range of style numbers used for annotations</span></p> <h2>Other settings</h2> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETBUFFEREDDRAW'>BufferedDraw</a><span class="comment"> -- If drawing is buffered then each line of text is drawn into a bitmap buffer before drawing it to the screen to avoid flicker.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETTWOPHASEDRAW'>TwoPhaseDraw</a><span class="comment"> -- In twoPhaseDraw mode, drawing is performed in two phases, first the background and then the foreground. This avoids chopping off characters that overlap the next run.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETTECHNOLOGY'>Technology</a><span class="comment"> -- Set the technology used.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETFONTQUALITY'>FontQuality</a><span class="comment"> -- Choose the quality level for text from the FontQuality enumeration.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETCODEPAGE'>CodePage</a><span class="comment"> -- Set the code page used to interpret the bytes of the document as characters. The SC_CP_UTF8 value can be used to enter Unicode mode.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETKEYSUNICODE'>KeysUnicode</a><span class="comment"> -- Always interpret keyboard input as Unicode</span></p> <p>string editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETWORDCHARS'>WordChars</a><span class="comment"> -- Set the set of characters making up words for when moving or selecting by word. First sets defaults like SetCharsDefault.</span></p> <p>string editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETWHITESPACECHARS'>WhitespaceChars</a><span class="comment"> -- Set the set of characters making up whitespace for when moving or selecting by word. Should be called after SetWordChars.</span></p> <p>string editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETPUNCTUATIONCHARS'>PunctuationChars</a><span class="comment"> -- Set the set of characters making up punctuation characters Should be called after SetWordChars.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETCHARSDEFAULT'>SetCharsDefault</a>()<span class="comment"> -- Reset the set of characters for whitespace and word characters to the defaults.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GRABFOCUS'>GrabFocus</a>()<span class="comment"> -- Set the focus to this Scintilla widget.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETFOCUS'>Focus</a><span class="comment"> -- Change internal focus flag.</span></p> <h2>Brace highlighting</h2> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_BRACEHIGHLIGHT'>BraceHighlight</a>(position pos1, position pos2)<span class="comment"> -- Highlight the characters at two positions.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_BRACEBADLIGHT'>BraceBadLight</a>(position pos)<span class="comment"> -- Highlight the character at a position indicating there is no matching brace.</span></p> <p>position editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_BRACEMATCH'>BraceMatch</a>(position pos)<span class="comment"> -- Find the position of a matching brace or INVALID_POSITION if no match.</span></p> <h2>Tabs and Indentation Guides</h2> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETTABWIDTH'>TabWidth</a><span class="comment"> -- Change the visible size of a tab to be a multiple of the width of a space character.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETUSETABS'>UseTabs</a><span class="comment"> -- Indentation will only use space characters if useTabs is false, otherwise it will use a combination of tabs and spaces.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETINDENT'>Indent</a><span class="comment"> -- Set the number of spaces used for one level of indentation.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETTABINDENTS'>TabIndents</a><span class="comment"> -- Sets whether a tab pressed when caret is within indentation indents.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETBACKSPACEUNINDENTS'>BackSpaceUnIndents</a><span class="comment"> -- Sets whether a backspace pressed when caret is within indentation unindents.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETLINEINDENTATION'>LineIndentation</a>[int line]<span class="comment"> -- Change the indentation of a line to a number of columns.</span></p> <p>position editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETLINEINDENTPOSITION'>LineIndentPosition</a>[int line] read-only</p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETINDENTATIONGUIDES'>IndentationGuides</a><span class="comment"> -- Show or hide indentation guides.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETHIGHLIGHTGUIDE'>HighlightGuide</a><span class="comment"> -- Set the highlighted indentation guide column. 0 = no highlighted guide.</span></p> <h2>Markers</h2> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERDEFINE'>MarkerDefine</a>(int markerNumber, int markerSymbol)<span class="comment"> -- Set the symbol used for a particular marker number.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERDEFINEPIXMAP'>MarkerDefinePixmap</a>(int markerNumber, string pixmap)<span class="comment"> -- Define a marker from a pixmap.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_RGBAIMAGESETWIDTH'>RGBAImageWidth</a> write-only<span class="comment"> -- Set the width for future RGBA image data.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_RGBAIMAGESETHEIGHT'>RGBAImageHeight</a> write-only<span class="comment"> -- Set the height for future RGBA image data.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_RGBAIMAGESETSCALE'>RGBAImageScale</a> write-only<span class="comment"> -- Set the scale factor in percent for future RGBA image data.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERDEFINERGBAIMAGE'>MarkerDefineRGBAImage</a>(int markerNumber, string pixels)<span class="comment"> -- Define a marker from RGBA data. It has the width and height from RGBAImageSetWidth/Height</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERSYMBOLDEFINED'>MarkerSymbolDefined</a>(int markerNumber)<span class="comment"> -- Which symbol was defined for markerNumber with MarkerDefine</span></p> <p>colour editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERSETFORE'>MarkerFore</a>[int markerNumber] write-only<span class="comment"> -- Set the foreground colour used for a particular marker number.</span></p> <p>colour editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERSETBACK'>MarkerBack</a>[int markerNumber] write-only<span class="comment"> -- Set the background colour used for a particular marker number.</span></p> <p>colour editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERSETBACKSELECTED'>MarkerBackSelected</a>[int markerNumber] write-only<span class="comment"> -- Set the background colour used for a particular marker number when its folding block is selected.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERENABLEHIGHLIGHT'>MarkerEnableHighlight</a>(bool enabled)<span class="comment"> -- Enable/disable highlight for current folding bloc (smallest one that contains the caret)</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERSETALPHA'>MarkerAlpha</a>[int markerNumber] write-only<span class="comment"> -- Set the alpha used for a marker that is drawn in the text area, not the margin.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERADD'>MarkerAdd</a>(int line, int markerNumber)<span class="comment"> -- Add a marker to a line, returning an ID which can be used to find or delete the marker.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERADDSET'>MarkerAddSet</a>(int line, int set)<span class="comment"> -- Add a set of markers to a line.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERDELETE'>MarkerDelete</a>(int line, int markerNumber)<span class="comment"> -- Delete a marker from a line.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERDELETEALL'>MarkerDeleteAll</a>(int markerNumber)<span class="comment"> -- Delete all markers with a particular number from all lines.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERGET'>MarkerGet</a>(int line)<span class="comment"> -- Get a bit mask of all the markers set on a line.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERNEXT'>MarkerNext</a>(int lineStart, int markerMask)<span class="comment"> -- Find the next line at or after lineStart that includes a marker in mask. Return -1 when no more lines.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERPREVIOUS'>MarkerPrevious</a>(int lineStart, int markerMask)<span class="comment"> -- Find the previous line before lineStart that includes a marker in mask.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERLINEFROMHANDLE'>MarkerLineFromHandle</a>(int handle)<span class="comment"> -- Retrieve the line number at which a particular marker is located.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_MARKERDELETEHANDLE'>MarkerDeleteHandle</a>(int handle)<span class="comment"> -- Delete a marker.</span></p> <h2>Indicators</h2> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_INDICSETSTYLE'>IndicStyle</a>[int indic]<span class="comment"> -- Set an indicator to plain, squiggle or TT.</span></p> <p>colour editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_INDICSETFORE'>IndicFore</a>[int indic]<span class="comment"> -- Set the foreground colour of an indicator.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_INDICSETALPHA'>IndicAlpha</a>[int indicator]<span class="comment"> -- Set the alpha fill colour of the given indicator.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_INDICSETOUTLINEALPHA'>IndicOutlineAlpha</a>[int indicator]<span class="comment"> -- Set the alpha outline colour of the given indicator.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_INDICSETUNDER'>IndicUnder</a>[int indic]<span class="comment"> -- Set an indicator to draw under text or over(default).</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETINDICATORCURRENT'>IndicatorCurrent</a><span class="comment"> -- Set the indicator used for IndicatorFillRange and IndicatorClearRange</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETINDICATORVALUE'>IndicatorValue</a><span class="comment"> -- Set the value used for IndicatorFillRange</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_INDICATORFILLRANGE'>IndicatorFillRange</a>(int position, int fillLength)<span class="comment"> -- Turn a indicator on over a range.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_INDICATORCLEARRANGE'>IndicatorClearRange</a>(int position, int clearLength)<span class="comment"> -- Turn a indicator off over a range.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_INDICATORALLONFOR'>IndicatorAllOnFor</a>(int position)<span class="comment"> -- Are any indicators present at position?</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_INDICATORVALUEAT'>IndicatorValueAt</a>(int indicator, int position)<span class="comment"> -- What value does a particular indicator have at at a position?</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_INDICATORSTART'>IndicatorStart</a>(int indicator, int position)<span class="comment"> -- Where does a particular indicator start?</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_INDICATOREND'>IndicatorEnd</a>(int indicator, int position)<span class="comment"> -- Where does a particular indicator end?</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_FINDINDICATORSHOW'>FindIndicatorShow</a>(position start, position end)<span class="comment"> -- On OS X, show a find indicator.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_FINDINDICATORFLASH'>FindIndicatorFlash</a>(position start, position end)<span class="comment"> -- On OS X, flash a find indicator, then fade out.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_FINDINDICATORHIDE'>FindIndicatorHide</a>()<span class="comment"> -- On OS X, hide the find indicator.</span></p> <h2>Autocompletion</h2> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCSHOW'>AutoCShow</a>(int lenEntered, string itemList)<span class="comment"> -- Display a auto-completion list. The lenEntered parameter indicates how many characters before the caret should be used to provide context.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCCANCEL'>AutoCCancel</a>()<span class="comment"> -- Remove the auto-completion list from the screen.</span></p> <p>bool editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCACTIVE'>AutoCActive</a>()<span class="comment"> -- Is there an auto-completion list visible?</span></p> <p>position editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCPOSSTART'>AutoCPosStart</a>()<span class="comment"> -- Retrieve the position of the caret when the auto-completion list was displayed.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCCOMPLETE'>AutoCComplete</a>()<span class="comment"> -- User has selected an item so remove the list and insert the selection.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCSTOPS'>AutoCStops</a>(string characterSet)<span class="comment"> -- Define a set of character that when typed cancel the auto-completion list.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCSETSEPARATOR'>AutoCSeparator</a><span class="comment"> -- Change the separator character in the string setting up an auto-completion list. Default is space but can be changed if items contain space.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCSELECT'>AutoCSelect</a>(string text)<span class="comment"> -- Select the item in the auto-completion list that starts with a string.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCGETCURRENT'>AutoCCurrent</a> read-only</p> <p>string editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCGETCURRENTTEXT'>AutoCCurrentText</a> read-only</p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCSETCANCELATSTART'>AutoCCancelAtStart</a><span class="comment"> -- Should the auto-completion list be cancelled if the user backspaces to a position before where the box was created.</span></p> <p>string editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCSETFILLUPS'>AutoCFillUps</a> write-only<span class="comment"> -- Define a set of characters that when typed will cause the autocompletion to choose the selected item.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCSETCHOOSESINGLE'>AutoCChooseSingle</a><span class="comment"> -- Should a single item auto-completion list automatically choose the item.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCSETIGNORECASE'>AutoCIgnoreCase</a><span class="comment"> -- Set whether case is significant when performing auto-completion searches.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR'>AutoCCaseInsensitiveBehaviour</a><span class="comment"> -- Set auto-completion case insensitive behaviour to either prefer case-sensitive matches or have no preference.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCSETAUTOHIDE'>AutoCAutoHide</a><span class="comment"> -- Set whether or not autocompletion is hidden automatically when nothing matches.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCSETDROPRESTOFWORD'>AutoCDropRestOfWord</a><span class="comment"> -- Set whether or not autocompletion deletes any word characters after the inserted text upon completion.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_REGISTERIMAGE'>RegisterImage</a>(int type, string xpmData)<span class="comment"> -- Register an XPM image for use in autocompletion lists.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_REGISTERRGBAIMAGE'>RegisterRGBAImage</a>(int type, string pixels)<span class="comment"> -- Register an RGBA image for use in autocompletion lists. It has the width and height from RGBAImageSetWidth/Height</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CLEARREGISTEREDIMAGES'>ClearRegisteredImages</a>()<span class="comment"> -- Clear all the registered XPM images.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCSETTYPESEPARATOR'>AutoCTypeSeparator</a><span class="comment"> -- Change the type-separator character in the string setting up an auto-completion list. Default is '?' but can be changed if items contain '?'.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCSETMAXHEIGHT'>AutoCMaxHeight</a><span class="comment"> -- Set the maximum height, in rows, of auto-completion and user lists. The default is 5 rows.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_AUTOCSETMAXWIDTH'>AutoCMaxWidth</a><span class="comment"> -- Set the maximum width, in characters, of auto-completion and user lists. Set to 0 to autosize to fit longest item, which is the default.</span></p> <h2>User lists</h2> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_USERLISTSHOW'>UserListShow</a>(int listType, string itemList)<span class="comment"> -- Display a list of strings and send notification when user chooses one.</span></p> <h2>Call tips</h2> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CALLTIPSHOW'>CallTipShow</a>(position pos, string definition)<span class="comment"> -- Show a call tip containing a definition near position pos.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CALLTIPCANCEL'>CallTipCancel</a>()<span class="comment"> -- Remove the call tip from the screen.</span></p> <p>bool editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CALLTIPACTIVE'>CallTipActive</a>()<span class="comment"> -- Is there an active call tip?</span></p> <p>position editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CALLTIPPOSSTART'>CallTipPosStart</a>()<span class="comment"> -- Retrieve the position where the caret was before displaying the call tip.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CALLTIPSETHLT'>CallTipSetHlt</a>(int start, int end)<span class="comment"> -- Highlight a segment of the definition.</span></p> <p>colour editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CALLTIPSETBACK'>CallTipBack</a> write-only<span class="comment"> -- Set the background colour for the call tip.</span></p> <p>colour editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CALLTIPSETFORE'>CallTipFore</a> write-only<span class="comment"> -- Set the foreground colour for the call tip.</span></p> <p>colour editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CALLTIPSETFOREHLT'>CallTipForeHlt</a> write-only<span class="comment"> -- Set the foreground colour for the highlighted part of the call tip.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CALLTIPUSESTYLE'>CallTipUseStyle</a> write-only<span class="comment"> -- Enable use of STYLE_CALLTIP and set call tip tab size in pixels.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CALLTIPSETPOSITION'>CallTipPosition</a> write-only<span class="comment"> -- Set position of calltip, above or below text.</span></p> <h2>Key bindings</h2> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ASSIGNCMDKEY'>AssignCmdKey</a>(keymod km, int msg)<span class="comment"> -- When key+modifier combination km is pressed perform msg.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CLEARCMDKEY'>ClearCmdKey</a>(keymod km)<span class="comment"> -- When key+modifier combination km is pressed do nothing.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CLEARALLCMDKEYS'>ClearAllCmdKeys</a>()<span class="comment"> -- Drop all key mappings.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_NULL'>Null</a>()<span class="comment"> -- Null operation.</span></p> <h2>Popup edit menu</h2> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_USEPOPUP'>UsePopUp</a>(bool allowPopUp)<span class="comment"> -- Set whether a pop up menu is displayed automatically when the user presses the wrong mouse button.</span></p> <h2>Macro recording</h2> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STARTRECORD'>StartRecord</a>()<span class="comment"> -- Start notifying the container of all key presses and commands.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_STOPRECORD'>StopRecord</a>()<span class="comment"> -- Stop notifying the container of all key presses and commands.</span></p> <h2>Printing</h2> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETPRINTMAGNIFICATION'>PrintMagnification</a><span class="comment"> -- Sets the print magnification added to the point size of each style for printing.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETPRINTCOLOURMODE'>PrintColourMode</a><span class="comment"> -- Modify colours when printing for clearer printed text.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETPRINTWRAPMODE'>PrintWrapMode</a><span class="comment"> -- Set printing to line wrapped (SC_WRAP_WORD) or not line wrapped (SC_WRAP_NONE).</span></p> <h2>Direct access</h2> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETDIRECTFUNCTION'>DirectFunction</a> read-only</p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETDIRECTPOINTER'>DirectPointer</a> read-only</p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETCHARACTERPOINTER'>CharacterPointer</a> read-only</p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETRANGEPOINTER'>GetRangePointer</a>(int position, int rangeLength)<span class="comment"> -- Return a read-only pointer to a range of characters in the document. May move the gap so that the range is contiguous, but will only move up to rangeLength bytes.</span></p> <p>position editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETGAPPOSITION'>GapPosition</a> read-only</p> <h2>Multiple views</h2> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETDOCPOINTER'>DocPointer</a><span class="comment"> -- Change the document object used.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CREATEDOCUMENT'>CreateDocument</a>()<span class="comment"> -- Create a new document object. Starts with reference count of 1 and not selected into editor.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ADDREFDOCUMENT'>AddRefDocument</a>(int doc)<span class="comment"> -- Extend life of document.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_RELEASEDOCUMENT'>ReleaseDocument</a>(int doc)<span class="comment"> -- Release a reference to the document, deleting document if it fades to black.</span></p> <h2>Background loading and saving</h2> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CREATELOADER'>CreateLoader</a>(int bytes)<span class="comment"> -- Create an ILoader*.</span></p> <h2>Folding</h2> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_VISIBLEFROMDOCLINE'>VisibleFromDocLine</a>(int line)<span class="comment"> -- Find the display line of a document line taking hidden lines into account.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_DOCLINEFROMVISIBLE'>DocLineFromVisible</a>(int lineDisplay)<span class="comment"> -- Find the document line of a display line taking hidden lines into account.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SHOWLINES'>ShowLines</a>(int lineStart, int lineEnd)<span class="comment"> -- Make a range of lines visible.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_HIDELINES'>HideLines</a>(int lineStart, int lineEnd)<span class="comment"> -- Make a range of lines invisible.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETLINEVISIBLE'>LineVisible</a>[int line] read-only</p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETALLLINESVISIBLE'>AllLinesVisible</a> read-only</p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETFOLDLEVEL'>FoldLevel</a>[int line]<span class="comment"> -- Set the fold level of a line. This encodes an integer level along with flags indicating whether the line is a header and whether it is effectively white space.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETFOLDFLAGS'>FoldFlags</a> write-only<span class="comment"> -- Set some style options for folding.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETLASTCHILD'>GetLastChild</a>(int line, int level)<span class="comment"> -- Find the last child line of a header line.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETFOLDPARENT'>FoldParent</a>[int line] read-only</p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_TOGGLEFOLD'>ToggleFold</a>(int line)<span class="comment"> -- Switch a header line between expanded and contracted.</span></p> <p>bool editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETFOLDEXPANDED'>FoldExpanded</a>[int line]<span class="comment"> -- Show the children of a header line.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CONTRACTEDFOLDNEXT'>ContractedFoldNext</a>(int lineStart)<span class="comment"> -- Find the next line at or after lineStart that is a contracted fold header line. Return -1 when no more lines.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ENSUREVISIBLE'>EnsureVisible</a>(int line)<span class="comment"> -- Ensure a particular line is visible by expanding any header line hiding it.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ENSUREVISIBLEENFORCEPOLICY'>EnsureVisibleEnforcePolicy</a>(int line)<span class="comment"> -- Ensure a particular line is visible by expanding any header line hiding it. Use the currently set visibility policy to determine which range to display.</span></p> <h2>Line wrapping</h2> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETWRAPMODE'>WrapMode</a><span class="comment"> -- Sets whether text is word wrapped.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETWRAPVISUALFLAGS'>WrapVisualFlags</a><span class="comment"> -- Set the display mode of visual flags for wrapped lines.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETWRAPVISUALFLAGSLOCATION'>WrapVisualFlagsLocation</a><span class="comment"> -- Set the location of visual flags for wrapped lines.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETWRAPINDENTMODE'>WrapIndentMode</a><span class="comment"> -- Sets how wrapped sublines are placed. Default is fixed.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETWRAPSTARTINDENT'>WrapStartIndent</a><span class="comment"> -- Set the start indent for wrapped lines.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETLAYOUTCACHE'>LayoutCache</a><span class="comment"> -- Sets the degree of caching of layout information.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETPOSITIONCACHE'>PositionCache</a><span class="comment"> -- Set number of entries in position cache</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_LINESSPLIT'>LinesSplit</a>(int pixelWidth)<span class="comment"> -- Split the lines in the target into lines that are less wide than pixelWidth where possible.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_LINESJOIN'>LinesJoin</a>()<span class="comment"> -- Join the lines in the target.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_WRAPCOUNT'>WrapCount</a>(int line)<span class="comment"> -- The number of display lines needed to wrap a document line</span></p> <h2>Zooming</h2> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ZOOMIN'>ZoomIn</a>()<span class="comment"> -- Magnify the displayed text by increasing the sizes by 1 point.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ZOOMOUT'>ZoomOut</a>()<span class="comment"> -- Make the displayed text smaller by decreasing the sizes by 1 point.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETZOOM'>Zoom</a><span class="comment"> -- Set the zoom level. This number of points is added to the size of all fonts. It may be positive to magnify or negative to reduce.</span></p> <h2>Long lines</h2> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETEDGEMODE'>EdgeMode</a><span class="comment"> -- The edge may be displayed by a line (EDGE_LINE) or by highlighting text that goes beyond it (EDGE_BACKGROUND) or not displayed at all (EDGE_NONE).</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETEDGECOLUMN'>EdgeColumn</a><span class="comment"> -- Set the column number of the edge. If text goes past the edge then it is highlighted.</span></p> <p>colour editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETEDGECOLOUR'>EdgeColour</a><span class="comment"> -- Change the colour used in edge indication.</span></p> <h2>Lexer</h2> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETLEXER'>Lexer</a><span class="comment"> -- Set the lexing language of the document.</span></p> <p>string editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETLEXERLANGUAGE'>LexerLanguage</a><span class="comment"> -- Set the lexing language of the document based on string name.</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_LOADLEXERLIBRARY'>LoadLexerLibrary</a>(string path)<span class="comment"> -- Load a lexer library (dll / so).</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_COLOURISE'>Colourise</a>(position start, position end)<span class="comment"> -- Colourise a segment of the document using the current lexing language.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_CHANGELEXERSTATE'>ChangeLexerState</a>(position start, position end)<span class="comment"> -- Indicate that the internal state of a lexer has changed over a range and therefore there may be a need to redraw.</span></p> <p>string editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_PROPERTYNAMES'>PropertyNames</a>()<span class="comment"> -- Retrieve a '\n' separated list of properties understood by the current lexer.</span></p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_PROPERTYTYPE'>PropertyType</a>(string name)<span class="comment"> -- Retrieve the type of a property.</span></p> <p>string editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_DESCRIBEPROPERTY'>DescribeProperty</a>(string name)<span class="comment"> -- Describe a property.</span></p> <p>string editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETPROPERTY'>Property</a>[string key]<span class="comment"> -- Set up a value that may be used by a lexer for some optional feature.</span></p> <p>string editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETPROPERTYEXPANDED'>PropertyExpanded</a>[string key] read-only</p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETPROPERTYINT'>PropertyInt</a>[string key] read-only</p> <p>string editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETKEYWORDS'>KeyWords</a>[int keywordSet] write-only<span class="comment"> -- Set up the key words used by the lexer.</span></p> <p>string editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_DESCRIBEKEYWORDSETS'>DescribeKeyWordSets</a>()<span class="comment"> -- Retrieve a '\n' separated list of descriptions of the keyword sets understood by the current lexer.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETSTYLEBITSNEEDED'>StyleBitsNeeded</a> read-only</p> <p>string editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETSUBSTYLEBASES'>SubStyleBases</a> read-only</p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_DISTANCETOSECONDARYSTYLES'>DistanceToSecondaryStyles</a> read-only</p> <p>int editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_ALLOCATESUBSTYLES'>AllocateSubStyles</a>(int styleBase, int numberStyles)<span class="comment"> -- Allocate a set of sub styles for a particular base style, returning start of range</span></p> <p>editor:<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_FREESUBSTYLES'>FreeSubStyles</a>()<span class="comment"> -- Free allocated sub styles</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETSUBSTYLESSTART'>SubStylesStart</a>[int styleBase] read-only</p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_GETSUBSTYLESLENGTH'>SubStylesLength</a>[int styleBase] read-only</p> <p>string editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETIDENTIFIERS'>Identifiers</a>[int style] write-only<span class="comment"> -- Set the identifiers that are shown in a particular style</span></p> <h2>Notifications</h2> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETIDENTIFIER'>Identifier</a><span class="comment"> -- Set the identifier reported as idFrom in notification messages.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETMODEVENTMASK'>ModEventMask</a><span class="comment"> -- Set which document modification events are sent to the container.</span></p> <p>int editor.<a href='http://www.scintilla.org/ScintillaDoc.html#SCI_SETMOUSEDWELLTIME'>MouseDwellTime</a><span class="comment"> -- Sets the time the mouse must sit still to generate a mouse dwell event.</span></p> <!-- </Autogenerated> --> </body> </html> |
Added doc/PrintHi.png.
cannot compute difference between binary files
Added doc/SciBreak.jpg.
cannot compute difference between binary files
Added doc/SciBreak2.jpg.
cannot compute difference between binary files
Added doc/SciCoding.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title> Scintilla and SciTE Code Style Preferences </title> <style> .S0 { color: #808080; } .S1 { font-family: Comic Sans MS; color: #007F00; font-size: 9pt; } .S2 { font-family: Comic Sans MS; color: #007F00; font-size: 9pt; } .S3 { font-family: Comic Sans MS; color: #3F703F; font-size: 9pt; } .S4 { color: #007F7F; } .S5 { font-weight: bold; color: #00007F; } .S6 { color: #7F007F; } .S7 { color: #7F007F; } .S8 { color: #804080; } .S9 { color: #7F7F00; } .S10 { font-weight: bold; color: #000000; } .S12 { font-family: Courier New; color: #000000; background: #E0C0E0; font-size: 10pt; } .S13 { font-family: Courier New; color: #007F00; background: #E0FFE0; font-size: 10pt; } .S14 { font-family: Courier New; color: #3F7F3F; background: #E0F0FF; font-size: 10pt; } .S15 { font-family: Comic Sans MS; color: #3F703F; font-size: 9pt; } SPAN { font-family: Verdana; font-size: 10pt; } </style> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5">Scintilla and SciTE</font></a> </td> </tr> </table> <h2> Code Style </h2> <h3> Introduction </h3> <p> The source code of Scintilla and SciTE follow my preferences. Some of these decisions are arbitrary and based on my sense of aesthetics but its good to have all the code look the same even if its not exactly how everyone would prefer. </p> <p> Code that does not follow these conventions will be accepted, but will be modified as time goes by to fit the conventions. Scintilla code follows the conventions more closely than SciTE except for lexers which are relatively independent modules. Lexers that are maintained by others are left as they are submitted except that warnings will be fixed so the whole project can compile cleanly. </p> <p> The <a href="http://astyle.sourceforge.net/">AStyle</a> formatting program with '-taOHUKk3 -M8' arguments formats code in much the right way although there are a few bugs in AStyle. </p> <h3> Language features </h3> <p> Design goals for Scintilla and SciTE include portability to currently available C++ compilers on diverse platforms with high performance and low resource usage. Scintilla has stricter portability requirements to SciTE as it may be ported to low capability platforms. </p> <p> To achieve portability, only a subset of C++ features are used. Exceptions and templates may be used but, since Scintilla can be used from C as well as C++, exceptions may not be thrown out of Scintilla and all exceptions should be caught before returning from Scintilla. Run-time type information adds to memory use so is turned off. A 'Scintilla' name spaces is optionally used based on the SCI_NAMESPACE definition. This helps with name clashes on OS X. </p> <p> The goto statement is not used because of bad memories from my first job maintaining FORTRAN programs. The union feature is not used as it can lead to non-type-safe value access. </p> <h3> Casting </h3> <p> Do not use old C style casts like (char *)s. Instead use the most strict form of C++ cast possible like const_cast<char *>(s). Use static_cast and const_cast where possible rather than reinterpret_cast. Because the code is compiled with run-time type information turned off, dynamic_cast will not work. </p> <p> The benefit to using the new style casts is that they explicitly detail what evil is occurring and act as signals that something potentially unsafe is being done. </p> <p> Code that treats const seriously is easier to reason about both for humans and compilers, so use const parameters and avoid const_cast. </p> <h3> Warnings </h3> <p> To help ensure code is well written and portable, it is compiled with almost all warnings turned on. This sometimes results in warnings about code that is completely good (false positives) but changing the code to avoid the warnings is generally fast and has little impact on readability. </p> <p> Initialise all variables and minimise the scope of variables. If a variable is defined just before its use then it can't be misused by code before that point. Use loop declarations that are compatible with both the C++ standard and currently available compilers. </p> <h3> Allocation </h3> <p> Memory exhaustion can occur in many Scintilla methods. This should be checked for and handled but once it has happened, it is very difficult to do anything as Scintilla's data structures may be in an inconsistent state. Fixed length buffers are often used as these are simple and avoid the need to worry about memory exhaustion but then require that buffer lengths are respected. </p> <p> The C++ new and delete operators are preferred over C's malloc and free as new and delete are type safe. </p> <h3> Bracketing </h3> <p> Start brackets, '{', should be located on the line of the control structure they start and end brackets, '}', should be at the indented start of a line. When there is an else clause, this occurs on the same line as the '}'. This format uses less lines than alternatives, allowing more code to be seen on screen. Fully bracketed control structures are preferred because this makes it more likely that modifications will be correct and it allows Scintilla's folder to work. No braces on returned expressions as return is a keyword, not a function call. </p> <SPAN class=S0></SPAN><SPAN class=S5>bool</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>fn</SPAN><SPAN class=S10>(</SPAN><SPAN class=S5>int</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>a</SPAN><SPAN class=S10>)</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>{</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S5>if</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>(</SPAN><SPAN class=S11>a</SPAN><SPAN class=S10>)</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>{</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S11>s</SPAN><SPAN class=S10>();</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S11>t</SPAN><SPAN class=S10>();</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S10>}</SPAN><SPAN class=S0> </SPAN><SPAN class=S5>else</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>{</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S11>u</SPAN><SPAN class=S10>();</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S10>}</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S5>return</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>!</SPAN><SPAN class=S11>a</SPAN><SPAN class=S10>;</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S10>}</SPAN><SPAN class=S0><BR> </SPAN> <h3> Spacing </h3> <p> Spaces on both sides of '=' and comparison operators and no attempt to line up '='. No space before or after '(', when used in calls, but a space after every ','. No spaces between tokens in short expressions but may be present in longer expressions. Space before '{'. No space before ';'. No space after '*' when used to mean pointer and no space after '[' or ']'. One space between keywords and '('. </p> <SPAN class=S0></SPAN><SPAN class=S5>void</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>StoreConditionally</SPAN><SPAN class=S10>(</SPAN><SPAN class=S5>int</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>c</SPAN><SPAN class=S10>,</SPAN><SPAN class=S0> </SPAN><SPAN class=S5>const</SPAN><SPAN class=S0> </SPAN><SPAN class=S5>char</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>*</SPAN><SPAN class=S11>s</SPAN><SPAN class=S10>)</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>{</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S5>if</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>(</SPAN><SPAN class=S11>c</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>&&</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>(</SPAN><SPAN class=S11>baseSegment</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>==</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>trustSegment</SPAN><SPAN class=S10>[</SPAN><SPAN class=S6>"html"</SPAN><SPAN class=S10>]))</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>{</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S11>baseSegment</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>=</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>s</SPAN><SPAN class=S10>+</SPAN><SPAN class=S4>1</SPAN><SPAN class=S10>;</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S11>Store</SPAN><SPAN class=S10>(</SPAN><SPAN class=S11>s</SPAN><SPAN class=S10>,</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>baseSegment</SPAN><SPAN class=S10>,</SPAN><SPAN class=S0> </SPAN><SPAN class=S6>"html"</SPAN><SPAN class=S10>);</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S10>}</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S10>}</SPAN> <h3> Names </h3> <p> Identifiers use mixed case and no underscores. Class, function and method names start with an uppercase letter and use further upper case letters to distinguish words. Variables start with a lower case letter and use upper case letters to distinguish words. Loop counters and similar variables can have simple names like 'i'. Function calls should be differentiated from method calls with an initial '::' global scope modifier. </p> <SPAN class=S0></SPAN><SPAN class=S5>class</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>StorageZone</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>{</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S5>public</SPAN><SPAN class=S10>:</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S5>void</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>Store</SPAN><SPAN class=S10>(</SPAN><SPAN class=S5>const</SPAN><SPAN class=S0> </SPAN><SPAN class=S5>char</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>*</SPAN><SPAN class=S11>s</SPAN><SPAN class=S10>)</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>{</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S11>Media</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>*</SPAN><SPAN class=S11>mediaStore</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>=</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>::</SPAN><SPAN class=S11>GetBaseMedia</SPAN><SPAN class=S10>(</SPAN><SPAN class=S11>zoneDefault</SPAN><SPAN class=S10>);</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S5>for</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>(</SPAN><SPAN class=S5>int</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>i</SPAN><SPAN class=S10>=</SPAN><SPAN class=S11>mediaStore</SPAN><SPAN class=S10>-></SPAN><SPAN class=S11>cursor</SPAN><SPAN class=S10>;</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>mediaStore</SPAN><SPAN class=S10>[</SPAN><SPAN class=S11>i</SPAN><SPAN class=S10>],</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>i</SPAN><SPAN class=S10>++)</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>{</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S11>mediaStore</SPAN><SPAN class=S10>-></SPAN><SPAN class=S11>Persist</SPAN><SPAN class=S10>(</SPAN><SPAN class=S11>s</SPAN><SPAN class=S10>[</SPAN><SPAN class=S11>i</SPAN><SPAN class=S10>]);</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S10>}</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S10>}</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S10>};</SPAN> <h3> Submitting a lexer </h3> <p>Add a public feature request to the <a href="https://sourceforge.net/tracker/?group_id=2439&atid=352439">Feature Request Tracker</a>.</p> <p>Send all the modified and new files as full text (not patches) in an archive (.zip or .tgz).</p> <p>Define all of the lexical states in a modified Scintilla.iface.</p> <p>Ensure there are no warnings under the compiler you use. Warnings from other compilers will be noted on the feature request.</p> <p>sc.ch is an int: do not pass this around as a char.</p> </body> </html> |
Added doc/SciRest.jpg.
cannot compute difference between binary files
Added doc/SciTE.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="HTML Tidy, see www.w3.org" /> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" /> <meta name="Description" content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." /> <meta name="Date.Modified" content="20130226" /> <script type="text/javascript"> function IsRemote() { var loc = '' + window.location; return loc.indexOf('http:') != -1; } </script> <style type="text/css"> #versionlist { margin: 0; padding: .5em; list-style-type: none; color: #FFCC99; background: #000000; } #versionlist li { margin-bottom: .5em; } #menu { margin: 0; padding: .5em 0; list-style-type: none; font-size: larger; background: #CCCCCC; } #menu li { margin: 0; padding: 0 .5em; display: inline; } </style> <title> Scintilla and SciTE </title> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td width="256"> <img src="http://www.scintilla.org/SciTEWord.jpg" height="85" width="200" alt="Scintilla" /> </td> <td width="40%" align="left"> <font color="#FFCC99" size="4"> A free source code editor for Win32 and X</font> </td> <td width="40%" align="right"> <font color="#FFCC99" size="3"> Release version 3.2.5<br /> Site last modified February 26 2013</font> </td> <td width="20%"> </td> </tr> </table> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td width="100%" style="background: url(http://www.scintilla.org/SciBreak2.jpg) no-repeat;height:150px;"> </td> </tr> </table> <ul id="versionlist"> <li>Version 3.2.5 caret x positions are remembered when switching documents.</li> <li>Version 3.2.4 does not truncate copies to clipboard at NULs.</li> <li>Version 3.2.3 defines PLAT_UNIX for all Unix variants and fixes minor problems.</li> <li>Version 3.2.2 remains responsive by limiting highlight.current.word to 0.25 seconds.</li> <li>Version 3.2.1 retrieves string properties from the Scintilla API using property notation in Lua scripts.</li> <li>Version 3.2.0 allows Ctrl to be used with mouse double and triple clicks to add words and lines to the selection.</li> </ul> <ul id="menu"> <li><a href="http://www.scintilla.org/SciTEImage.html">Screenshot</a></li> <li id="remote1"><a href="http://www.scintilla.org/SciTEDownload.html">Download</a></li> <li><a href="http://www.scintilla.org/SciTEDoc.html">Documentation</a></li> <li id="remote2"><a href="http://www.scintilla.org/index.html">Scintilla</a></li> <li><a href="http://code.google.com/p/scite-files/wiki/Customization">Extras</a></li> <li><a href="http://code.google.com/p/scite-files/wiki/Translations">Translations</a></li> <li><a href="http://www.scintilla.org/SciTEFAQ.html">Frequently Asked Questions</a></li> </ul> <script type="text/javascript" language="JavaScript"><!-- if (!IsRemote()) { //if NOT remote... document.getElementById('remote1').style.display='none'; document.getElementById('remote2').style.display='none'; } //--></script> <p> <a href="http://www.scintilla.org/SciTEDoc.html">SciTE</a> is a SCIntilla based Text Editor. Originally built to demonstrate <a href="http://www.scintilla.org">Scintilla</a>, it has grown to be a generally useful editor with facilities for building and running programs. It is best used for jobs with simple configurations - I use it for building test and demonstration programs as well as SciTE and Scintilla, themselves. </p> <p> SciTE is currently available for Intel Windows (XP or later) and Linux compatible operating systems with GTK+. It has been run on Windows 7 and on Fedora 12 and Ubuntu 10.10 with GTK+ 2.20. <a href="http://www.scintilla.org/SciTEImage.html">Here is a screenshot of SciTE.</a><br /> </p> <script type="text/javascript" language="JavaScript"><!-- if (IsRemote()) { document.write('<p>You can <a href="http://www.scintilla.org/SciTEDownload.html">download Scintilla and SciTE.</a></p>'); } //--></script> <noscript> <p>You can <a href="http://www.scintilla.org/SciTEDownload.html">download Scintilla and SciTE.</a></p> </noscript> <p> For OS X, there is a commercial version of SciTE available from the <a href="http://www.scintilla.org/SciTE-OSX.html">Mac App Store</a>. </p> <p> There are some <a href="http://code.google.com/p/scite-files/wiki/Customization">extra configuration files</a> that can enhance SciTE for various languages and APIs. </p> <p> Questions and comments about SciTE should be directed to the <a href="http://groups.google.com/group/scite-interest">scite-interest</a> mailing list, which is for discussion of SciTE and related projects, their bugs and future features. This is a low traffic list, averaging less than 50 messages per week. To avoid spam, only list members can write to the list. New versions of SciTE are announced on scite-interest and may also be received by SourceForge members by clicking on the Monitor column icon for "scite" on <a href="https://sourceforge.net/project/showfiles.php?group_id=2439">the downloads page</a>. Messages sent to my personal email address that could have been sent to the list may receive no response. <br /> </p> There is a <a href="https://sourceforge.net/project/?group_id=2439">Scintilla project page</a> hosted on <script type="text/javascript" language="JavaScript"> <!-- if (IsRemote()) { document.write('<a href="http://sourceforge.net/projects/scintilla">'); document.write('<img src="http://sflogo.sourceforge.net/sflogo.php?group_id=2439&type=8" width="80" height="15" alt="Get Scintilla at SourceForge.net. Fast, secure and Free Open Source software downloads" /></a> '); } else { document.write('<a href="http://sourceforge.net/projects/scintilla">SourceForge<\/a>'); } //--> </script> <noscript> <a href="http://sourceforge.net/projects/scintilla"> <img src="http://sflogo.sourceforge.net/sflogo.php?group_id=2439&type=8" width="80" height="15" alt="Get Scintilla at SourceForge.net. Fast, secure and Free Open Source software downloads" /></a> </noscript> </body> </html> |
Added doc/SciTEDirector.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title> SciTE Director Interface </title> <style type="text/css"> table { border: 1px solid black; border-collapse: collapse; } td { border: 1px solid black; padding: 1px 5px 1px 5px; } .S0 { color: #808080; } .S1 { font-family: Comic Sans MS; color: #007F00; font-size: 9pt; } .S2 { font-family: Comic Sans MS; color: #007F00; font-size: 9pt; } .S3 { font-family: Comic Sans MS; color: #3F703F; font-size: 9pt; } .S4 { color: #007F7F; } .S5 { font-weight: bold; color: #00007F; } .S6 { color: #7F007F; } .S7 { color: #7F007F; } .S8 { color: #804080; } .S9 { color: #7F7F00; } .S10 { font-weight: bold; color: #000000; } .S12 { font-family: Courier New; color: #000000; background: #E0C0E0; font-size: 10pt; } .S13 { font-family: Courier New; color: #007F00; background: #E0FFE0; font-size: 10pt; } .S14 { font-family: Courier New; color: #3F7F3F; background: #E0F0FF; font-size: 10pt; } .S15 { font-family: Comic Sans MS; color: #3F703F; font-size: 9pt; } SPAN { font-family: Verdana; font-size: 10pt; } .example { color: #00A000; font-weight: bold; } DIV.example { background: #F7FCF7; border: 1px solid #C0D7C0; margin: 0.3em 3em; padding: 0.3em 0.6em; font-size: 80%; } DIV.highlighted { background: #F7FCF7; border: 1px solid #C0D7C0; margin: 0.3em 3em; padding: 0.3em 0.6em; font-size: 80%; } </style> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5"> SciTE Director Interface</font></a> </td> </tr> </table> <h3> Purpose. </h3> <p>Software development does not occur only at the single file level handled by SciTE. A developer will generally work on a group of related files together in the context of one project. Project manager functionality could be added to SciTE as it has to other editors but this would impose a particular view of how projects are to be managed including the format of project files. Instead, SciTE has an interface that can be used by project managers or similar applications to control SciTE. Any application that controls SciTE is referred to as a "Director".</p> <p>The current Director interface only works on Windows. In the future, it should be possible to replace the low level interface and so make this interface available on other platforms.</p> <p>There is currently one director application, <a href="http://llt.chez.tiscali.fr/">Filerx</a>, available.</p> <p>This interface is implemented on top of the <a href="SciTEExtension.html">SciTE Extension Interface</a>, in the file scite\win32\DirectorExtension.cxx.</p> <h3> Direct connection, broadcasting and explicit return addresses. </h3> <p>One application at a time is <i>the director</i> of SciTE, controlling SciTE as it wishes. To support other communications techniques applications may broadcast to all active director interfaces. When doing so, each message should contain an explicit return address where replies to the broadcast message will be sent. </p> <h3> Low level interface on Windows. </h3> <p>The Windows WM_COPYDATA message is used to transfer data between SciTE and a Director. The messages are sent between windows created by the two applications. SciTE uses a window that has no other purpose than to receive these messages. The lpData and cbData fields of the COPYDATASTRUCT are used to transfer a string between the two processes, with cbData holding the length of the string pointed to by lpData. The string does not have to be terminated with '\0'. The dwData should be 0.</p> <p>Before messages can be sent from one application to the other, the window handle of the window to receive the message must be found. This is normally transferred when starting the other application as a command line parameter. Either application may start the other. SciTE makes its window handle available in the WindowID property and accepts a director.hwnd property as the window handle to which it sends data.</p> <p>As an example of communicating the window handle, to install Filerx in the Tools menu of SciTE these properties could be used:</p> <div class="example"> command.name.0.*=Project Editor<br/> command.0.*="C:\os\scite\bin\filerx.exe" "$(FileDir)" "$(WindowID)"<br/> command.subsystem.0.*=2 </div> <p>In the opposite direction, Filerx can start up SciTE with a command line that specifies its window handle as well as the file it wants edited:</p> <div class="example"> SciTE -director.hwnd=937846 c:\os\scite\src\SciTEBase.cxx </div> <p>Once one application has the window handle of the other application, it should send its window handle to the other application using an identity message as described later. Then both sides are able to send messages.</p> <p>To broadcast a message on Windows, the set of active director interfaces can be found by broadcasting the "SciTEDirectorInterface" message and seeing which windows reply with the same value as that message. Example broadcast code:</p> <div class="highlighted"> <SPAN class=S0></SPAN><SPAN class=S5>unsigned</SPAN><SPAN class=S0> </SPAN><SPAN class=S5>int</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>SDI</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>=</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>::</SPAN><SPAN class=S11>RegisterWindowMessage</SPAN><SPAN class=S10>(</SPAN><SPAN class=S0></SPAN><SPAN class=S6>"SciTEDirectorInterface"</SPAN><SPAN class=S10>);</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S11>HWND</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>w</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>=</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>::</SPAN><SPAN class=S11>GetWindow</SPAN><SPAN class=S10>(::</SPAN><SPAN class=S11>GetDesktopWindow</SPAN><SPAN class=S10>(),</SPAN><SPAN class=S0></SPAN><SPAN class=S11>GW_CHILD</SPAN><SPAN class=S10>);</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S5>while</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>(</SPAN><SPAN class=S11>w</SPAN><SPAN class=S10>)</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>{</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S11>DWORD</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>res</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>=</SPAN><SPAN class=S0> </SPAN><SPAN class=S4>0</SPAN><SPAN class=S10>;</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S2>// Need time out to avoid hung applications</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S10>::</SPAN><SPAN class=S11>SendMessageTimeout</SPAN><SPAN class=S10>(</SPAN><SPAN class=S11>w</SPAN><SPAN class=S10>,</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>SDI</SPAN><SPAN class=S10>,</SPAN><SPAN class=S0> </SPAN><SPAN class=S4>0</SPAN><SPAN class=S10>,</SPAN><SPAN class=S0> </SPAN><SPAN class=S4>0</SPAN><SPAN class=S10>,</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S11>SMTO_NORMAL</SPAN><SPAN class=S10>,</SPAN><SPAN class=S0> </SPAN><SPAN class=S4>1000</SPAN><SPAN class=S10>,</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>&</SPAN><SPAN class=S11>res</SPAN><SPAN class=S10>);</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S5>if</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>(</SPAN><SPAN class=S11>res</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>==</SPAN><SPAN class=S0> </SPAN><SPAN class=S5>static_cast</SPAN><SPAN class=S10><</SPAN><SPAN class=S11>DWORD</SPAN><SPAN class=S10>>(</SPAN><SPAN class=S11>SDI</SPAN><SPAN class=S10>))</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>{</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S2>// Replied with same SDI code so should</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S2>// understand SDI's version of WM_COPYDATA</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S10>::</SPAN><SPAN class=S11>SendMessage</SPAN><SPAN class=S10>(</SPAN><SPAN class=S11>w</SPAN><SPAN class=S10>,</SPAN><SPAN class=S11>WM_COPYDATA</SPAN><SPAN class=S10>,</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S10>(</SPAN><SPAN class=S11>UINT</SPAN><SPAN class=S10>)</SPAN><SPAN class=S11>m_hWnd</SPAN><SPAN class=S10>,(</SPAN><SPAN class=S5>long</SPAN><SPAN class=S10>)&</SPAN><SPAN class=S11>cds</SPAN><SPAN class=S10>);</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S10>}</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S11>w</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>=</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>::</SPAN><SPAN class=S11>GetWindow</SPAN><SPAN class=S10>(</SPAN><SPAN class=S11>w</SPAN><SPAN class=S10>,</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>GW_HWNDNEXT</SPAN><SPAN class=S10>);</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S10>}</SPAN><SPAN class=S0><BR> </SPAN> </div> <p>To advertise that a top level window supports the Director interface:</p> <div class="highlighted"> <SPAN class=S0></SPAN><SPAN class=S11>LRESULT</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>PASCAL</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>DirectorExtension_WndProc</SPAN><SPAN class=S10>(</SPAN><SPAN class=S11>HWND</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>hWnd</SPAN><SPAN class=S10>,</SPAN><SPAN class=S0> <BR> </SPAN><SPAN class=S11>UINT</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>iMessage</SPAN><SPAN class=S10>,</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>WPARAM</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>wParam</SPAN><SPAN class=S10>,</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>LPARAM</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>lParam</SPAN><SPAN class=S10>)</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>{</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S5>unsigned</SPAN><SPAN class=S0> </SPAN><SPAN class=S5>int</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>SDI</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>=</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>::</SPAN><SPAN class=S11>RegisterWindowMessage</SPAN><SPAN class=S10>(</SPAN><SPAN class=S6>"SciTEDirectorInterface"</SPAN><SPAN class=S10>);</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S5>if</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>(</SPAN><SPAN class=S11>iMessage</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>==</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>SDI</SPAN><SPAN class=S10>)</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>{</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S5>return</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>SDI</SPAN><SPAN class=S10>;</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S10>}</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S5>return</SPAN><SPAN class=S0> </SPAN><SPAN class=S10>::</SPAN><SPAN class=S11>DefWindowProc</SPAN><SPAN class=S10>(</SPAN><SPAN class=S11>hWnd</SPAN><SPAN class=S10>,</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>iMessage</SPAN><SPAN class=S10>,</SPAN><SPAN class=S0> </SPAN><SPAN class=S11>wParam</SPAN><SPAN class=S10>,</SPAN><SPAN class=S0></SPAN><SPAN class=S11>lParam</SPAN><SPAN class=S10>);</SPAN><SPAN class=S0><BR> </SPAN><SPAN class=S10>}</SPAN><BR> </div> <h3> Low level interface on GTK+. </h3> <p>This is not yet implemented. The proposed design uses an input fifo for each application supporting the director interface located in /tmp with a name using a pattern such as "/tmp/SciTE<PID>.director". This allows enumerating all active director interfaces and also opening a specific interface when the fifo name has been communicated through some other means such as a command line argument or an identity: command.</p> <h3> High level interface. </h3> <p>Messages use C style escapes to represent control characters and ensure that only visible characters are transmitted apart from the use of '\n' to separate messages.</p> <p>The string transmitted by the low level interface contains an optional return address surrounded by ':' characters, an action, a ':' character and an optional argument. The argument is often a file path. The ':' must be present even if there is no argument. For example, SciTE understands the message</p> <div class="example"> open:c:\\os\\scintilla\\include\\Scintilla.iface </div> <p>as a command to open the file "c:\os\scintilla\include\Scintilla.iface" just as if the user had performed this operation.</p> <p>If the first character of the message is a ':' then up to the next ':' is a return address, so SciTE will reply to the message</p> <div class="example"> :73658:askfilename: </div> <p>by sending the filename being edited to the return address 73658 rather than to its director.</p> <h4>The actions understood by SciTE are:</h4> <table border="1"> <tr> <td>askfilename:</td> <td>Return the name of the file being edited.</td> </tr> <tr> <td>askproperty:<key></td> <td>Return the value of a property.</td> </tr> <tr> <td>close:</td> <td>Close the current file.</td> </tr> <tr> <td>closing:</td> <td>Director is closing - SciTE closes if it was started by the director.</td> </tr> <tr> <td>currentmacro:<string></td> <td>Set the current macro to name.</td> </tr> <tr> <td>cwd:</td> <td>Change the working directory.</td> </tr> <tr> <td>enumproperties:dyn|local|user|base|embed</td> <td>Enumerate all the properties in the argument set.</td> </tr> <tr> <td>exportashtml:<path></td> <td>Save the document in HTML format as the indicated file.</td> </tr> <tr> <td>exportasrtf:<path></td> <td>Save the document in RTF format as the indicated file.</td> </tr> <tr> <td>exportaspdf:<path></td> <td>Save the document in PDF format as the indicated file.</td> </tr> <tr> <td>exportaslatex:<path></td> <td>Save the document in LaTeX format as the indicated file.</td> </tr> <tr> <td>exportasxml:<path></td> <td>Save the document in XML format as the indicated file.</td> </tr> <tr> <td>extender:<command></td> <td>Call the extension interface with the given command.</td> </tr> <tr> <td>find:<string></td> <td>Search for a string, select and show it.</td> </tr> <tr> <td>focus:<timeStamp></td> <td>On GTK+ bring this SciTE window to the front. The timeStamp is from the window manager and ensures that windows are only activated because of a user command. Has no effect on Windows as applications on Windows can only donate focus, not take focus.</td> </tr> <tr> <td>goto:<lineNumber>[,<columnNumber>]</td> <td>Move caret to a particular line and make it visible.<br> If there is a column number then select the word at that column number or move the caret there if no word is present.</td> </tr> <tr> <td>identity:<hwndDirector></td> <td>Sets the director window handle to which SciTE sends messages. The argument is in decimal.</td> </tr> <tr> <td>insert:<value></td> <td>Display the value in the editor pane replacing the selection.</td> </tr> <tr> <td>loadsession:<path></td> <td>Load a session as given by the indicated file.</td> </tr> <tr> <td>macrocommand:<command></td> <td>Execute a macro command. See the SciTE source code for the syntax of the command argument.</td> </tr> <tr> <td>macroenable:<enable></td> <td>If enable, display menu commands in SciTE for recording and playing macros.</td> </tr> <tr> <td>macrolist:<list></td> <td>Display a list for the user to choose from.</td> </tr> <tr> <td>menucommand:<cmd></td> <td>Execute a menu command based on numeric ID.</td> </tr> <tr> <td>open:<path></td> <td>Open the indicated file.</td> </tr> <tr> <td>output:<value></td> <td>Display the value in the output pane replacing the selection.</td> </tr> <tr> <td>property:<key>=<value></td> <td>Set a property to a value.</td> </tr> <tr> <td>quit:</td> <td>Shut down SciTE.</td> </tr> <tr> <td>reloadproperties:</td> <td>Reload properties from files.</td> </tr> <tr> <td>replaceall:<search>\000<replace></td> <td>Replace all instances of he search string in the document with the replace string.</td> </tr> <tr> <td>saveas:<path></td> <td>Save the document as the indicated file.</td> </tr> <tr> <td>savesession:<path></td> <td>Save a session as given by the indicated file.</td> </tr> </table> <h4>The actions sent by SciTE are:</h4> <table border="1"> <tr> <td>closed:<path></td> <td>SciTE has closed the indicated file.</td> </tr> <tr> <td>closing:</td> <td>SciTE is closing.</td> </tr> <tr> <td>dyn|local|user|base|embed:<key>=<value></td> <td>Set a property in a set to a value.</td> </tr> <tr> <td>filename:<path></td> <td>The file being edited is path. This is the reply to the askfilename: command.</td> </tr> <tr> <td>identity:<hwndSciTEReceiving></td> <td>SciTE indicates to the director the window handle to which it should send messages. The argument is in decimal.</td> </tr> <tr> <td>macro:getlist</td> <td>Retrieve the list of available macros which will be returned by the macrolist command.</td> </tr> <tr> <td>macro:record:<details></td> <td>Start recording a macro. See the SciTE source code for the syntax of the details argument.</td> </tr> <tr> <td>macro:run:<macroName></td> <td>Run the named macro.</td> </tr> <tr> <td>macro:stoprecord</td> <td>Stop recording a macro.</td> </tr> <tr> <td>opened:<path></td> <td>SciTE has opened the indicated file.</td> </tr> <tr> <td>switched:<path></td> <td>SciTE has switched buffers to the indicated file.</td> </tr> <tr> <td>saved:<path></td> <td>SciTE has saved the indicated file.</td> </tr> </table> <p>In the future, more actions will be defined. Applications should ignore any actions that they do not understand.</p> </body> </html> |
Added doc/SciTEDoc.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 |
<?xml version="1.0" encoding='utf-8'?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="HTML Tidy, see www.w3.org" /> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html" /> <title> SciTE </title> <style type="text/css"> table { border: 1px solid #1F1F1F; border-collapse: collapse; } td { border: 1px solid #1F1F1F; padding: 1px 5px 1px 5px; } th { border: 1px solid #1F1F1F; padding: 1px 5px 1px 5px; } .windowsonly { background: #EBF3FF; } .gtkonly { background: #FFFFE7; } .osxonly { background: #FFE7E7; } .example { color: #008000; font-weight: bold; } DIV.example { background: #F7FCF7; border: 1px solid #C0D7C0; margin: 0.3em 3em; padding: 0.3em 0.6em; font-size: 80%; } h3 { border: 2px solid #FFCC00; background-color: #FFF7EE; padding: 2px 5px; } .header{ border: 1px solid #CCCCCC; } .headerlinks { padding: 7px; background-color: #CCCCCC; border: 0px solid #FF0000; font-size: 120%; } </style> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" style="border:0px solid #FF0000" border="0" summary="banner"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5"> SciTE Documentation</font></a> </td> </tr> </table> <table class="header" width="100%" summary="header"> <tr> <td class="headerlinks"> <a href="SciTEFAQ.html"> Frequently Asked Questions</a> <a href="SciTELua.html"> Scripting</a> <a href="SciTERegEx.html">Regular Expressions</a> </td> </tr> </table> <h3 id="StandardEditing"> Standard Editing </h3> <p> Text editing in SciTE works similarly to most Macintosh or Windows editors with the added feature of automatic syntax styling. SciTE can hold multiple files in memory at one time but only one file will be visible. Rectangular blocks of text can be selected in SciTE by holding down the Alt key on Windows or the Ctrl key on GTK+ while dragging the mouse over the text. The modifier key used on GTK+ can be changed with the rectangular.selection.modifier property. </p> <p> There are two panes in SciTE, the editing pane and the output pane. The output pane is located either to the right of the editing pane or below it. Initially it is of zero size, but it can be made larger by dragging the divider between it and the editing pane. The Options | Vertical Split command can be used to move the output pane beneath the editing pane. </p> <p> SciTE can perform commands to compile or run source files with the output from these commands directed into the output pane. </p> <p> For example, if <a href="http://www.python.org">Python</a> is installed on the machine, open a new document, type: </p> <blockquote> <kbd> print "Hi" </kbd> </blockquote> <p> as that document's text. </p> Save the document as printhi.py. <br /> The document should now appear coloured as SciTE is using the file's extension to decide upon the syntax styling to use: <blockquote> <code> <b><font color="#000080">print </font></b> <i><font color="#800080">"hi"</font></i> </code> </blockquote> Perform the Tools | Go command.<br /> The output window will be made visible if it is not already visible and will show:<br /> <blockquote> <code> <font color="#0000FF">>python -u printhi.py</font><br /> hi<br /> <font color="#0000FF">>Exit code: 0</font> </code> </blockquote> The first blue line is from SciTE showing the command it will use to run the program. The black line is the output from running the Python program. The last blue line is from SciTE showing that the program has finished and displaying its exit code. An exit code of zero indicates a successful run. <br /> <p> SciTE partially understands the error messages produced by Python, GCC, Visual C++, Borland C++, PHP and other tools which use the same format as one of these. To see this, add a mistake to the Python file by adding a second line to make the file: </p> <blockquote> <code> <span style="color:#000080;font-weight:bold;">print </span> <span style="color:#800080;font-style:italic;">"hi"</span><br /> mistake </code> </blockquote> <p> Perform the Tools | Go command. The results should look like: </p> <blockquote> <pre> <span style="color:#0000FF">>python -u printhi.py</span> hi Traceback (innermost last): <span style="color:#FF0000">File "printhi.py", line 2, in ?</span> mistake NameError: mistake <span style="color:#0000FF">>Exit code: 1</span> </pre> </blockquote> <p> While it is easy to see where the problem is in this simple case, when a file is larger the Tools | Next Message command can be used to view each of the reported errors. Upon performing Tools | Next Message, the first error message in the output pane is highlighted with a yellow background, and an error indicator is displayed for the appropriate line in the editing pane. The caret is moved to this line and the pane is scrolled if needed to show the line. SciTE now looks like this: </p> <img src="PrintHi.png" alt="SciTE after running Python interpreter" /> <p> SciTE understands both the file name and line number parts of error messages in most cases so can open another file (such as a header file) if errors were caused by that file. This feature may not work where the file name is complicated by containing spaces or ".." </p> <p> If command execution has failed and is taking too long to complete then the Tools | Stop Executing command can be used. </p> <h3 id="CommandSubsystem"> Command subsystem </h3> <p> Tools can be executed in various modes by SciTE which are called "subsystems". Different subsystems are supported on Windows and GTK+. The default subsystem is 0. </p> <table class="windowsonly" cellpadding="0" cellspacing="0" border="1" summary="Command line commands"> <thead><tr><td colspan="3">Windows</td></tr></thead> <tr><td>0</td><td>console</td><td>Command line programs<br/>Do not use for GUI programs as their windows will not be visible.</td></tr> <tr><td>1</td><td>windows</td><td>Programs that create their own windows</td></tr> <tr><td>2</td><td>shellexec</td><td>Run using ShellExecute<br /> A good way to open HTML files and similar as it handles this similarly to a user opening the file from the shell.</td></tr> <tr><td>3</td><td>lua<br />director</td><td>Internal extension or director extension</td></tr> <tr><td>4</td><td>htmlhelp</td><td>Open in HtmlHelp program<br /> Two part command separated by ! with the first part being the topic to search for and the second the name of the help file </td></tr> <tr><td>5</td><td>winhelp</td><td>Open with WinHelp function<br /> Two part command similar to subsystem 4</td></tr> </table> <br /> <table class="gtkonly" cellpadding="0" cellspacing="0" border="1" summary="Command line commands"> <thead><tr><td colspan="3">GTK+</td></tr></thead> <tr><td>0</td><td>console</td><td>Execute tool and wait for it to finish</td></tr> <tr><td>2</td><td>shellexec</td><td>Execute in background</td></tr> </table> <h3 id="CommandLineArguments"> Command line arguments </h3> <p> Command line arguments to SciTE include file names, commands and properties. Commands and properties are preceded by "-" and are differentiated by the use in commands of ':' as the first character that is not '.' or alphabetic. Properties use the syntax used in property set files and override any properties set in property files. If there is no value given for a property, it is set to 1. Double quotes may be placed around arguments that contain spaces but they must be placed around the whole argument, not just around a file name, so "-open:x y.txt" works but -open:"x y.txt" doesn't. On Linux, the standard shell quoting is available. The "-p" argument causes SciTE to print the file and then exit. </p> <p> For <span class="windowsonly">Windows</span>:<br /> The command line arguments "-" and "--" (without the quotes) are special in that they read the stdin stream into the last buffer ("-"), or the output pane ("--"))<br /> The command line argument "-@" (without the quotes) is special in that file names are read from stdin and opened.<br /> <b>Note:</b> when reading stdin into the output pane, when the property split.vertical is 0, the output pane is increased to its maximum height. When the property split.vertical is 1, the output pane is increased to approximately half of the screen width.<br /> <b>Note:</b> If stdin is not redirected, these arguments are effectively ignored. </p> <div> For example,</div> <div class="example"> SciTE "-font.base=font:MS Gothic,size:11" -save.recent ScintillaGTK.cxx </div> <div>starts SciTE, opens ScintillaGTK.cxx, loads the recent file list, and uses 11 point MS Gothic as the base font.<br /> A group of properties can be saved as a property set file (with the extension ".properties") and the import command used on the command line:</div> <div class="example"> SciTE "-import c:\os\web_work" SciTEDoc.html </div> <p> A few commands are currently available although this will expand in the future. These commands are available:</p> <table cellpadding="0" cellspacing="0" border="1" summary="Command line commands"> <thead> <tr><th>Command</th><th>Argument</th></tr> </thead> <tr><td>close:</td><td></td></tr> <tr><td>cwd:</td><td>change working directory</td></tr> <tr><td>find:</td><td>search text</td></tr> <tr><td>goto:</td><td>line number[,column number]</td></tr> <tr><td>open:</td><td>file name</td></tr> <tr><td>loadsession:</td><td>file name</td></tr> <tr><td>quit:</td><td></td></tr> <tr><td>replaceall:</td><td>search text\000replacement text</td></tr> <tr><td>saveas:</td><td>file name</td></tr> </table> <br /> Commands use C style escape sequences which include: <table cellpadding="0" cellspacing="0" border="1" summary="Command line escape sequences"> <thead> <tr><th>Escape Sequence</th><th>Meaning</th></tr> </thead> <tr><td>\\</td><td>backslash</td></tr> <tr><td>\a</td><td>bell</td></tr> <tr><td>\b</td><td>backspace</td></tr> <tr><td>\f</td><td>form feed</td></tr> <tr><td>\n</td><td>new line</td></tr> <tr><td>\r</td><td>carriage return</td></tr> <tr><td>\t</td><td>tab</td></tr> <tr><td>\v</td><td>vertical tab</td></tr> <tr><td>\<ooo></td><td>octal number specified by 1, 2, or 3 digits</td></tr> <tr><td>\x<hh></td><td>hexadecimal number specified by 2 digits</td></tr> </table> The following opens /big/icon.txt:<br /> <div class="example"> SciTE -open:/big/icon.txt </div> On Windows, the following opens C:\Program Files\SciTE\SciTEDoc.html and goes to the 123rd line:<br /> <div class="example"> SciTE "-open:C:\\Program Files\\SciTE\\SciTEDoc.html" -goto:123 </div> <p> Command line arguments are evaluated left to right in two phases because opening files requires the user interface to be available and there is also a need to set some user interface properties before the user interface is displayed. The first phase process arguments until just before the first file name would be opened. The second phase processes the remaining arguments. </p> <p> So, if you need to perform e.g. a find: or a goto: command on a file, you must put the command after the filename, to allow SciTE to open the file before performing the command. </p> <p> For <span class="windowsonly">Windows</span>:<br /> If any simple file name on the command line matches a directory name, the file open dialog appears - this is dependant upon the property "open.dialog.in.file.directory"<br /><br /> If the property "buffers" is greater than one and the file name matches either a existing file or by means of a wildcard search, one or more files, the matching files are loaded up to the property "buffers" count. Directories are not considered a match in this case<br /><br /> If the file name is an extension, optionally preceded by a path, and no such simple file name exists, the file open dialog appears, with the given extension as the filter.<br /><br /> If the file name contains no extension, the property "source.default.extensions" is used to provide default extensions to attempt to match the file name to an existing file. </p> <h3 id="Buffers"> Buffers </h3> <p> SciTE may be configured to use between 1 and 100 buffers each containing a file. The default is 1 and this effectively turns off buffers. With more than one buffer, the Buffers menu can be used to switch between buffers, either by selecting the file name or using the Previous (F6) and Next (Shift+F6) commands. A tab is displayed for each buffer in the tab bar although this can be turned off with the View | Tab Bar command. A tab may be closed by clicking on it with the middle mouse button. Setting large numbers of buffers may cause problems as some menus are fixed in length and thus files beyond that length may not be accessible. </p> <p> When all the buffers contain files, then opening a new file causes a buffer to be reused which may require a file to be saved. In this case an alert is displayed to ensure the user wants the file saved. </p> <h3 id="Sessions"> Sessions </h3> <p> A session is a list of file names. You can save a complete set of your currently opened buffers as a session for fast batch-loading in the future. Sessions are stored as properties files with the extension ".session". </p> <p> Use File | Load Session and File | Save Session to load/save sessions. You can turn on/off "last session autoloading" using SciTE properties variable "save.session". </p> <p> If "buffers" variable is set to "0" session management is turned off. </p> <p> Loading previously saved session will close your currently opened buffers. However you will not lose your edits, because you will be asked to save unsaved buffers first. </p> <p> Opening a specific file from command line overrides "save.session" variable state. When you start SciTE loading a specific file from command line last session will not restore even if "save.session" variable is set to "1". This makes "save.session" safe to use - you will never open a couple of files when you are trying to open just one, specific file. </p> <p> By setting "session.bookmarks" and "session.folds" variables bookmarks and folding states of the currently opened buffers are saved in session files and restored when sessions are loaded. </p> <h3 id="Languages"> Languages understood by SciTE </h3> <p> SciTE currently is able to syntax style these languages (* denotes support for folding): </p> <ul> <li>Abaqus*</li> <li>Ada</li> <li>ANS.1 MIB definition files*</li> <li>APDL</li> <li>Assembler (NASM, MASM)</li> <li>Asymptote*</li> <li>AutoIt*</li> <li>Avenue*</li> <li>Batch files (MS-DOS)</li> <li>Baan*</li> <li>Bash*</li> <li>BlitzBasic*</li> <li>Bullant*</li> <li>C/C++/C#*</li> <li>Clarion*</li> <li>cmake*</li> <li>conf (Apache)*</li> <li>CSound*</li> <li>CSS*</li> <li>D</li> <li>diff files*</li> <li>E-Script*</li> <li>Eiffel*</li> <li>Erlang*</li> <li>Flagship (Clipper / XBase)*</li> <li>Flash (ActionScript)*</li> <li>Fortran*</li> <li>Forth*</li> <li>GAP*</li> <li>Gettext</li> <li>Haskell</li> <li>HTML*</li> <li>HTML with embedded JavaScript, VBScript, PHP and ASP*</li> <li>Gui4Cli*</li> <li>IDL - both MSIDL and XPIDL*</li> <li>INI, properties* and similar</li> <li>InnoSetup*</li> <li>Java*</li> <li>JavaScript*</li> <li>LISP*</li> <li>LOT*</li> <li>Lout*</li> <li>Lua*</li> <li>Make</li> <li>Matlab*</li> <li>Metapost*</li> <li>MMIXAL</li> <li>MSSQL</li> <li>nnCron</li> <li>NSIS*</li> <li>Objective Caml*</li> <li>Opal</li> <li>Octave*</li> <li>Pascal/Delphi*</li> <li>Perl, most of it except for some ambiguous cases*</li> <li>PL/M*</li> <li>Progress*</li> <li>PostScript*</li> <li>POV-Ray*</li> <li>PowerBasic*</li> <li>PowerShell*</li> <li>PureBasic*</li> <li>Python*</li> <li>R*</li> <li>Rebol*</li> <li>Ruby*</li> <li>Scheme*</li> <li>scriptol*</li> <li>Specman E*</li> <li>Spice</li> <li>Smalltalk</li> <li>SQL and PLSQL</li> <li>TADS3*</li> <li>TeX and LaTeX</li> <li>Tcl/Tk*</li> <li>VB and VBScript*</li> <li>Verilog*</li> <li>VHDL*</li> <li>XML*</li> <li>YAML*</li> </ul> <p> Running and building commands for some of these languages have been set up but should be checked as they will have to be modified to work for many people. </p> <p> To keep menus to a reasonable length some languages are included but have been commented out in global options. These should be enabled by removing the comment character '#'. </p> <p> Language settings are determined from the file extension but this can be changed by selecting another language from the Language menu. The language menu can be changed with the menu.language property. </p> <h3 id="FindReplace"> Find and Replace </h3> <p> Either dialogs or strips may be used for find and replace, with dialogs being the default. Strips are similar to find in web browsers, appearing at the bottom of the window and are smaller and less distracting than dialogs. They are specified with the find.use.strip and replace.use.strip properties. </p> <p> SciTE has options to allow searching for words, regular expressions, matching case, in the reverse direction, wrapping around the end of the document. C style backslash escapes which are listed in the command line arguments section, may be used to search and replace control characters. Replacements can be made individually, over the current selection or over the whole file. When regular expressions are used tagged subexpressions can be used in the replacement text. Regular expressions will not match across a line end. </p> <p> SciTE supports <a href="SciTERegEx.html">basic regular expressions</a> with tagging. </p> <p> On Windows, pressing Shift+Enter when the focus is in a text entry field will search in the opposite of the current direction, so will normally search backwards. </p> <h3 id="Keyboard"> Keyboard commands </h3> <p> Keyboard commands in SciTE mostly follow common Windows and GTK+ conventions. All movement keys (arrows, page up/down, home and end) allow to extend or reduce a stream selection when holding the Shift key, and a rectangular selection when holding the Shift and Alt keys. Some keys may not be available with some national keyboards or because they are taken by the system such as by a window manager on GTK+. The user.shortcuts setting may be used to assign a key to a function. Note that Home key behaviour is changed by the vc.home.key option. Keyboard equivalents of menu commands are listed in the menus. Some less common commands with no menu equivalent are: </p> <table cellpadding="0" cellspacing="0" border="1" summary="Keyboard commands"> <tr> <td>Magnify text size.</td><td>Ctrl+Keypad+</td> </tr> <tr> <td>Reduce text size.</td><td>Ctrl+Keypad-</td> </tr> <tr> <td>Restore text size to normal.</td><td>Ctrl+Keypad/</td> </tr> <tr> <td>Cycle through recent files.</td><td>Ctrl+Tab</td> </tr> <tr> <td>Indent block.</td><td>Tab</td> </tr> <tr> <td>Dedent block.</td><td>Shift+Tab</td> </tr> <tr> <td>Delete to start of word.</td><td>Ctrl+BackSpace</td> </tr> <tr> <td>Delete to end of word.</td><td>Ctrl+Delete</td> </tr> <tr> <td>Delete to start of line.</td><td>Ctrl+Shift+BackSpace</td> </tr> <tr> <td>Delete to end of line.</td><td>Ctrl+Shift+Delete</td> </tr> <tr> <td>Go to start of document.</td><td>Ctrl+Home</td> </tr> <tr> <td>Extend selection to start of document.</td><td>Ctrl+Shift+Home</td> </tr> <tr> <td>Go to start of display line.</td><td>Alt+Home</td> </tr> <tr> <td>Go to end of document.</td><td>Ctrl+End</td> </tr> <tr> <td>Extend selection to end of document.</td><td>Ctrl+Shift+End</td> </tr> <tr> <td>Go to end of display line.</td><td>Alt+End</td> </tr> <tr> <td>Expand or contract a fold point.</td><td>Ctrl+Keypad*</td> </tr> <tr> <td>Select to next bookmark.</td><td>Alt+F2</td> </tr> <tr> <td>Select to previous bookmark.</td><td>Alt+Shift+F2</td> </tr> <tr> <td>Find selection.</td><td>Ctrl+F3</td> </tr> <tr> <td>Find selection backwards.</td><td>Ctrl+Shift+F3</td> </tr> <tr> <td>Scroll up.</td><td>Ctrl+Up</td> </tr> <tr> <td>Scroll down.</td><td>Ctrl+Down</td> </tr> <tr> <td>Line cut.</td><td>Ctrl+L</td> </tr> <tr> <td>Line copy.</td><td>Ctrl+Shift+T</td> </tr> <tr> <td>Line delete.</td><td>Ctrl+Shift+L</td> </tr> <tr> <td>Line transpose with previous.</td><td>Ctrl+T</td> </tr> <tr> <td>Selection duplicate.</td><td>Ctrl+D</td> </tr> <tr> <td>Find matching preprocessor conditional, skipping nested ones.</td><td>Ctrl+K</td> </tr> <tr> <td>Select to matching preprocessor conditional.</td><td>Ctrl+Shift+K</td> </tr> <tr> <td>Find matching preprocessor conditional backwards, skipping nested ones.</td><td>Ctrl+J</td> </tr> <tr> <td>Select to matching preprocessor conditional backwards.</td><td>Ctrl+Shift+J</td> </tr> <tr> <td>Previous paragraph. Shift extends selection.</td><td>Ctrl+[</td> </tr> <tr> <td>Next paragraph. Shift extends selection.</td><td>Ctrl+]</td> </tr> <tr> <td>Previous word. Shift extends selection.</td><td>Ctrl+Left</td> </tr> <tr> <td>Next word. Shift extends selection.</td><td>Ctrl+Right</td> </tr> <tr> <td>Previous word part. Shift extends selection</td><td>Ctrl+/</td> </tr> <tr> <td>Next word part. Shift extends selection.</td><td>Ctrl+\</td> </tr> <tr> <td>Rectangular block selection.</td><td>Alt+Shift+Movement</td> </tr> <tr> <td>Extend rectangular selection to start of line.</td><td>Alt+Shift+Home</td> </tr> <tr> <td>Extend rectangular selection to end of line.</td><td>Alt+Shift+End</td> </tr> </table> <p class="windowsonly"> On Windows, a search can be performed in the opposite direction by using Shift+Enter in the Find or Replace strips or dialogs. </p> <h3 id="Abbreviations"> Abbreviations </h3> <p> To use an abbreviation, type it and use the Expand Abbreviation command or the Ctrl+B key. The abbreviation is replaced by an expansion defined in the Abbreviations file. You can open the Abbreviations file with a command in the Options menu and add abbreviations. There is a default abbreviations file but a different abbreviations file can be set for particular file extensions. </p> <p> Each line in the files looks like "abbreviation=expansion".<br /> The abbreviations names can have any character (except perhaps control chars, surely for CR and LF), including high Ascii chars (accented chars).<br /> Names have properties files limits: they cannot start with sharp (#) or space or tab (but can have spaces inside); and they cannot have '=' character inside.<br /> Abbreviations names are limited to 32 characters. It is probably enough for <em>abbreviations</em>...<br /> </p> <p> An expansion may contain new line characters indicated by '\n' and a caret position indicated by the '|' character. To include a literal '|' character, use '||'.<br /> Some simple examples are included in the distributed Abbreviations file.<br /> When expanding, the names don't need to be separated from the previous text. Ie. if you define 'é' as '&eacute;', you can expand it inside a word.<br /> When multiple abbreviation names match, the longest matching name will be expanded. </p> <h3 id="Folding"> Folding </h3> <p> SciTE supports folding for many languages (see the list of languages understood by SciTE for more information.) Fold points are based upon indentation for Python and on counting braces for the other languages. </p> <p> The fold point markers (in the fold margin) can be clicked to expand and contract folds. Normal clicking does not alter the fold state of child fold points; naturally the children are hidden when the parent fold is contracted, but when the parent is expanded again, each child is still folded or not, as before. </p> <p> Ctrl+Click on a fold point toggles it and performs the same operation on all children. </p> <p> Shift+Click on a fold point does not toggle that fold, it expands all the child folds. </p> <p> Ctrl+Shift+Click in the fold margin expands or contracts all the top level folds. "Toggle all folds" in the View menu does the same; it toggles only top-level folds. </p> <p> Tip: To open a large code block with all its children folded, fold it with Ctrl+Click, then open it with a normal click. Then on opening a child fold, you will see that the grandchild folds are still closed; if you want those 'grandchild' folds open, Shift+Click the child fold. </p> <h3 id="PropertiesFile"> Properties file </h3> <p> Much of SciTE's behaviour can be changed by editing the properties files. </p> <p> There are four properties files used:</p> <ul> <li>Local properties file called "SciTE.properties" which may be present in the same directory as the file being edited.</li> <li>Directory properties file called "SciTEDirectory.properties" which may be present in the same or in a parent directory as the file being edited.</li> <li>User properties file called "SciTEUser.properties" on Windows and ".SciTEUser.properties" on GTK+</li> <li>Global properties file called "SciTEGlobal.properties"</li> </ul> <p> Settings in the local properties file override those in the directory properties file which overrides those in the user properties file which override those in the global properties files. Environment variables are also available as properties and these are overridden by an explicit setting in one of the properties files. </p> <p> The directory properties file can be used as project options file where user commands and compile, build commands should work in the same manner in subdirectories of a project. The benefit is that local properties files in subdirectories can be replaced by one properties file which is located at the root of the project. The evalution of the directory properties file is disabled by default and must be enabled by setting the variable properties.directory.enable to 1 in the user or global properties file. </p> <p> The user properties file is intended for customisation by the user, leaving the global properties file to contain the default options distributed with SciTE. The main use of the local properties files is to change the effects of the Compile, Build and Go commands for the files in a directory. For example, I use the javac compiler from the Java Development Kit for most work, so SciTEGlobal.properties sets the command for compiling .java files to "javac". If I want to use the jvc compiler for the files in one directory, then the SciTE.properties file in that directory contains an entry setting the command to "jvc". </p> <p> On Windows, the global properties file is located in the directory of the executable. The user properties file is looked for in the user profile directory as set in the USERPROFILE environment variable, or in the directory of the executable if USERPROFILE is not set. For GTK+ the user properties file is found in the user's home directory and the global properties in a directory set at build time - normally /usr/share/scite. If the "SciTE_HOME" environment variable is set on either Windows or GTK+ then it is where both the global and user properties files are found. </p> <p> There are commands in the Options menu for opening each of the properties files. </p> <p> The files are in approximately the same format as Java properties files which have a simple text format. Lines that start with '#' or that are completely blank are comments. Other lines are of the form </p> <p> variable=value </p> <p> For long values, a '\' character at the end of the line continues that value on the next line. Space characters are significant so <span class="example">x =1</span> defines a variable called "x ". Values may include the values of other variables by using $(variablename). There are some variables set by the environment to access the name of the current file as well: </p> <table cellpadding="0" cellspacing="0" border="1" summary="Variables set by the environment for use in property files"> <thead> <tr><th>Name</th><th>Meaning</th></tr> </thead> <tr id='property-FilePath'><td>FilePath</td><td>full path of the current file</td></tr> <tr id='property-FileDir'><td>FileDir</td><td>directory of the current file without a trailing slash</td></tr> <tr id='property-FileName'><td>FileName</td><td>base name of the current file</td></tr> <tr id='property-FileExt'><td>FileExt</td><td>extension of the current file</td></tr> <tr id='property-FileNameExt'><td>FileNameExt</td><td>$(FileName).$(FileExt)</td></tr> <tr id='property-Language'><td>Language</td><td>name of the lexer used for the current file</td></tr> <tr id='property-SessionPath'><td>SessionPath</td><td>full path of the current session</td></tr> <tr id='property-CurrentSelection'><td>CurrentSelection</td><td>value of the currently selected text</td></tr> <tr id='property-CurrentWord'><td>CurrentWord</td><td>value of word which the caret is within or near</td></tr> <tr id='property-Replacements'><td>Replacements</td><td>number of replacements made by last Replace command</td></tr> <tr id='property-SelectionStartColumn'><td>SelectionStartColumn</td><td>column where selection starts</td></tr> <tr id='property-SelectionStartLine'><td>SelectionStartLine</td><td>line where selection starts</td></tr> <tr id='property-SelectionEndColumn'><td>SelectionEndColumn</td><td>column where selection ends</td></tr> <tr id='property-SelectionEndLine'><td>SelectionEndLine</td><td>line where selection ends</td></tr> <tr id='property-CurrentMessage'><td>CurrentMessage</td><td>most recently selected output pane message</td></tr> <tr id='property-SciteDefaultHome'><td>SciteDefaultHome</td><td>directory in which the Global Options file is found</td></tr> <tr id='property-SciteUserHome'><td>SciteUserHome</td><td>directory in which the User Options file is found</td></tr> <tr id='property-SciteDirectoryHome'><td>SciteDirectoryHome</td><td>directory in which the Directory Options file is found</td></tr> <tr id='property-APIPath'><td>APIPath</td><td>list of full paths of API files from api.<i>filepattern</i></td></tr> <tr id='property-AbbrevPath'><td>AbbrevPath</td><td>full path of abbreviations file</td></tr> </table> <p> Some features use file name patterns to see which variable to use. For example, the lexer variable can be specialised for a particular file, or a group of files based upon wildcard matching so:<br /> <b>lexer.makefile=makefile</b> indicates that the lexer called "makefile" should be used on files called "makefile".<br /> <b>lexer.*.cxx=cpp</b> indicates that the lexer called "cpp" should be used on files with a "cxx" extension.<br /> Variable substitution is available on the left hand side of file pattern assignments and look like this:<br /> <b>file.patterns.html=*.html;*.htm;*.asp;*.shtml</b><br /> <b>command.go.$(file.patterns.html)=file://$(FilePath)</b> </p> <p> Wildcard matching only works where the wildcard is at the start of a file specification, so "*.mak" will match "proj.mak" but "Makefile*" will not match "Makefile.in". </p> <p> Properties files are not treated as having a particular encoding, however individual property values may be treated as having an encoding. For file names, commands, and user interface text, this is UTF-8 so it may be easier to edit properties files as UTF-8 by inserting a coding cookie as explained later. Other properties may be treated as byte sequences (like word.characters.<i>filepattern</i>) or in an implicit encoding (such as keywords.<i>filepattern</i> matching the document encoding) so that it may be better to edit these settings using a non-UTF-8 encoding. Where both UTF-8 and non-UTF-8 values are wanted, two files can be used with different encodings and an import statement to include one in the other. </p> <h3 id="ImportAndConditional"> Importing properties files and conditional logic </h3> <p> <a name="property-import"></a> The 'import' statement includes a properties file as if the text were inline at that point. The imported properties file must be in the same directory as the current file and a properties extension is assumed. Therefore a "import Lua" statement in c:\os\scite\bin\SciTEGlobal.properties will import c:\os\scite\bin\Lua.properties. </p> <p> All of the properties files in a directory can be imported with "import *". This does not import generic properties files like user properties or abbreviations. The set of files that are imported can be controlled with the imports.include and imports.exclude properties. </p> <p> <a name="property-if"></a> The 'if' statement takes one argument which is a symbol that may be defined earlier in this property set file or in a base property set. If the symbol evaluates to '0' then the test fails. An empty string or not present symbol evaluates to 0. Into the very top property set is inserted one of 'PLAT_GTK' with value '1', 'PLAT_WIN' with value '1', or 'PLAT_MAC' with value '1'. For both PLAT_GTK and PLAT_MAC, 'PLAT_UNIX' is inserted with value '1'. If the test succeeds then following indented statements are executed. When a non-indented statement is found the if clause is finished. Only simple set statements are allowed in if clauses. The evaluation of if statements occurs at read time, not at evaluation time. </p> <h3 id="Parameters"> Command parameters and prompting </h3> <p> SciTE has 4 properties $(1) .. $(4) which can be used to run commands with changeable parameters. To set the parameter values, use the View | Parameters command to view the modeless Parameters dialog which shows the current values of these parameters and allows setting new values. The accelerator keys for the main window remain active while this dialog is displayed, so it can be used to rapidly run a command several times with different parameters. Alternatively, a command can be made to display the modal Parameters dialog when executed by starting the command with a '*' which is otherwise ignored. If the modeless Parameters dialog is already visible, then the '*' is ignored. </p> <h3 id="Encodings"> Encodings </h3> <p> SciTE will automatically detect the encoding scheme used for Unicode files that start with a Byte Order Mark (BOM). The UTF-8 and UTF-16 encodings are recognised including both Little Endian and Big Endian variants of UTF-16. </p> <p> UTF-8 files will also be recognised when they contain a coding cookie on one of the first two lines. A coding cookie looks similar to "coding: utf-8" ("coding" followed by ':' or '=', optional whitespace, optional quote, "utf-8") and is normally contained in a comment:</p> <div class="example"># -*- coding: utf-8 -*-</div> For XML there is a declaration:<br /> <div class="example"><?xml version='1.0' encoding='utf-8'?></div> <p> For other encodings set the code.page and character.set properties. </p> <h3 id="DefinedVariables"> <a name="property-"></a> Defined variables in properties files </h3> <p> Some properties are only available on <span class="windowsonly">Windows</span>, <span class="gtkonly">GTK+</span>, or. <span class="osxonly">OS X</span>. </p> <table cellpadding="1" cellspacing="0" border="1" summary="Defined variables in property files"> <tr id='property-position.left'> <td> <a name='property-position.top'></a><a name='property-position.width'></a><a name='property-position.height'></a><a name='property-position.maximize'></a> position.left<br /> position.top<br /> position.width<br /> position.height<br /> position.maximize </td> <td> Set the initial window size and position. If these are omitted then the environment's defaults are used. If the width or height are -1 or the position.maximize property is set then the window is maximised. </td> </tr> <tr class="windowsonly" id='property-position.tile'> <td> position.tile </td> <td> If there is another copy of SciTE open, set the initial window position to be with the left side at position.left + position.width so that most of the time you can see both copies at once without overlap. Works nicely if position.left set to 0 and position.width set to half of the screen width. </td> </tr> <tr id='property-buffers'> <td> buffers </td> <td> Set to a number between 1 and 100 to configure that many buffers. Values outside this range are clamped to be within the range. The default is 1 which turns off UI features concerned with buffers.<br /> This value is read only once, early in the startup process and only from the global properties files. So after changing it, restart SciTE to see the effect. </td> </tr> <tr id='property-buffers.zorder.switching'> <td> buffers.zorder.switching </td> <td> This setting chooses the ordering of buffer switching when Ctrl+Tab pressed. Set to 1, the buffers are selected in the order of their previous selection otherwise they are chosen based on the buffer number. </td> </tr> <tr id='property-are.you.sure'> <td> <a name='property-are.you.sure.for.build'></a> are.you.sure<br /> are.you.sure.for.build </td> <td> The classic GUI question. Normally, when SciTE is about to close a file which has unsaved edits it asks this annoying question. To turn off the question, set are.you.sure to 0 and files will be automatically saved without bothering the user. To abandon edits to a file use the New command. New always asks "Are you sure?" giving an opportunity to not save the file.<br /> When running or building a file, its most likely that you want the file to be saved first. To enable a confirmation dialog for performing Compile, Build or Go commands, set are.you.sure.for.build=1. </td> </tr> <tr id='property-save.all.for.build'> <td> save.all.for.build </td> <td> SciTE normally saves the current buffer when performing a Compile, Build, or Go command. To save all buffers set save.all.for.build=1 </td> </tr> <tr id='property-view.whitespace'> <td> <a name='property-view.indentation.whitespace'></a> view.whitespace<br /> view.indentation.whitespace </td> <td> Setting view.whitespace to 1 makes SciTE start up with whitespace visible.<br /> Setting view.indentation.whitespace to 0 hides visible whitespace inside indentation. </td> </tr> <tr id='property-whitespace.fore'> <td> <a name='property-whitespace.back'></a> whitespace.fore<br /> whitespace.back </td> <td> Sets the colours used for displaying all visible whitespace, overriding any styling applied by the lexer. </td> </tr> <tr id='property-view.indentation.guides'> <td> <a name='property-view.indentation.examine'></a><a name='property-highlight.indentation.guides'></a> view.indentation.guides<br /> view.indentation.examine<br /> view.indentation.examine.<i>filepattern</i><br /> highlight.indentation.guides </td> <td> Setting view.indentation.guides to 1 displays dotted vertical lines within indentation white space every indent.size columns.<br /> Setting view.indentation.examine to 1 to display guides within real indentation whitespace only, 2 according to the next non-empty line (good for Python) or 3 according to both the next and previous non-empty lines (good for most languages).<br /> Setting highlight.indentation.guides to 1 highlights the indentation guide associated with a brace when that brace is highlighted. </td> </tr> <tr id='property-view.eol'> <td> view.eol </td> <td> Setting this to 1 makes SciTE display the characters that make up line ends. This looks similar to (CR), (LF), or (CR)(LF). This is useful when using files created on another operating system with software that is picky about line ends. </td> </tr> <tr id='property-eol.mode'> <td> eol.mode </td> <td> The default EOL mode (characters that make up line ends) depends on your platform. You can overwrite this behaviour by setting the property to <div class="example"> LF for UNIX and OS X format<br /> CR for Macintosh format prior to OS X<br /> CRLF for DOS/Windows format</div> </td> </tr> <tr id='property-eol.auto'> <td> eol.auto </td> <td> This setting overrides the eol.mode value and chooses the end of line character sequence based on the current contents of the file when it is opened. The line ending used the most in the file is chosen. </td> </tr> <tr id='property-blank.margin.left'> <td> <a name='property-blank.margin.right'></a> blank.margin.left<br /> blank.margin.right </td> <td> There is a blank margin on both sides of the text. It is drawn in the background colour of default text. This defaults to one pixel for both left and right sides but may be altered with these settings. </td> </tr> <tr id='property-margin.width'> <td> margin.width </td> <td> Setting this to a number makes SciTE display a selection margin to the left of the text. The value is the number of pixels wide the selection margin should be. Line markers are displayed in the selection margin area. </td> </tr> <tr class="windowsonly" id='property-full.screen.hides.menu'> <td> full.screen.hides.menu </td> <td> Setting this to 1 hides the menu bar when the Full Screen command is used on Windows. On GTK+ the menu is always visible. </td> </tr> <tr class="windowsonly" id='property-minimize.to.tray'> <td> minimize.to.tray </td> <td> Setting this to 1 minimizes SciTE to the system tray rather than to the task bar. </td> </tr> <tr id='property-line.margin.visible'> <td> <a name='property-line.margin.width'></a> line.margin.visible<br /> line.margin.width </td> <td> SciTE is able to display a column of line numbers to the left of the selection margin. Setting line.margin.visible to 1 makes this column visible at startup. The line.margin.width property controls how much space is reserved for the line numbers, in terms of the number of digits that can be displayed. To specify that the margin should expand if needed to accomodate larger line numbers, add a '+' after the number of digits, e.g. <span class="example">line.margin.width=3+</span>. </td> </tr> <tr id='property-tabbar.visible'> <td> tabbar.visible </td> <td> Setting tabbar.visible to 1 makes the tab bar visible at start up. The buffers property must be set to a value greater than 1 for this option to work. </td> </tr> <tr id='property-tabbar.hide.one'> <td> tabbar.hide.one </td> <td> Setting tabbar.hide.one to 1 hides the tab bar until there is more than one tab. </td> </tr> <tr class="windowsonly" id='property-tabbar.multiline'> <td> tabbar.multiline </td> <td> Setting tabbar.multiline uses multiple lines for the tab bar </td> </tr> <tr id='property-toolbar.visible'> <td> toolbar.visible </td> <td> Setting this to 1 makes the tool bar visible at start up. </td> </tr> <tr class="gtkonly" id='property-toolbar.usestockicons'> <td> toolbar.usestockicons </td> <td> SciTE has a built-in icon set for the toolbar, setting this to 1 makes SciTE more integrated in the GNOME desktop by using the icons provided by the current theme used in GNOME. </td> </tr> <tr class="gtkonly" id='property-pathbar.visible'> <td> pathbar.visible </td> <td> The path bar is a line of text under the tab bar showing the full path of the currently selected tab. Setting pathbar.visible to 1 makes the path bar visible on GTK+. </td> </tr> <tr id='property-undo.redo.lazy'> <td> undo.redo.lazy </td> <td> Setting this to 1 changes the technique used to determine when to enable or disable tool bar buttons to be less accurate. This may improve performance on slow machines. </td> </tr> <tr id='property-statusbar.visible'> <td> statusbar.visible </td> <td> Setting this to 1 makes the status bar visible at start up. </td> </tr> <tr id='property-statusbar.number'> <td> <a name='property-statusbar.text'></a> statusbar.number<br /> statusbar.text.<i>number</i> </td> <td> The statusbar.text.1 option defines the information displayed in the status bar by default on all platforms. Property values may be used in this text using the $() syntax. Commonly used properties are: ReadOnly, EOLMode, BufferLength, NbOfLines (in buffer), SelLength (chars), SelHeight (lines). Extra properties defined for the status bar are LineNumber, ColumnNumber, and OverType which is either "OVR" or "INS" depending on the overtype status. You can also use file properties, which, unlike those above, are not updated on each keystroke: FileName or FileNameExt, FileDate and FileTime and FileAttr. Plus CurrentDate and CurrentTime.<br /> On Windows only, further texts may be set as statusbar.text.2 .. and these may be cycled between by clicking the status bar.<br /> The statusbar.number option defines how many texts are to be cycled through. </td> </tr> <tr id='property-buffered.draw'> <td> buffered.draw </td> <td> Setting this to 0 rather than the default 1 makes SciTE draw output directly to the screen rather than into a buffer bitmap first and then to the screen. Buffered drawing flickers less but is slower. </td> </tr> <tr id='property-two.phase.draw'> <td> two.phase.draw </td> <td> Two phase drawing is a better but slower way of drawing text. In single phase drawing each run of characters in one style is drawn along with its background. If a character overhangs the end of a run, such as in "<i>V</i>_" where the "<i>V</i>" is in a different style from the "_", then this can cause the right hand side of the "<i>V</i>" to be overdrawn by the background of the "_" which cuts it off. Two phase drawing fixes this by drawing all the backgrounds first and then drawing the text in transparent mode. Two phase drawing may flicker more than single phase unless buffered drawing is on. The default is for drawing to be two phase. </td> </tr> <tr class="windowsonly" id='property-technology'> <td> technology </td> <td> On Windows Vista or newer, this can be set to 1 to use the Direct2D and DirectWrite APIs for higher quality antialiased drawing. The default is 0. </td> </tr> <tr id='property-load.on.activate'> <td> <a name='property-save.on.deactivate'></a> load.on.activate<br /> save.on.deactivate </td> <td> The load.on.activate property causes SciTE to check whether the current file has been updated by another process whenever it is activated. This is useful when another editor such as a WYSIWYG HTML editor, is being used in conjunction with SciTE.<br /> The save.on.deactivate property causes SciTE to save the file whenever the SciTE application loses focus. This is useful when developing web pages and you want to often check the appearance of the page in a browser. </td> </tr> <tr id='property-are.you.sure.on.reload'> <td> are.you.sure.on.reload </td> <td> When both this and load.on.activate are set to 1, SciTE will ask if you really want to reload the modified file, giving you the chance to keep the file as it is. By default this property is disabled, causing SciTE to reload the file without bothering you. </td> </tr> <tr id='property-save.on.timer'> <td> save.on.timer </td> <td> The save.on.timer property causes SciTE to save modified files whenever there have been no modifications for the number of seconds specified by the property. When set to 0, the default, this feature is disabled and files are not automatically saved. </td> </tr> <tr id='property-reload.preserves.undo'> <td> reload.preserves.undo </td> <td> When set to 1, reloading a file does not delete all the undo history. This is useful when load.on.activate is used in conjunction with filter commands. </td> </tr> <tr id='property-check.if.already.open'> <td> check.if.already.open </td> <td> This option allows opening files in an existing instance of SciTE rather than always opening a new instance. When this option is set and SciTE is started, it checks to see if there are any other instances of SciTE open. If there is, another instance is asked to open the file and become active and the new instance exits. On Windows, the instance with the Options | Open Files Here menu item checked opens the file. On GTK+, an arbitrary instance opens the file. </td> </tr> <tr id='property-read.only'> <td> read.only </td> <td> When this option is set then opened documents are initially read only. New files are not affected by this setting. </td> </tr> <tr id='property-background.open.size'> <td> <a name='property-background.save.size'></a> background.open.size<br /> background.save.size </td> <td> This setting controls whether files are opened and saved without blocking the user interface while they are being read or written. Files larger than the given size in bytes will be read or written in the background while smaller files will be read or written directly and SciTE will not respond until the file access is completed. The default value is -1 allows background processing for all files. For saving, the size used is the in-memory size in bytes which will differ from the on-disk size when the UTF-16 encoding is used. </td> </tr> <tr class="windowsonly" id='property-temp.files.sync.load'> <td> temp.files.sync.load </td> <td> Files dropped on SciTE on Windows are normally opened asynchronously as there may be a long list. However, files dragged from some applications such as 7-Zip may only exist for a moment in the temporary directory and be deleted once the drop has occurred.<br /> Setting this to 1 makes SciTE open dropped files in the temporary directory immediately. </td> </tr> <tr id='property-quit.on.close.last'> <td> quit.on.close.last </td> <td> If this option is set, SciTE will close when its last buffer has been closed, e.g. with File/Close. (By default, if this option is not set, SciTE will remain open and will create a new blank document when its last buffer is closed.) </td> </tr> <tr id='property-highlight.current.word'> <td> highlight.current.word </td> <td> When set to 1, all occurrences of the selected word are highlighted with the colour defined by highlight.current.word.colour. By default, this option is disabled. (See indicators.alpha and indicators.under) </td> </tr> <tr id='property-highlight.current.word.colour'> <td> <a name='property-highlight.current.word.by.style'></a> highlight.current.word.colour<br /> highlight.current.word.by.style </td> <td> The option highlight.current.word.colour defines the colour of highlight. The default value is #A0A000.<br /> If the option highlight.current.word.by.style is set, then only words with the same style are highlighted (e.g. if you select this word in a comment, then only occurrences of words in comments are selected). </td> </tr> <tr class="gtkonly" id='property-rectangular.selection.modifier'> <td> rectangular.selection.modifier </td> <td> On GTK+, the modifier key used to make rectangular selections can be set with this property. Valid options are 2 (Ctrl), 4 (Alt) or 8 (Super). Super is often assigned to the Windows/Start key on Windows keyboards or the Command key on Mac keyboards. <br /> Since the Alt key is often used by window managers to move windows, this will need to be configured off to use the combination in SciTE. This can be done for Metacity using gconf-editor to modify the /apps/metacity/general/mouse_button_modifier. A valid value here is <Super>. </td> </tr> <tr id='property-selection.fore'> <td> <a name='property-selection.back'></a><a name='property-selection.alpha'></a> selection.fore<br /> selection.back<br /> selection.alpha </td> <td> Sets the colours used for displaying selected text. If one of these is not set then that attribute is not changed for the selection. The default is to show the selection by changing the background to light grey and leaving the foreground the same as when it was not selected. The translucency of the selection is set with selection.alpha with an alpha of 256 turning translucency off. </td> </tr> <tr id='property-caret.fore'> <td> caret.fore </td> <td> Sets the colour used for the caret. </td> </tr> <tr id='property-selection.additional.fore'> <td> <a name='property-selection.additional.back'></a><a name='property-selection.additional.alpha'></a> selection.additional.fore<br /> selection.additional.back<br /> selection.additional.alpha </td> <td> Similar to selection.fore, selection.back, selection.alpha. Sets the colours used for displaying additional selections when multiple selections are enabled or a rectangular selection is made. </td> </tr> <tr id='property-caret.additional.blinks'> <td> caret.additional.blinks </td> <td> Set whether all carets blink. 0 means only the main caret blinks. Default is 1. </td> </tr> <tr id='property-caret.line.back'> <td> <a name='property-caret.line.back.alpha'></a> caret.line.back<br /> caret.line.back.alpha </td> <td> Sets the background colour and translucency used for line containing the caret. Translucency ranges from 0 for completely transparent to 255 for opaque with 256 being opaque and not using translucent drawing code which may be slower. </td> </tr> <tr id='property-caret.period'> <td> caret.period </td> <td> Sets the rate at which the caret blinks. The value is the time in milliseconds that the caret is visible before it is switched to invisible. It then stays invisible for the same period before appearing again. A value of 0 stops the caret from blinking. </td> </tr> <tr id='property-caret.width'> <td> caret.width </td> <td> Sets the width of the caret in pixels. Only values of 1, 2, or 3 work. </td> </tr> <tr id='property-selection.multiple'> <td> <a name='property-selection.additional.typing'></a> selection.multiple<br /> selection.additional.typing </td> <td> Set selection.multiple to make multiple selections with the mouse by holding down the Ctrl key.<br /> Set selection.additional.typing to 1. to allow typing, backspace and delete to affect all selections including each line of rectangular selections. When set to 0, typing only affectes the main selection. </td> </tr> <tr id='property-virtual.space'> <td> virtual.space </td> <td> Determines whether the caret can be moved into virtual space, that is, beyond the last character on a line. Set to 1 to allow virtual space when making a rectangular selection, 2 to allow the arrow keys or a mouse click to move the caret into virtual space, and 3 to allow both. </td> </tr> <tr id='property-caret.policy.xslop'> <td> <a name='property-caret.policy.width'></a><a name='property-caret.policy.xstrict'></a><a name='property-caret.policy.xeven'></a><a name='property-caret.policy.xjumps'></a><a name='property-caret.policy.yslop'></a><a name='property-caret.policy.lines'></a><a name='property-caret.policy.ystrict'></a><a name='property-caret.policy.yeven'></a><a name='property-caret.policy.yjumps'></a> caret.policy.xslop<br /> caret.policy.width<br /> caret.policy.xstrict<br /> caret.policy.xeven<br /> caret.policy.xjumps<br /><br /> caret.policy.yslop<br /> caret.policy.lines<br /> caret.policy.ystrict<br /> caret.policy.yeven<br /> caret.policy.yjumps<br /> </td> <td> <p>If slop is set, we can define a slop value: width for xslop, lines for yslop.<br /> This value defines an unwanted zone (UZ) where the caret is... unwanted.<br /> This zone is defined as a number of pixels near the vertical margins, and as a number of lines near the horizontal margins.<br /> By keeping the caret away from the edges, it is seen within its context, so it is likely that the identifier that the caret is on can be completely seen, and that the current line is seen with some of the lines following it which are often dependent on that line.</p> <p>If strict is set, the policy is enforced... strictly.<br /> The caret is centred on the display if slop is not set, and cannot go in the UZ if slop is set.</p> <p>If jumps is set, the display is moved more energetically so the caret can move in the same direction longer before the policy is applied again.<br /> '3UZ' notation is used to indicate three time the size of the UZ as a distance to the margin.</p> <p>If even is not set, instead of having symmetrical UZs, the left and bottom UZs are extended up to right and top UZs respectively.<br /> This way, we favour the displaying of useful information: the begining of lines, where most code reside, and the lines after the caret, eg. the body of a function.</p> <p>See the table below to see how these settings interact.<br /> Default: xslop, yslop, xeven, yeven=1, width=50, all others = 0.</p> </td> </tr> <tr id='property-visible.policy.strict'> <td> <a name='property-visible.policy.slop'></a><a name='property-visible.policy.lines'></a> visible.policy.strict<br /> visible.policy.slop<br /> visible.policy.lines </td> <td> Determines how the display area is determined after a Go to command or equivalent such as a Find or Next Message. Options are similar to caret.policy.*. </td> </tr> <tr id='property-edge.mode'> <td> <a name='property-edge.column'></a><a name='property-edge.colour'></a> edge.mode<br /> edge.column<br /> edge.colour<br /> </td> <td> Indicates long lines. The default edge.mode, 0, does not indicate long lines. An edge.mode of 1 uses a vertical line to indicate the specified column and an edge.mode of 2 changes the background colour of characters beyond that column. For proportional fonts, an edge.mode of 2 is more useful than 1. </td> </tr> <tr id='property-control.char.symbol'> <td> control.char.symbol </td> <td> Sets the character to use to indicate control characters. If not set, control characters are shown as mnemonics. </td> </tr> <tr id='property-error.marker.fore'> <td> <a name='property-error.marker.back'></a> error.marker.fore<br /> error.marker.back </td> <td> The colours used to indicate error and warning lines in both the edit and output panes are set with these two values. If there is a margin on a pane then a symbol is displayed in the margin to indicate the error message for the output pane or the line causing the error message for the edit pane. The error.marker.back is used as the fill colour of the symbol and the error.marker.fore as the outline colour. If there is no margin then the background to the line is set to the error.marker.back colour. </td> </tr> <tr id='property-error.inline'> <td> <a name='property-style.error.0'></a><a name='property-style.error.1'></a><a name='property-style.error.2'></a><a name='property-style.error.3'></a> error.inline<br /> style.error.0<br /> style.error.1<br /> style.error.2<br /> style.error.3 </td> <td> To see error messages interspersed with the source code, set error.inline=1.<br /> Different visual styles are used for different severities: style.error.0 is the default; style.error.1 for warnings; style.error.2 for errors; and style.error.3 for fatal errors. The severity of a message is inferred from finding the text "warning", "error", or "fatal" in the message. </td> </tr> <tr id='property-bookmark.fore'> <td> <a name='property-bookmark.back'></a><a name='property-bookmark.alpha'></a> bookmark.fore<br /> bookmark.back<br /> bookmark.alpha </td> <td> The colours used to display bookmarks in the margin. If bookmark.fore is not set then a blue sphere is used. When the margin is turned off, bookmarks are shown by a change in the background colour of the line with the translucency set with bookmark.alpha. </td> </tr> <tr id='property-find.mark'> <td> find.mark </td> <td> If set, then the Mark All command in the Find dialog will draw translucent boxes over each string found. (See indicators.alpha and indicators.under) </td> </tr> <tr id='property-indicators.alpha'> <td> indicators.alpha </td> <td> This property defines the alpha level for indicators (default value is 30). The alpha value can range from 0 (completely transparent) to 255 (no transparency). A value out of this range is ignored and the default one is used. </td> </tr> <tr id='property-indicators.under'> <td> indicators.under </td> <td> If set, the indicators are drawn under text or over (by default, it is over). </td> </tr> <tr id='property-error.select.line'> <td> error.select.line </td> <td> When a command execution produces error messages, and you step with F4 key through the matching source lines, this option selects the line where the error occurs. Most useful if the error message contains the column of error too as the selection will start at the column of the error. The error message must contain the column and must be understood by SciTE (currently only supported for HTML Tidy). The tab size assumed by the external tool must match the tab size of your source file for correct column reporting. </td> </tr> <tr id='property-openpath'> <td>openpath.<i>filepattern</i></td> <td>Defines a path for the Open Selected Filename command in the File menu. The path is searched if the selected filename doesn't contain an absolute path or the file is not found in the document directory. The directories in openpath are separated by ';' on Windows and ':' on OS X and GTK+.<br /> An openpath setting may look like: <div class="example"> openpath.*.txt=c:\dos\;f:\;<br /> openpath.$(file.patterns.cpp)=$(cpp_includes)</div> </td> </tr> <tr id='property-open.suffix'> <td>open.suffix.<i>filepattern</i></td> <td>Defines a suffix to add to the selected file name for the Open Selected Filename command in the File menu. This is used in languages where the suffix is not given when accessing a file. An example is python where "import xlib" will most often mean to import from a file called "xlib.py".<br /> An open.suffix setting may look like:<br /> <div class="example">open.suffix.*.py=.py</div> </td> </tr> <tr id='property-strip.trailing.spaces'> <td> strip.trailing.spaces<br /> strip.trailing.spaces.<i>filepattern</i> </td> <td> Strips trailing white spaces from the file while saving.<br /> The global strip.trailing.spaces property can be overridden for files that match a pattern by using the file pattern forms: <br /> <div class="example"> strip.trailing.spaces.*.yaml=0<br /> or <br /> strip.trailing.spaces.$(file.patterns.yaml)=0<br /> </div> </td> </tr> <tr id='property-ensure.final.line.end'> <td> ensure.final.line.end </td> <td> Ensures file ends with a line end when saved. </td> </tr> <tr id='property-ensure.consistent.line.ends'> <td> ensure.consistent.line.ends </td> <td> Ensures all lines end with the current Line End Characters setting when saved. </td> </tr> <tr id='property-abbreviations'> <td> abbreviations.<i>filepattern</i> </td> <td> Loads an abbreviations file for a particular language overriding the default abbreviations file. For example, <div class="example"> abbreviations.*.c=$(SciteUserHome)/c_abbrev.properties<br /> </div> </td> </tr> <tr id='property-api'> <td> api.<i>filepattern</i> </td> <td> Loads a set of API files for a particular language. If there is more than one API file then the file names are separated by ';'. API files contain a sorted list of identifiers and function prototypes, one per line. If there are multiple files then each file should end with a line end or the next file's first line will merge with the previous file's last line. The "Complete Symbol" command looks at the characters before the caret and displayed the subset of the API file starting with that string. When an opening brace is typed, the file is searched for the text preceding the caret and if a function prototype is found then it is displayed as a calltip. For example, the setting <div class="example"> api.*.c=w.api<br /> </div> could be used with a w.api file containing <div class="example"> fclose(FILE* fileClose)<br /> FILE<br /> fopen(const char* szFileName, const char* szMode)<br /> fpos_t<br /> fread(void* buf, size_t size, size_t count, FILE* file)<br /> fseek(FILE* file, long lnOffset, int nOrigin)<br /> </div> to provide autocompletion and calltips for some of the C file functions. It is best to use the full path to the API file as otherwise the current directory is used. See the Creating API files section for ways to create API files. </td> </tr> <tr id='property-autocomplete.choose.single'> <td> autocomplete.choose.single </td> <td> When set to 1 and an autocompletion list is invoked and there is only one element in that list then that element is automatically chosen. This means that the matched element is inserted and the list is not displayed. </td> </tr> <tr id='property-autocomplete.*.ignorecase'> <td> autocomplete.<i>lexer</i>.ignorecase<br /> autocomplete.*.ignorecase </td> <td> When set to 1 the API file is searched in a case insensitive way to find elements for autocompletion lists. Otherwise matches only occur if case also matches. The * form is used if there is no lexer specific setting. </td> </tr> <tr id='property-autocomplete.*.start.characters'> <td> autocomplete.<i>lexer</i>.start.characters<br /> autocomplete.*.start.characters </td> <td> If this setting is not empty, typing any of the characters will cause autocompletion to start. For example, if autocomplete.python.start.characters=. and the API file for Python contains "string.rjust" and "string.replace" then typing "string." will cause the autocompletion to display both identifiers. The * form is used if there is no lexer specific setting. </td> </tr> <tr id='property-autocomplete.*.fillups'> <td> autocomplete.<i>lexer</i>.fillups<br /> autocomplete.*.fillups </td> <td> If this setting is not empty, typing any of the characters will cause autocompletion to complete. For example, if autocomplete.python.fillups=( and the API file for Python contains "string.replace" then typing "string.r(" will cause "string.replace(" to be inserted. The * form is used if there is no lexer specific setting. </td> </tr> <tr id='property-autocompleteword.automatic'> <td> autocompleteword.automatic </td> <td> If this setting is 1 then when typing a word, if only one word in the document starts with that string then an autocompletion list is displayed with that word so it can be chosen by pressing Tab. </td> </tr> <tr id='property-calltip.*.ignorecase'> <td> calltip.<i>lexer</i>.ignorecase<br /> calltip.*.ignorecase </td> <td> When set to 1 the API file is searched in a case insensitive way to find the function which will have its signature displayed as a calltip. The * form is used if there is no lexer specific setting. </td> </tr> <tr id='property-calltip.*.use.escapes'> <td> calltip.<i>lexer</i>.use.escapes<br /> calltip.*.use.escapes </td> <td> When set to 1 the API file may contain C style backslash escapes which are listed in the command line arguments section. The * form is used if there is no lexer specific setting. </td> </tr> <tr id='property-calltip.*.word.characters'> <td> calltip.<i>lexer</i>.word.characters<br /> calltip.*.word.characters </td> <td> To determine the identifier to look up for calltips, a search is performed allowing the characters in this set to be included in the identifier. While the same setting can be used as for word.characters, sometimes additional characters may be allowed. For example, in Python, '.' is not normally considered part of a word when selecting text, but it is good to allow "string.replace" to show a calltip so calltip.python.word.characters=._$(chars.alpha) would be a reasonable setting. The * form is used if there is no lexer specific setting. </td> </tr> <tr id='property-calltip.*.parameters.start'> <td> <a name='property-calltip.*.parameters.end'></a><a name='property-calltip.*.parameters.separators'></a> calltip.<i>lexer</i>.parameters.start<br /> calltip.<i>lexer</i>.parameters.end<br /> calltip.<i>lexer</i>.parameters.separators<br /> calltip.*.parameters.start<br /> calltip.*.parameters.end<br /> calltip.*.parameters.separators </td> <td> Allows you to specify characters which start, end and separate parameters. For most common languages, it's usually left brace for start, right brace for end and comma or semicolon for separator. E.g. CSS has colon for start, space for separator and nothing for end. You can specify more characters for each property. The * form is used if there is no lexer specific setting. </td> </tr> <tr id='property-calltip.*.end.definition'> <td> calltip.<i>lexer</i>.end.definition<br /> calltip.*.end.definition </td> <td> API files may contain explanatory text after each function definition. To display the explanation on a second line, set this property to the character used at the end of the definition part. For most languages, this is ')'. The * form is used if there is no lexer specific setting. </td> </tr> <tr id='property-xml.auto.close.tags'> <td> xml.auto.close.tags </td> <td> For XML and HTML, setting this property to 1 will automatically insert the corresponding end tag when '>' is typed to end a start tag. Type "<td>" and the result will be "<td></td>" with the caret placed between the tags. </td> </tr> <!--++Autogenerated - run ../../scintilla/src/LexGen.py to regenerate --> <!--**\(\*\n\) --> <tr id='property-asp.default.language'> <td>asp.default.language</td> <td>Script in ASP code is initially assumed to be in JavaScript. To change this to VBScript set asp.default.language to 2. Python is 3.</td> </tr> <tr id='property-fold.asm.comment.explicit'> <td>fold.asm.comment.explicit</td> <td>This option enables folding explicit fold points when using the Asm lexer. Explicit fold points allows adding extra folding by placing a ;{ comment at the start and a ;} at the end of a section that should fold.</td> </tr> <tr id='property-fold.asm.comment.multiline'> <td>fold.asm.comment.multiline</td> <td>Set this property to 1 to enable folding multi-line comments.</td> </tr> <tr id='property-fold.asm.explicit.anywhere'> <td>fold.asm.explicit.anywhere</td> <td>Set this property to 1 to enable explicit fold points anywhere, not just in line comments.</td> </tr> <tr id='property-fold.asm.explicit.end'> <td>fold.asm.explicit.end</td> <td>The string to use for explicit fold end points, replacing the standard ;}.</td> </tr> <tr id='property-fold.asm.explicit.start'> <td>fold.asm.explicit.start</td> <td>The string to use for explicit fold start points, replacing the standard ;{.</td> </tr> <tr id='property-fold.asm.syntax.based'> <td>fold.asm.syntax.based</td> <td>Set this property to 0 to disable syntax based folding.</td> </tr> <tr id='property-fold.at.else'> <td>fold.at.else</td> <td>This option enables C++ folding on a "} else {" line of an if statement.</td> </tr> <tr id='property-fold.basic.comment.explicit'> <td>fold.basic.comment.explicit</td> <td>This option enables folding explicit fold points when using the Basic lexer. Explicit fold points allows adding extra folding by placing a ;{ (BB/PB) or '{ (FB) comment at the start and a ;} (BB/PB) or '} (FB) at the end of a section that should be folded.</td> </tr> <tr id='property-fold.basic.explicit.anywhere'> <td>fold.basic.explicit.anywhere</td> <td>Set this property to 1 to enable explicit fold points anywhere, not just in line comments.</td> </tr> <tr id='property-fold.basic.explicit.end'> <td>fold.basic.explicit.end</td> <td>The string to use for explicit fold end points, replacing the standard ;} (BB/PB) or '} (FB).</td> </tr> <tr id='property-fold.basic.explicit.start'> <td>fold.basic.explicit.start</td> <td>The string to use for explicit fold start points, replacing the standard ;{ (BB/PB) or '{ (FB).</td> </tr> <tr id='property-fold.basic.syntax.based'> <td>fold.basic.syntax.based</td> <td>Set this property to 0 to disable syntax based folding.</td> </tr> <tr id='property-fold.comment'> <td>fold.comment</td> <td>This option enables folding multi-line comments and explicit fold points when using the C++ lexer. Explicit fold points allows adding extra folding by placing a //{ comment at the start and a //} at the end of a section that should fold.</td> </tr> <tr id='property-fold.cpp.comment.explicit'> <td>fold.cpp.comment.explicit</td> <td>Set this property to 0 to disable folding explicit fold points when fold.comment=1.</td> </tr> <tr id='property-fold.cpp.comment.multiline'> <td>fold.cpp.comment.multiline</td> <td>Set this property to 0 to disable folding multi-line comments when fold.comment=1.</td> </tr> <tr id='property-fold.cpp.explicit.anywhere'> <td>fold.cpp.explicit.anywhere</td> <td>Set this property to 1 to enable explicit fold points anywhere, not just in line comments.</td> </tr> <tr id='property-fold.cpp.explicit.end'> <td>fold.cpp.explicit.end</td> <td>The string to use for explicit fold end points, replacing the standard //}.</td> </tr> <tr id='property-fold.cpp.explicit.start'> <td>fold.cpp.explicit.start</td> <td>The string to use for explicit fold start points, replacing the standard //{.</td> </tr> <tr id='property-fold.cpp.syntax.based'> <td>fold.cpp.syntax.based</td> <td>Set this property to 0 to disable syntax based folding.</td> </tr> <tr id='property-fold.d.comment.explicit'> <td>fold.d.comment.explicit</td> <td>Set this property to 0 to disable folding explicit fold points when fold.comment=1.</td> </tr> <tr id='property-fold.d.comment.multiline'> <td>fold.d.comment.multiline</td> <td>Set this property to 0 to disable folding multi-line comments when fold.comment=1.</td> </tr> <tr id='property-fold.d.explicit.anywhere'> <td>fold.d.explicit.anywhere</td> <td>Set this property to 1 to enable explicit fold points anywhere, not just in line comments.</td> </tr> <tr id='property-fold.d.explicit.end'> <td>fold.d.explicit.end</td> <td>The string to use for explicit fold end points, replacing the standard //}.</td> </tr> <tr id='property-fold.d.explicit.start'> <td>fold.d.explicit.start</td> <td>The string to use for explicit fold start points, replacing the standard //{.</td> </tr> <tr id='property-fold.d.syntax.based'> <td>fold.d.syntax.based</td> <td>Set this property to 0 to disable syntax based folding.</td> </tr> <tr id='property-fold.html'> <td>fold.html</td> <td>Folding is turned on or off for HTML and XML files with this option. The fold option must also be on for folding to occur.</td> </tr> <tr id='property-fold.html.preprocessor'> <td>fold.html.preprocessor</td> <td>Folding is turned on or off for scripts embedded in HTML files with this option. The default is on.</td> </tr> <tr id='property-fold.hypertext.comment'> <td>fold.hypertext.comment</td> <td>Allow folding for comments in scripts embedded in HTML. The default is off.</td> </tr> <tr id='property-fold.hypertext.heredoc'> <td>fold.hypertext.heredoc</td> <td>Allow folding for heredocs in scripts embedded in HTML. The default is off.</td> </tr> <tr id='property-fold.perl.at.else'> <td>fold.perl.at.else</td> <td>This option enables Perl folding on a "} else {" line of an if statement.</td> </tr> <tr id='property-fold.perl.comment.explicit'> <td>fold.perl.comment.explicit</td> <td>Set to 0 to disable explicit folding.</td> </tr> <tr id='property-fold.perl.package'> <td>fold.perl.package</td> <td>Set to 0 to disable folding packages when using the Perl lexer.</td> </tr> <tr id='property-fold.perl.pod'> <td>fold.perl.pod</td> <td>Set to 0 to disable folding Pod blocks when using the Perl lexer.</td> </tr> <tr id='property-fold.preprocessor'> <td>fold.preprocessor</td> <td>This option enables folding preprocessor directives when using the C++ lexer. Includes C#'s explicit #region and #endregion folding directives.</td> </tr> <tr id='property-fold.quotes.python'> <td>fold.quotes.python</td> <td>This option enables folding multi-line quoted strings when using the Python lexer.</td> </tr> <tr id='property-fold.sql.at.else'> <td>fold.sql.at.else</td> <td>This option enables SQL folding on a "ELSE" and "ELSIF" line of an IF statement.</td> </tr> <tr id='property-html.tags.case.sensitive'> <td>html.tags.case.sensitive</td> <td>For XML and HTML, setting this property to 1 will make tags match in a case sensitive way which is the expected behaviour for XML and XHTML.</td> </tr> <tr id='property-lexer.asm.comment.delimiter'> <td>lexer.asm.comment.delimiter</td> <td>Character used for COMMENT directive's delimiter, replacing the standard "~".</td> </tr> <tr id='property-lexer.cpp.allow.dollars'> <td>lexer.cpp.allow.dollars</td> <td>Set to 0 to disallow the '$' character in identifiers with the cpp lexer.</td> </tr> <tr id='property-lexer.cpp.hashquoted.strings'> <td>lexer.cpp.hashquoted.strings</td> <td>Set to 1 to enable highlighting of hash-quoted strings.</td> </tr> <tr id='property-lexer.cpp.track.preprocessor'> <td>lexer.cpp.track.preprocessor</td> <td>Set to 1 to interpret #if/#else/#endif to grey out code that is not active.</td> </tr> <tr id='property-lexer.cpp.triplequoted.strings'> <td>lexer.cpp.triplequoted.strings</td> <td>Set to 1 to enable highlighting of triple-quoted strings.</td> </tr> <tr id='property-lexer.cpp.update.preprocessor'> <td>lexer.cpp.update.preprocessor</td> <td>Set to 1 to update preprocessor definitions when #define found.</td> </tr> <tr id='property-lexer.css.hss.language'> <td>lexer.css.hss.language</td> <td>Set to 1 for HSS (.hss)</td> </tr> <tr id='property-lexer.css.less.language'> <td>lexer.css.less.language</td> <td>Set to 1 for Less CSS (.less)</td> </tr> <tr id='property-lexer.css.scss.language'> <td>lexer.css.scss.language</td> <td>Set to 1 for Sassy CSS (.scss)</td> </tr> <tr id='property-lexer.d.fold.at.else'> <td>lexer.d.fold.at.else</td> <td>This option enables D folding on a "} else {" line of an if statement.</td> </tr> <tr id='property-lexer.errorlist.value.separate'> <td>lexer.errorlist.value.separate</td> <td>For lines in the output pane that are matches from Find in Files or GCC-style diagnostics, style the path and line number separately from the rest of the line with style 21 used for the rest of the line. This allows matched text to be more easily distinguished from its location.</td> </tr> <tr id='property-lexer.flagship.styling.within.preprocessor'> <td>lexer.flagship.styling.within.preprocessor</td> <td>For Harbour code, determines whether all preprocessor code is styled in the preprocessor style (0) or only from the initial # to the end of the command word(1, the default). It also determines how to present text, dump, and disabled code.</td> </tr> <tr id='property-lexer.html.django'> <td>lexer.html.django</td> <td>Set to 1 to enable the django template language.</td> </tr> <tr id='property-lexer.html.mako'> <td>lexer.html.mako</td> <td>Set to 1 to enable the mako template language.</td> </tr> <tr id='property-lexer.props.allow.initial.spaces'> <td>lexer.props.allow.initial.spaces</td> <td>For properties files, set to 0 to style all lines that start with whitespace in the default style. This is not suitable for SciTE .properties files which use indentation for flow control but can be used for RFC2822 text where indentation is used for continuation lines.</td> </tr> <tr id='property-lexer.python.keywords2.no.sub.identifiers'> <td>lexer.python.keywords2.no.sub.identifiers</td> <td>When enabled, it will not style keywords2 items that are used as a sub-identifier. Example: when set, will not highlight "foo.open" when "open" is a keywords2 item.</td> </tr> <tr id='property-lexer.python.literals.binary'> <td>lexer.python.literals.binary</td> <td>Set to 0 to not recognise Python 3 binary and octal literals: 0b1011 0o712.</td> </tr> <tr id='property-lexer.python.strings.b'> <td>lexer.python.strings.b</td> <td>Set to 0 to not recognise Python 3 bytes literals b"x".</td> </tr> <tr id='property-lexer.python.strings.over.newline'> <td>lexer.python.strings.over.newline</td> <td>Set to 1 to allow strings to span newline characters.</td> </tr> <tr id='property-lexer.python.strings.u'> <td>lexer.python.strings.u</td> <td>Set to 0 to not recognise Python Unicode literals u"x" as used before Python 3.</td> </tr> <tr id='property-lexer.sql.allow.dotted.word'> <td>lexer.sql.allow.dotted.word</td> <td>Set to 1 to colourise recognized words with dots (recommended for Oracle PL/SQL objects).</td> </tr> <tr id='property-lexer.sql.numbersign.comment'> <td>lexer.sql.numbersign.comment</td> <td>If "lexer.sql.numbersign.comment" property is set to 0 a line beginning with '#' will not be a comment.</td> </tr> <tr id='property-lexer.xml.allow.scripts'> <td>lexer.xml.allow.scripts</td> <td>Set to 0 to disable scripts in XML.</td> </tr> <tr id='property-sql.backslash.escapes'> <td>sql.backslash.escapes</td> <td>Enables backslash as an escape character in SQL.</td> </tr> <tr id='property-styling.within.preprocessor'> <td>styling.within.preprocessor</td> <td>For C++ code, determines whether all preprocessor code is styled in the preprocessor style (0, the default) or only from the initial # to the end of the command word(1).</td> </tr> <tr id='property-tab.timmy.whinge.level'> <td>tab.timmy.whinge.level</td> <td>For Python code, checks whether indenting is consistent. The default, 0 turns off indentation checking, 1 checks whether each line is potentially inconsistent with the previous line, 2 checks whether any space characters occur before a tab character in the indentation, 3 checks whether any spaces are in the indentation, and 4 checks for any tab characters in the indentation. 1 is a good level to use.</td> </tr> <!----Autogenerated -- end of automatically generated section --> <tr id='property-user.shortcuts'> <td> user.shortcuts </td> <td> Define keys that perform commands. This is a '|' delimited list of keys and the commands they produce. The commands are either <a href="CommandValues.html">string or numeric IDs</a>. Numeric IDs above 2000 are Scintilla commands and are sent to the focussed pane. Named IDs and numeric IDs below 2000 are SciTE menu commands. The modifiers are Ctrl, Shift, and Alt and the named keys are Left, Right, Up, Down, Insert, End, Home, Enter, Space, Tab, KeypadPlus, KeypadMinus, KeypadMultiply, KeypadDivide, Escape, Delete, PageUp, PageDown, Slash, Question, Equal, Win. <br/> <div class="example"> user.shortcuts=\<br/> Ctrl+Shift+I|IDM_OPEN|\<br/> Ctrl+Shift+Left|IDM_CLOSE|<br/> </div> This property is only read at start up. <br/> </td> </tr> <tr id='property-user.context.menu'> <td> user.context.menu </td> <td> Define additional commands for the context menu. This is a '|' delimited list of menu items and the commands they produce with commands defined as in user.shortcuts. An empty item produces a separator. <br/> <div class="example"> user.context.menu=\<br/> ||\<br/> Next File|IDM_NEXTFILE|\<br/> Prev File|IDM_PREVFILE|<br/> </div> </td> </tr> <tr id='property-magnification'> <td> <a name='property-output.magnification'></a> magnification<br /> output.magnification </td> <td> Sets the initial magnification factor of the edit and output panes. This is useful when you want to change the size of text globally, such as after changing the screen resolution without having to touch every style setting. 0 is default, negative values makes the size smaller and positive values make it larger. </td> </tr> <tr id='property-split.vertical'> <td> <a name='property-output.horizontal.size'></a><a name='property-output.vertical.size'></a><a name='property-output.initial.hide'></a> split.vertical<br /> output.horizontal.size<br /> output.vertical.size<br /> output.initial.hide </td> <td> If split.vertical is set to 1 then the output pane is to the right of the editing pane, if set to 0 then the output pane is below the editing pane. The output.*.size settings determine the initial size of the output pane. If output.initial.hide is 1, then the output pane is hidden when SciTE first starts up even when output.*.size is set; otherwise the output pane is shown at startup. </td> </tr> <tr id='property-clear.before.execute'> <td> clear.before.execute </td> <td> If set to 1 then the output pane is cleared before any tool commands are run. </td> </tr> <tr id='property-horizontal.scrollbar'> <td> <a name='property-horizontal.scroll.width'></a><a name='property-horizontal.scroll.width.tracking'></a><a name='property-output.horizontal.scrollbar'></a><a name='property-output.horizontal.scroll.width'></a><a name='property-output.horizontal.scroll.width.tracking'></a><a name='property-output.scroll'></a><a name='property-end.at.last.line'></a> horizontal.scrollbar<br /> horizontal.scroll.width<br /> horizontal.scroll.width.tracking<br /> output.horizontal.scrollbar<br /> output.horizontal.scroll.width<br /> output.horizontal.scroll.width.tracking<br /> output.scroll<br /> end.at.last.line </td> <td> If horizontal.scrollbar set to 0 then the edit pane's horizontal scrollbar is not displayed.<br /> horizontal.scroll.width is the document width assumed for scrolling.<br /> Similarly, output.horizontal.scrollbar and output.horizontal.scroll.width controls the horizontal scroll bar of the output pane.<br /> The horizontal scroll bar widths can automatically grow as needed to ensure all displayed lines can be fully scrolled with horizontal.scroll.width.tracking and output.horizontal.scroll.width.tracking.<br /> To stop the output pane from automatically scrolling, set output.scroll to 0. To have the output pane scroll and return back to the line of the executed command, set output.scroll to 1. If you want the output pane to scroll and remain at the bottom after execution, set output.scroll to 2.<br /> The vertical scroll range is normally set so that maximum scroll position has the last line at the bottom of the view. Set end.at.last.line to 0 to allow scrolling one page below the last line. </td> </tr> <tr id='property-wrap'> <td> <a name='property-output.wrap'></a> wrap<br /> output.wrap </td> <td> If wrap set to 1 then the edit pane is dynamically line wrapped. If output.wrap set to 1 then the output pane is dynamically line wrapped. These options have a high performance cost which is proportional to the amount of text so should be turned off for large documents on slow machines. </td> </tr> <tr id='property-wrap.style'> <td> wrap.style </td> <td> Chooses between word wrapping (1, the default) and character wrapping (2). Character wrapping is a better choice for Asian languages with no spaces between words. </td> </tr> <tr id='property-wrap.visual.flags'> <td> wrap.visual.flags </td> <td> Flags to display markers at end and begin of wrapped lines for visual identify them. Set to 0 to not display markers (default). Set to 1 to display markers at end of wrapped lines, to 2 to display markers at begin of wrapped lines and to 3 to display markers at begin and end. </td> </tr> <tr id='property-wrap.visual.flags.location'> <td> wrap.visual.flags.location </td> <td> Flags to set the location of the display markers (if enabled) near to text or near to border. Set to 0 to have begin and end markers near to border (default). Set to 1 to have end markers near text, to 2 to have begin markers near text and to 3 to have all markers near text. </td> </tr> <tr id='property-wrap.indent.mode'> <td> wrap.indent.mode </td> <td> Wrapped sublines can be indented in various ways relative to the initial subline. Default mode 0 indents sublines to the left of window plus wrap.visual.startindent. Mode 1 aligns sublines to the first subline. Mode 2 aligns sublines to the first subline plus one more level of indentation. </td> </tr> <tr id='property-wrap.visual.startindent'> <td> wrap.visual.startindent </td> <td> Sets the indention of continued wrapped lines to better visually identify the wrapping. Default is 0 (no indention). Note if wrap.visual.flags is 2 or 3 (begin marker displayed) the line is indented at least 1, even if wrap.visual.startindent is still 0. </td> </tr> <tr id='property-wrap.aware.home.end.keys'> <td>wrap.aware.home.end.keys</td> <td> This property changes the behaviour of the home and end keys when dynamic line wrapping is turned on. When set to 0 (the default), the Home and End keys will move the caret to the very beginning / end of the 'logical' line, whether or not the line is wrapped over multiple lines in the display. When this property is set to 1, the caret moves to the end of the current 'display' line if you press End once, or to the very end of the 'logical' line if you press End again. Likewise, the Home key moves first to the beginning of the 'display' line, then on to the very beginning of the line. In a pane where dynamic line-wrapping is not enabled, this setting has no effect. </td> </tr> <tr id='property-cache.layout'> <td> <a name='property-output.cache.layout'></a> cache.layout<br /> output.cache.layout </td> <td> A large proportion of the time spent in the editor is used to lay out text prior to drawing it. This information often stays static between repaints so can be cached with these settings. There are four levels of caching. 0 is no caching, 1 caches the line that the caret is on, 2 caches the visible page as well as the caret, and 3 caches the whole document. The more that is cached, the greater the amount of memory used, with 3 using large amounts of memory, 7 times the size of the text in the document. However, level 3 dramatically speeds up dynamic wrapping by around 25 times on large source files so is a very good option to use when wrapping is turned on and memory is plentiful. </td> </tr> <tr id='property-open.filter'> <td> open.filter </td> <td> This is a complex expression used for determining the file types that will be available in the open file dialog. For each type of file, there is some explanatory text, a '|' character, some file patterns, and another '|' character. In the distributed SciTEGlobal.properties file, the line continuation character '\', is used to spread these items out, one per line. These file types appear in the "Files of type:" pull down. The first item is the default, so you may wish to change the first item to include the file types you commonly open.<br /> </td> </tr> <tr class="windowsonly" id='property-save.filter'> <td> save.filter </td> <td> This is a complex expression used for determining the file types that will be available in the save file dialog. The structure of the property is the same as open.filter.<br /> Does not work on GTK+. </td> </tr> <tr id='property-max.file.size'> <td> max.file.size </td> <td> To avoid accidentally loading huge files on slow media, or just to ensure SciTE is used only to edit human readable code, the user can set the max.file.size property to specify a limit to file loading. If unset or set to 0, there is no limit. If set to a given size in bytes and if a file to load exceeds this limit, the user is asked if the file should be loaded. If accepted, the file is read as usual. If rejected then no action is taken (no file loaded, no buffer created). </td> </tr> <tr id='property-save.deletes.first'> <td> save.deletes.first </td> <td> Causes files to be deleted before being opened for saving. Can be used to ensure saving under a different capitalisation changes the files capitalisation rather than silently using the old capitalisation. </td> </tr> <tr id='property-save.check.modified.time'> <td> save.check.modified.time </td> <td> With save.check.modified.time=1, when saving and the file has been modified by another process, check if it should be overwritten by the current contents. </td> </tr> <tr id='property-save.session'> <td> <a name='property-save.recent'></a><a name='property-save.position'></a> save.session<br /> save.recent<br /> save.position<br /> save.find </td> <td> If you set save.session, the list of currently opened buffers will be saved on exit in a session file. When you start SciTE next time (without specifying a file name on the command line) the last session will be restored automatically.<br /> For GTK+, the file is called ".SciTE.session" and is located in the directory given by the SciTE_HOME environment variable and if that is not set, the value of the HOME environment variable and if that is not set, the top level directory. For Windows, the file is called "SciTE.session" and is located in the directory given by the SciTE_HOME environment variable and if that is not set, the value of the USERPROFILE environment variable and if that is not set, the directory of the SciTE executable.<br /> Setting save.recent causes the most recently used files list to be saved on exit in the session file and read at start up.<br /> Setting save.position causes the SciTE window position on the desktop to be saved on exit in the session file and restored at start up.<br /> Setting save.find cause the "Find what" and "Replace with" to be saved in the session file. </td> </tr> <tr id='property-session.bookmarks'> <td> <a name='property-session.folds'></a> session.bookmarks<br /> session.folds </td> <td> Setting session.bookmarks causes bookmarks to be saved in session files. If you set session.folds then the folding state will be saved in session files. When loading a session file bookmarks and/or folds are restored. Folding states are not restored if fold.on.open is set. </td> </tr> <tr class="windowsonly" id='property-open.dialog.in.file.directory'> <td> open.dialog.in.file.directory </td> <td> Setting open.dialog.in.file.directory causes the open dialog to initially display the same directory as the current file. If it is not set then the system default is used. </td> </tr> <tr class="windowsonly" id='property-find.close.on.find'> <td> find.close.on.find </td> <td> Set to 0 to prevent the Find dialog from closing when "Find" pressed. </td> </tr> <tr id='property-find.replace.matchcase'> <td> <a name='property-find.replace.regexp'></a><a name='property-find.replace.wrap'></a><a name='property-find.replace.escapes'></a> find.replace.matchcase<br /> find.replace.regexp<br /> find.replace.wrap<br /> find.replace.escapes </td> <td> These properties define the initial conditions for find and replace commands. The find.replace.matchcase property turns of the "Match case" option, find.replace.regexp the "Regular expression" option, find.replace.wrap the "Wrap around" option and find.replace.escapes the "Transform backslash expressions" option.<br /> </td> </tr> <tr class="windowsonly" id='property-find.replacewith.focus'> <td> find.replacewith.focus </td> <td> If the find.replacewith.focus property is set, the Replace With input box is focused in the Replace dialog if Find What is non-empty. </td> </tr> <tr id='property-find.replace.regexp.posix'> <td> find.replace.regexp.posix </td> <td> Change behaviour of Regular expression search. If set to 0 (the default), characters '(' and ')' must be escaped by '\' to behave as regexp meta characters. If set to 1, these characters are meta characters itself. </td> </tr> <tr id='property-find.use.strip'> <td> <a name='property-replace.use.strip'></a> find.use.strip<br /> replace.use.strip </td> <td> Use in-window strips rather than dialogs for performing Find or Replace commands. </td> </tr> <tr class="gtkonly" id='property-strip.button.height'> <td> strip.button.height </td> <td> Buttons on GTK+ often contain extra spacing that makes strips take too much room. This setting tries to limit the height of buttons. A value of 23 or 24 may work well. </td> </tr> <tr id='property-find.replace.advanced'> <td> find.replace.advanced </td> <td> Enables Replace in Buffers command <span class="windowsonly">and Search only in this style checkbox. If enabled, searches can be restricted to a particular style (e.g. strings).</span> </td> </tr> <tr class="osxonly" id='property-find.indicator'> <td> find.indicator </td> <td> Controls the animated golden match indicator on OS X. The default value, 1, shows and animates the find indicator then fades it away so surrounding text can be seen clearly. Use the value 0 to disable the find indicator and the value 2 to keep the find indicator displayed. </td> </tr> <tr id='property-find.command'> <td> find.command<br /> <span class="windowsonly">find.input</span> </td> <td> The Find in Files command works in a similar way to the building commands executing a command line tool with output redirected to the output pane. If the command produces output understood by one of the error output passes, as does grep, then the F4 and Shift+F4 keys can be used to move through all the matches. The $(find.what), $(find.files), and $(find.directory) variables can be used for the values from the Find in Files dialog.<br /> There are some scripts that implement this feature in Perl better than grep does itself <a href="http://jenda.krynicky.cz/#SciteFind">here</a> and <a href="http://www.forusers.com/forme/finder.zip">here</a>. This command line works with Cygwin on Windows, with modifications to suit the Cygwin installation directory:<br /> <div class="example"> find.command=cmd /c c:\cygwin\bin\find "$(find.directory)" -name "$(find.files)" -print0 | c:\cygwin\bin\xargs -0 fgrep -G -n "$(find.what)" </div> On Windows, the find string can be given to the find command through its standard input stream to avoid problems with quote interpretation. To do this, specify find.input to be the search string, $(find.what). <br /> If find.command is empty then SciTE's own search code is used. This only does a simple search without regular expressions and is faster than running an external program. </td> </tr> <tr id='property-find.files'> <td> find.files </td> <td> This is the default set of files to search through using the Find in Files command. The find.files property can contain a list of sets of files separated by '|' like "*.cxx *.h|*.py *.pyw|*.html" which adds three entries to the history and uses the first as the default value.<br /> The evaluation of this setting is a little unusual in that each entry in the value from the property files is appended to the end of the history if that entry is not already present. This means that opening files from different directories will result in any local setting of find.files being added to the list. </td> </tr> <tr id='property-find.in.dot'> <td> find.in.dot </td> <td> If find.in.dot is 1 then Find in Files searches in directories that start with '.'. The default behaviour is to prevent SciTE finding matches in the unmodified versions of files kept by Subversion in .svn subdirectories. </td> </tr> <tr id='property-find.in.binary'> <td> find.in.binary </td> <td> If find.in.binary is 1 then Find in Files displays matches in binary files. For Find in Files, a binary file is a file that contains a NUL byte in the first 64K block read from the file. </td> </tr> <tr id='property-find.in.directory'> <td> find.in.directory </td> <td> If set then Find in Files directory will be prefilled by this value. If not set then Find in Files directory will be prefilled by directory of current file. </td> </tr> <tr class="windowsonly" id='property-find.in.files.close.on.find'> <td> find.in.files.close.on.find </td> <td> Set to 0 to prevent the Find in Files dialog from closing when "Find" pressed. </td> </tr> <tr id='property-code.page'> <td> <a name='property-output.code.page'></a> code.page<br /> output.code.page </td> <td> To support a DBCS language such as Japanese, a code page can be set here. This ensures that double byte characters are always treated as a unit so the caret is never located between the two bytes of a double byte character.<br/><br/> <table> <thead><tr><th>Code page</th><th>Value</th></tr></thead> <tr><td>Default (single byte character set)</td><td align="right">0</td></tr> <tr><td>UTF-8</td><td align="right">65001</td></tr> <tr><td>Japanese Shift-JIS</td><td align="right">932</td></tr> <tr><td>Simplified Chinese GBK</td><td align="right">936</td></tr> <tr><td>Korean Wansung</td><td align="right">949</td></tr> <tr><td>Traditional Chinese Big5</td><td align="right">950</td></tr> <tr><td>Korean Johab</td><td align="right">1361</td></tr> </table> Setting code.page to 65001 starts Unicode mode and the document is treated as a sequence of characters expressed as UTF-8. Display is performed by converting to the platform's normal Unicode encoding first so characters from any language will be displayed. Correct glyphs may only be displayed if fonts are chosen that contain the appropriate glyphs. The Tahoma font contains a wide range of glyphs so may be a good choice. <br/> This property can <em>not</em> set a single byte character set.<br /> If output.code.page is set then it is used for the output pane which otherwise matches the edit pane. </td> </tr> <tr id='property-character.set'> <td> character.set </td> <td> This setting allows changing the character set that is asked for when setting up fonts. Not all of the values will work on all platforms.<br/><br/> <table> <thead><tr><th>Character set</th><th>Value</th></tr></thead> <tr><td>Default</td><td align="right">0</td></tr> <tr><td>Japanese</td><td align="right">128</td></tr> <tr><td>Chinese GB2312</td><td align="right">134</td></tr> <tr><td>Chinese BIG5</td><td align="right">136</td></tr> <tr><td>Korean</td><td align="right">129</td></tr> <tr><td>Greek</td><td align="right">161</td></tr> <tr><td>Eastern European</td><td align="right">238</td></tr> <tr class="windowsonly"><td>Baltic</td><td align="right">186</td></tr> <tr class="windowsonly"><td>Turkish</td><td align="right">162</td></tr> <tr><td>Hebrew</td><td align="right">177</td></tr> <tr><td>Arabic</td><td align="right">178</td></tr> <tr class="windowsonly"><td>Thai</td><td align="right">222</td></tr> <tr class="windowsonly"><td>Vietnamese</td><td align="right">163</td></tr> <tr><td>Cyrillic (CP1251 on Windows, KOI8-R on GTK+)</td><td align="right">204</td></tr> <tr class="gtkonly"><td>Cyrillic (CP1251 on GTK+)</td><td align="right">1251</td></tr> <tr class="gtkonly"><td>European with Euro (ISO 8859-15)</td><td align="right">1000</td></tr> </table> All of these values except for 1251 and 1000 should work on OS X or Windows. On GTK+ Baltic, Turkish, Thai and Vietnamese will probably not work. </td> </tr> <tr id='property-imports.include'> <td> <a name='property-imports.exclude'></a> imports.include<br /> imports.exclude </td> <td> These settings control which files are imported by import statements.<br/> The imports.include property defines the names of the properties files that may be imported. Say you are only interested in using fortran and lisp, then in user properties, you could set<br /> <div class="example"> imports.include=fortran lisp </div> The imports.exclude property is examined only if imports.include is empty or missing. This property stops the named files from being imported. </td> </tr> <tr id='property-command.discover.properties'> <td> command.discover.properties </td> <td> This property can be used to run a program to determine file encoding and other properties when a file is loaded.<br /> The program should print a list of property=value lines for each property it wants to set. This is the same format as properties files.<br /> <div class="example"> command.discover.properties=python /home/user/FileDetect.py "$(FilePath)" </div> A simple Python script that recognises a particular tag that indicates the file is in the Korean code page 949:<br /> <div class="example"> <span><span class="S5">import</span><span class="S0"> </span>sys<br /> <span class="S5">if</span><span class="S0"> </span><span class="S3">"Language:Korean"</span><span class="S0"> </span><span class="S5">in</span><span class="S0"> </span>open<span class="S10">(</span>sys<span class="S10">.</span>argv<span class="S10">[</span><span class="S2">1</span><span class="S10">]).</span>read<span class="S10">():</span><br /> <span class="S0"> </span><span class="S5">print</span><span class="S10">(</span><span class="S4">'code.page=949'</span><span class="S10">)</span><br /> <span class="S0"> </span><span class="S5">print</span><span class="S10">(</span><span class="S4">'character.set=129'</span><span class="S10">)</span><br /> <span class="S0"></span></span> </div> </td> </tr> <tr id='property-comment.block'> <td> <a name='property-comment.block.at.line.start'></a><a name='property-comment.stream.start'></a><a name='property-comment.stream.end'></a><a name='property-comment.box.start'></a><a name='property-comment.box.middle'></a><a name='property-comment.box.end'></a> comment.block.<i>lexer</i><br /> comment.block.at.line.start.<i>lexer</i><br /> comment.stream.start.<i>lexer</i><br /> comment.stream.end.<i>lexer</i><br /> comment.box.start.<i>lexer</i><br /> comment.box.middle.<i>lexer</i><br /> comment.box.end.<i>lexer</i> </td> <td> These settings are for the comment commands in the Edit menu and are defined separately for each lexer. Not all languages support both stream and block comments.<br /> Block comments are comments that start with a particular string and continue until the end of line. The comment.block property sets the string to be inserted or deleted at the start of the selected lines when the Block Comment or Uncomment command is performed. To make this command perform sensibly over a range of text that already contains comments and other code, the string can be defined to contain a character such as '~' that is not used in real comments.<br /> Set comment.block.at.line.start to "1" to place block comment symbols at the start of the lines, instead of just before the first non-blank character of the lines.<br /> Stream comments start with a particular string and end with another particular string and may continue over line ends. These are defined with comment.stream.start and comment.stream.end. <br /> Box comments are a form of stream comment that takes several lines and uses different strings for the start, end and other lines in the range. These are defined with comment.box.start, comment.box.middle and comment.box.end. </td> </tr> <tr id='property-preprocessor.symbol'> <td> <a name='property-preprocessor.start'></a><a name='property-preprocessor.middle'></a><a name='property-preprocessor.end'></a> preprocessor.symbol.<i>filepattern</i><br /> preprocessor.start.<i>filepattern</i><br /> preprocessor.middle.<i>filepattern</i><br /> preprocessor.end.<i>filepattern</i> </td> <td> These settings make the preprocessor conditional movement and selection commands work. The character that defines preprocessor lines is defined by preprocessor.symbol. The preprocessor keywords that make up the start (if), middle (else), and end (endif) of preprocessor conditionals are defined by the other three properties. There may be multiple values for each of these, as, for example, C uses "if", "ifdef", and "ifndef" to begin preprocessor conditionals. </td> </tr> <tr id='property-lexer'> <td> lexer.<i>filepattern</i> </td> <td> A lexer splits a file up into syntactic pieces. SciTE can then display these pieces in different visual styles. Many lexers are included in SciTE for popular programming languages such as Python, Java, C/C++, JavaScript and VB. Often several file extensions (.cpp, .cc, .h) can map to one language (C++) and hence one lexer. These settings associate a file name with a lexer.<br /> The lexers included in SciTE are written in C++ and compiled into the SciTE executable. Lexers can also be written as a <a href="ScriptLexer.html">Lua script</a> or as a Lua LPeg lexer using <a href="http://code.google.com/p/scintillua/">scintillua</a>. </td> </tr> <tr id='property-shbang'> <td> shbang.<i>command</i> </td> <td> On Unix, command files often have no extension and instead specify the interpreter to use for the file in an initial line that starts with "#!". When the lexer can not be otherwise determined and the file starts with "#!", the initial line is split up into words and each word is prepended with "shbang.". If a property with this name exists then it is treated as the extension of the file. For example, <span class="example">shbang.python=py</span> will be triggered by an initial line <span class="example">#!/usr/bin/env python</span> so the file will be treated as Python. </td> </tr> <tr id='property-lexerpath'> <td> lexerpath.<i>filepattern</i> </td> <td> Specifies the path to an external lexer module that will be loaded into Scintilla. </td> </tr> <tr id='property-keywords'> <td> <a name='property-keywords2'></a><a name='property-keywords3'></a><a name='property-keywords4'></a><a name='property-keywords5'></a><a name='property-keywords6'></a><a name='property-keywords7'></a><a name='property-keywords8'></a><a name='property-keywords9'></a><a name='property-keywordclass'></a> keywords.<i>filepattern</i><br /> keywords2.<i>filepattern</i><br /> keywords3.<i>filepattern</i><br /> keywords4.<i>filepattern</i><br /> keywords5.<i>filepattern</i><br /> keywords6.<i>filepattern</i><br /> keywords7.<i>filepattern</i><br /> keywords8.<i>filepattern</i><br /> keywords9.<i>filepattern</i><br /> keywordclass.<i>lexer</i> </td> <td> Most of the lexers differentiate between names and keywords and use the keywords variables to do so. To avoid repeating the keyword list for each file extension, where several file extensions are used for one language, a keywordclass variable is defined in the distributed properties file although this is just a convention. Some lexers define a second set of keywords which will be displayed in a different style to the first set of keywords. This is used in the HTML lexer to display JavaScript keywords in a different style to HTML tags and attributes.<br /> Keywords can be prefix based so ^GTK_ will treat all words that start with GTK_ as keywords. </td> </tr> <tr id='property-default.file.ext'> <td> default.file.ext </td> <td> Defines the language mode used before the file has a name. For example, if default.file.ext=.py, then when the New command is used to create a new file then Python syntax styling is used. </td> </tr> <tr id='property-word.characters'> <td> word.characters.<i>filepattern</i> </td> <td> Defines which characters can be parts of words. The default value here is all the alphabetic and numeric characters and the underscore which is a reasonable value for languages such as C++. </td> </tr> <tr id='property-whitespace.characters'> <td> whitespace.characters.<i>filepattern</i> </td> <td> Defines which characters are considered whitespace. The default value is that initially set up by Scintilla, which is space and all chars less than 0x20. Setting this property allows you to force Scintilla to consider other characters as whitespace (e.g. punctuation) during such activities as cursor navigation (ctrl+left/right). </td> </tr> <tr id='property-style.*'> <td> style.*.<i>stylenumber</i><br /> style.<i>lexer</i>.<i>stylenumber</i> </td> <td> The lexers determine a style number for each lexical type, such as keyword, comment or number. These settings determine the visual style to be used for each style number of each lexer.<br /> The value of each setting is a set of ',' separated fields, some of which have a subvalue after a ':'. The fields are font, size, fore, back, italics, notitalics, bold, notbold, weight, eolfilled, noteolfilled, underlined, notunderlined, and case. The font field has a subvalue which is the name of the font, the fore and back have colour subvalues, the size field has a (fractional) numeric size subvalue, the weight field has a numeric size subvalue (1.. 999: 100=light, 400=normal, 700=bold), the case field has a subvalue of 'm', 'u', or 'l' for mixed, upper or lower case, and the bold, italics and eolfilled fields have no subvalue. The value "fore:#FF0000,font:Courier,size:14" represents 14 point, red Courier text.<br /> A global style can be set up using style.*.<i>stylenumber</i>. Any style options set in the global style will be inherited by each lexer style unless overridden.<br /> On GTK+, the font name should be prefixed with "!" such as "font:!Sans" to ensure Pango anti-aliased fonts are used. If this is not done, an older font system will be used which may not work well. </td> </tr> <tr> <td> style.<i>lexer</i>.32<br /> style.<i>lexer</i>.33<br /> style.<i>lexer</i>.34<br /> style.<i>lexer</i>.35<br /> style.<i>lexer</i>.36<br /> style.<i>lexer</i>.37<br /> style.<i>lexer</i>.38 </td> <td> As well as the styles generated by the lexer, there are other numbered styles used.<br /> Style 32 is the default style and its features will be inherited by all other styles unless overridden.<br /> Style 33 is used to display line numbers in the margin.<br /> Styles 34 and 35 are used to display matching and non-matching braces respectively.<br /> Style 36 is used for displaying control characters. This is not a full style as the foreground and background colours for control characters are determined by their lexical state rather than this style.<br /> Style 37 is used for displaying indentation guides. Only the fore and back are used.<br /> Style 38 is used for displaying calltips. Only the font, size, fore and back are used.<br /> A * can be used instead of a lexer to indicate a global style setting. </td> </tr> <tr id='property-braces.check'> <td> <a name='property-braces.sloppy'></a> braces.check<br /> braces.sloppy<br /> style.<i>lexer</i>.34<br /> style.<i>lexer</i>.35<br /> braces.<i>lexer</i>.style </td> <td> Brace highlighting is a feature that shows the range of a brace when the caret is positioned immediately after it. It is especially useful when complex nested braces are used. The characters '(', ')', '[', ']', '{', and '}' are considered braces. The feature defaults to off (because it slows cursor movement) unless braces.check is set to 1. If braces.sloppy is set to 1 then if there is no brace before the caret then the character after the caret is checked. The highlighting is performed by displaying the braces in style number 34 or in style number 35 if there is no matching brace. While this is a full style, to avoid partial display of the braces, it is best to make this style differ from the standard style of braces only in foreground and background colour. Only braces with style set to braces.<i>lexer</i>.style (which defaults to 0) are candidates for brace match highlighting. </td> </tr> <tr id='property-font.monospace'> <td> font.monospace </td> <td> Defines, with the same syntax as the style properties, the font name and size to be used when the Use Monospaced Font command is performed. </td> </tr> <tr id='property-command.compile'> <td> <a name='property-command.compile.subsystem'></a><a name='property-command.build'></a><a name='property-command.build.subsystem'></a><a name='property-command.build.directory'></a><a name='property-command.go'></a><a name='property-command.go.subsystem'></a> command.compile.<i>filepattern</i><br /> command.compile.subsystem.<i>filepattern</i><br /> command.build.<i>filepattern</i><br /> command.build.subsystem.<i>filepattern</i><br /> command.build.directory.<i>filepattern</i><br /> command.go.<i>filepattern</i><br /> command.go.subsystem.<i>filepattern</i> </td> <td> These settings choose which commands to execute when the Compile, Build or Go menu items are selected. The subsystem options are explained in the subsystem section.<br /> When source files are in a different directory to that they should be built in, the command.build.directory property can be set to change to a particular directory before performing the build. </td> </tr> <tr id='property-command.go.needs'> <td> <a name='property-command.go.needs.subsystem'></a> command.go.needs.<i>filepattern</i><br /> command.go.needs.subsystem.<i>filepattern</i> </td> <td> Sometimes a file must be compiled or built before it can be run. If this is the case, this setting indicates what command needs to be run to perform the compile or build step before running the file. When a file is compiled, this is noted and future runs will not perform a compile or build. To make a 'compile and go' Go command for .c files: <div class="example"> command.go.*.c=$(FileName)<br /> command.go.needs.*.c=g++ $(FileNameExt) -o $(FileName)<br /> </div> </td> </tr> <tr> <td> command.name.<i>number</i>.<i>filepattern</i><br /> command.<i>number</i>.<i>filepattern</i><br /> command.is.filter.<i>number</i>.<i>filepattern</i><br /> command.subsystem.<i>number</i>.<i>filepattern</i><br /> command.save.before.<i>number</i>.<i>filepattern</i><br /> <span class="windowsonly">command.input.<i>number</i>.<i>filepattern</i></span><br /> command.replace.selection.<i>number</i>.<i>filepattern</i><br /> <span class="windowsonly">command.quiet.<i>number</i>.<i>filepattern</i></span><br /> command.mode.<i>number</i>.<i>filepattern</i><br /> command.shortcut.<i>number</i>.<i>filepattern</i> </td> <td> Extra commands can be added to the Tools menu. For example to include the 'astyle' indenter, the properties file could contain <div class="example">command.name.0.*.cc=Indent<br /> command.0.*.cc=astyle -taO $(FileNameExt)<br /> command.is.filter.0.*.cc=1</div> The first line defines the string that will appear in the Tools menu (immediately below 'Go'). The second line is the command string, similar to those of the compile, build, and go commands. The optional command.is.filter property states that the command modifies the current file so it may need to be read in after performing the command if load.on.activate is set.<br /> If command.save.before is set to 1, SciTE automatically saves the file before execution. If it is set to 2, SciTE will not save the file, otherwise SciTE asks you. On Windows, the optional command.input property specifies text that will be piped to the command. This may reference other properties; for example, <span class="example">command.input.0.*.cc=$(CurrentSelection)</span> would pipe the current selection to the command processes. The command.input property is only supported for subsystem 0 (command line programs).<br /> <br /> The optional command.replace.selection can be used to specify that the command output should replace the current selection (or be inserted at the cursor location, if there is no selection). This property has three available settings: 0, the default, means do not replace the selection. 1 means replace the selection when the command finishes. 2 means replace the selection only if the command finishes with an exit code of 0. If the user cancels the command via "Tools / Stop Executing", the selection will not be replaced even in mode 1. Note, commands run asynchronously, so you are not prevented from modifying the document or even switching buffers while a command is running. However, please bear in mind that command.replace.selection will send the output to whatever window is active <i>when the command completes</i>.<br /> A final command property that is currently supported only on windows is command.quiet. A value of 1 indicates that the command I/O should not be echoed to the output pane. This may be useful in combination with command.input and command.replace.selection.<br /> <br /> The command.mode property is a comma-separated list of flags / settings. Each mode setting can have an argument, separated from the setting name by a colon. For most of these, the argument portion is optional; if the setting name appears without an argument, this works the same as "setting:yes". If a setting is included in the command.mode but also appears as a separate command property, the mode property will be overridden. Similarly, if a single setting appears more than once with different arguments, the last valid argument takes priority. The supported command.mode settings are: <div class="example"> filter - accepts keyword arguments yes and no<br /> quiet - accepts keyword arguments yes and no<br /> replaceselection - accepts yes, no, and auto<br /> savebefore - accepts yes, no, and prompt<br /> subsystem - console, windows, shellexec, lua, director, winhelp, htmlhelp<br /> groupundo - yes or no </div> Currently, all of these except groupundo are based on individual properties with similar names, and so are not described separately here. The groupundo setting works with subsystem 3 (lua / director), and indicates that SciTE should treat any changes made by the command as a single undo action. A command that uses the groupundo setting should not change which buffer is active in the editor.<br /> The command.shortcut property allows you to specify a keyboard shortcut for the command. By default, commands 0 to 9 have keyboard shortcuts Ctrl+0 to Ctrl+9 respectively, but this can be overridden. For commands numbered higher than 9, there is no default keyboard shortcut. The notation used to specify keyboard shortcuts is the same as for the user.shortcuts property, described elsewhere in this document.<br /> <br /> If the text of a command starts with '*' then the Parameters dialog is displayed to prompt for parameters before executing the command. The initial '*' is not included in the command that is executed.<br /> <br /> The command number can be in the range of 0 to 49. Command numbers 0 to 9 are assigned Ctrl+Number shortcuts. Internally these commands use IDs starting from 1100 (IDM_TOOLS) which can be used in user.shortcuts and user.context.menu as: <div class="example">user.context.menu=Indent|1100|</div> If command.name is empty then no item is added to the Tools menu. This can be used for commands that are only in the context menu or user shortcuts. </td> </tr> <tr id='property-command.help'> <td> <a name='property-command.help.subsystem'></a> command.help.<i>filepattern</i><br /> command.help.subsystem.<i>filepattern</i> </td> <td> Defines a command to be executed when the help command is invoked or F1 pressed. On Windows, this often uses subsystem 4 as described above. On OS X or Linux, running man or a browser are common ways of displaying help. The word at the cursor is copied to $(CurrentWord) and this is often a good argument to the help application. The subsystem property works in the same way as for other commands. </td> </tr> <tr id='property-command.scite.help'> <td> <a name='property-command.scite.help.subsystem'></a> command.scite.help<br /> command.scite.help.subsystem </td> <td> Defines a command to be executed for help on the SciTE program itself which normally means displaying this file in a browser. </td> </tr> <tr class="gtkonly" id='property-command.print'> <td> <a name='property-command.print.subsystem'></a> command.print.<i>filepattern</i><br /> command.print.subsystem.<i>filepattern</i> </td> <td> Defines a command to be executed when print is invoked on GTK+ 2.x. On Windows and GTK+ 3.x, printing is performed directly by SciTE. </td> </tr> <tr id='property-time.commands'> <td> time.commands </td> <td> When a command is completed, print the time it took in seconds. </td> </tr> <tr id='property-print.magnification'> <td> print.magnification </td> <td> Printing is normally done with the same settings as screen display. To make the printing larger or smaller, the print.magnification setting is added to the size of every font when printed. To get a good miniaturisation of text, set print.magnification to -4. </td> </tr> <tr id='property-print.colour.mode'> <td> print.colour.mode </td> <td> Some people prefer light coloured text on a black background on screen but dark text on white on paper. If print.colour.mode is set to 1 then each colour is inverted for printing. If set to 2 then printing produces black text on white background. 3 forces the background to white and 4 forces the default background to white. </td> </tr> <tr class="windowsonly" id='property-print.margins'> <td> print.margins </td> <td> Specify the default margins on the printer on Windows in left right top bottom order. Units depends on your locale, either hundredths of millimetres or thousandths of inches. You can see which units by the units used in the page setup dialog. This property is only read at start up. </td> </tr> <tr id='property-print.header.format'> <td> <a name='property-print.footer.format'></a> print.header.format<br /> print.footer.format </td> <td> These settings determine what will be printed if anything as headers and footers. Property settings can be substituted into the values using the $(property) syntax. There are some extra properties set up while printing: CurrentPage, FileTime, FileDate, CurrentDate, and CurrentTime (at start of printing). Common properties to use in headers and footers are FileNameExt and FilePath.<br /> A header setting may look like:<br /> <div class="example"> print.header.format=$(FileNameExt) - Printed on $(CurrentDate),$(CurrentTime) - Page $(CurrentPage) </div> </td> </tr> <tr id='property-print.header.style'> <td> <a name='property-print.footer.style'></a> print.header.style<br /> print.footer.style </td> <td> These settings determine the style of the header and footer using the same format as other styles in SciTE. Only the fore, back, font, size, bold, italics, and underlined attributes are supported. </td> </tr> <tr id='property-export.keep.ext'> <td> export.keep.ext </td> <td> This property determines how the file name (for example, LineMarker.cxx) is transformed when exporting to include the appropriate export format extension - .html for HTML and .rtf for RTF. If export.keep.ext is the default, 0, then the current extension is replaced (LineMarker.html). If it is 1, then the export format extension is added (LineMarker.cxx.html). If it is 2 then the final '.' is replaced by '_' and the export format extension added (LineMarker_cxx.html). </td> </tr> <tr id='property-export.html.wysiwyg'> <td> <a name='property-export.html.tabs'></a><a name='property-export.html.folding'></a><a name='property-export.html.styleused'></a><a name='property-export.html.title.fullpath'></a> export.html.wysiwyg<br /> export.html.tabs<br /> export.html.folding<br /> export.html.styleused<br /> export.html.title.fullpath </td> <td> When export.html.wysiwyg is set to 0 then exporting to a HTML file produces a smaller file but which is less completely specified so may look more different to the on screen display. When export.html.tabs is set to 1 and export.html.wysiwyg is set to 0 then tab characters in the file are exported as tab characters rather than a sequence of space characters.<br /> The exported file can be made to fold in browsers that support CSS well (Mozilla and Internet Explorer) by setting export.html.folding to 1. Only export styles actually used when export.html.styleused set to 1. The full path name of the file is put in the title, instead of just the file name when export.html.title.fullpath set to 1. </td> </tr> <tr id='property-export.rtf.wysiwyg'> <td> <a name='property-export.rtf.tabs'></a><a name='property-export.rtf.font.face'></a><a name='property-export.rtf.font.size'></a><a name='property-export.rtf.tabsize'></a> export.rtf.wysiwyg<br /> export.rtf.tabs<br /> export.rtf.font.face<br /> export.rtf.font.size<br /> export.rtf.tabsize </td> <td> When export.rtf.wysiwyg is set to 0 then exporting to a RTF file produces a smaller file but which is less completely specified so may look more different to the on screen display. When export.rtf.tabs is set to 1 and export.rtf.wysiwyg is set to 0 then tab characters in the file are exported as tab characters rather than a sequence of space characters. <br /> export.rtf.font.face and export.rtf.font.size can be used to select a particular font and size for the exported RTF file. export.rtf.tabsize can be set to use a different tab size than that defined by the tabsize setting. </td> </tr> <tr id='property-export.pdf.magnification'> <td> <a name='property-export.pdf.font'></a><a name='property-export.pdf.pagesize'></a><a name='property-export.pdf.margins'></a> export.pdf.magnification<br /> export.pdf.font<br /> export.pdf.pagesize<br /> export.pdf.margins </td> <td> export.pdf.magnification is a value that is added to the font size of the default screen style in use. A positive value increases the PDF document's font size, and vice versa.<br /> export.pdf.font accepts a one-word parameter that selects one of the default PDF fonts: Courier, Helvetica or Times. Helvetica is the default. Helvetica and Times do not line wrap, Courier line wraps.<br /> export.pdf.pagesize is used to set the document's page size, using points (1/72th of an inch) as the unit. E.g. Letter paper (8.5 inch x 11 inch) is specified using the values 612,792.<br /> export.pdf.margins sets the widths of the page margins. Margins defaults to 72 points, or 1 inch.<br /> The PDF exporter is necessarily feature-limited because PDF is a document archival format. Supporting a full set of features will bloat SciTE. Wrapping Helvetica or Times adequately isn't possible without the complexities of font metrics and kerning. The PDF produced uses WinAnsiEncoding, so pre-encoding has to be done before exporting to PDF, if you want to use extended characters. </td> </tr> <tr id='property-export.tex.title.fullpath'> <td> export.tex.title.fullpath </td> <td> The full path name of the file is put in the title, instead of just the file name when export.tex.title.fullpath set to 1. </td> </tr> <tr id='property-export.xml.collapse.spaces'> <td> <a name='property-export.xml.collapse.lines'></a> export.xml.collapse.spaces<br /> export.xml.collapse.lines </td> <td> export.xml.collapse.spaces and export.xml.collapse.lines are flags that control how empty lines and runs of space characters are converted into XML. The flags are enabled if set to 1. Tab characters are always converted by the XML exporter into spaces according to the tabsize property. </td> </tr> <tr id='property-fold'> <td>fold</td> <td>Folding is turned on by setting fold=1.</td> </tr> <tr id='property-fold.symbols'> <td> fold.symbols </td> <td> The fold.symbols setting chooses between four ways of showing folding. Set to 0 (the default) for MacOS style arrows to indicate contracted (facing right) and expanded (facing down); 1 to display contracted folds with "+" and expanded with "-"; 2 for a flattened tree control with round headers and rounded joins; 3 for a flattened tree control with square headers. </td> </tr> <tr id='property-fold.margin.width'> <td> fold.margin.width </td> <td> Sets the width of the fold margin. </td> </tr> <tr id='property-fold.margin.colour'> <td> <a name='property-fold.margin.highlight.colour'></a> fold.margin.colour<br /> fold.margin.highlight.colour </td> <td> These two properties defined the fold margin colour and fold margin highlight colour. If they are not defined (left commented out) the colours for the fold margin will default to a reasonable pair of colours. On Windows, the system colours are used to make the fold margin appear like the background of scroll bars. As an example, with <span class="example">fold.margin.colour=#FF0000</span> and <span class="example">fold.margin.highlight.colour=#0000FF</span>, the fold margin is a mixture of red and blue. </td> </tr> <tr id='property-fold.on.open'> <td> fold.on.open </td> <td> To automatically fold files as much as possible when loaded, set fold.on.open to 1. </td> </tr> <tr id='property-fold.flags'> <td> fold.flags </td> <td> Not really documented ;) bit flags which may go away. 2, 4, 8, and 16 control drawing lines above and below folding lines if expanded or not expanded. Set to 64 to help debug folding by showing hexadecimal fold levels in margin. </td> </tr> <tr id='property-fold.compact'> <td> fold.compact<br /> </td> <td> For HTML, XML, Lua and C++ and similar files, turning this option on leads to blank lines following the end of an element folding with that element. Defaults to on. </td> </tr> <tr id='property-fold.highlight'> <td> fold.highlight<br /> </td> <td> Set to 1 to enable highlight for current folding block (smallest one that contains the caret). By default, it's disable. Note : The highlight is enabled only when fold.symbols equals to 2 (round headers) or 3 (square headers). </td> </tr> <tr id='property-fold.highlight.colour'> <td> fold.highlight.colour<br /> </td> <td> Define the colour of highlight. The colour by default is red (#FF0000). </td> </tr> <tr id='property-title.full.path'> <td> title.full.path </td> <td> Chooses how the file name is displayed in the title bar. When 0 (default) the file name is displayed. When 1 the full path is displayed. When 2 the window title displays "filename in directory". </td> </tr> <tr id='property-title.show.buffers'> <td> title.show.buffers </td> <td> When set to 1 shows the current buffer number in the title bar. </td> </tr> <tr id='property-tabsize'> <td> <a name='property-tab.size'></a><a name='property-indent.size'></a><a name='property-use.tabs'></a><a name='property-indent.auto'></a><a name='property-tab.indents'></a><a name='property-backspace.unindents'></a> tabsize<br /> tab.size.<i>filepattern</i><br /> indent.size<br /> indent.size.<i>filepattern</i><br /> use.tabs<br /> use.tabs.<i>filepattern</i><br /> indent.auto<br /> tab.indents<br /> backspace.unindents </td> <td> Sets the size of a tab as a multiple of the size of a space character in the style of the default style definition. The indent size is the size to use when performing automatic indentation and may be different from the tab size. Many people use a tab size of 8 but 4 character indentation. When creating indentation, use.tabs determines whether the indentation is made up purely from space characters or from a mix of tabs and spaces using as many tabs as possible. <br /> The global tabsize, indent.size, and use.tabs properties can be overridden for files that match a pattern by using the file pattern forms: <br /> <div class="example"> indent.size.*.pas=3</div> If indent.auto is set then indent.size and use.tabs are set according to the contents of the opened document.<br /> The properties file settings apply to newly opened files but remain constant once the file is open unless changed using the Change Indentation Settings dialog.<br /> If tab.indents is set then pressing tab within indentation whitespace indents by indent.size rather than inserting a tab character. If backspace.unindents then pressing backspace within indentation whitespace unindents by indent.size rather than deleting the character before the caret. </td> </tr> <tr id='property-indent.automatic'> <td> <a name='property-indent.opening'></a><a name='property-indent.closing'></a><a name='property-indent.maintain'></a> indent.automatic<br /> indent.opening<br /> indent.closing<br /> indent.maintain.<i>filepattern</i> </td> <td> Determines the look of automatic indentation. Automatic indentation is turned on with indent.automatic=1. To indent a brace line after a compound statement start set indent.opening=1, likewise for the terminating brace. So with both set to 0: <div class="example"> if (c)<br /> {<br /> s;<br /> }<br /> </div> And with both set to 1: <div class="example"> if (c)<br /> {<br /> s;<br /> }<br /> </div> Automatic indentation may be changed to simply repeat the indentation of the previous line for some files with indent.maintain.<i>filepattern</i>=1 which overrides the other language specific settings. </td> </tr> <tr id='property-statement.indent'> <td> <a name='property-statement.end'></a><a name='property-statement.lookback'></a><a name='property-block.start'></a><a name='property-block.end'></a> statement.indent.<i>filepattern</i><br /> statement.end.<i>filepattern</i><br /> statement.lookback.<i>filepattern</i><br /> block.start.<i>filepattern</i><br /> block.end.<i>filepattern</i> </td> <td> Each of these settings starts with a style number and then a set of words or characters that define how to recognise that feature. If there is a second space in the setting then it is a set of words, otherwise a set of characters. The set of keywords used to indicate the start of a compound statement is defined in statement.indent. For example: <div class="example"> statement.indent.$(file.patterns.cpp)=5 if else while </div> says that for C++ the words "if", "else", and "while" in keyword style, 5, start compound statements which leads to the next line being indented if no other factors affect it. However, if a statement end is found on the same line then the next line is not indented. For C++ the statement end is the semicolon in the operator style, so this is defined: <div class="example"> statement.end.$(file.patterns.cpp)=10 ; </div> The number of lines looked at to determine indentation can be set with statement.lookback. This can be used either to bound the amount of time spent on this task or to specify that only the last line be examined for indentation.<br /> The block.start and block.end properties define the language elements used to bracket groups of statements. In C++ these are '{' and '}'. </td> </tr> <tr id='property-indent.python.colon'> <td> indent.python.colon </td> <td> For Python, automatically indent by one level if the previous line ended in a ':' ignoring comments and whitespace. Otherwise use the same indentation as the previous line. This property overrides other indentation settings. </td> </tr> <tr id='property-os.x.home.end.keys'> <td> os.x.home.end.keys </td> <td> Chooses the standard OS X behaviour for the Home and End keys which is to scroll the file to the start or end. This setting takes precedence over vc.home.key. </td> </tr> <tr id='property-vc.home.key'> <td> vc.home.key </td> <td> Chooses the behaviour of the Home and Shift+Home keys. 1, the default is like Visual C++ moving the caret to the end of the line indentation unless already there, in which case it moves to the start of the line. 0 moves to the start of the line. </td> </tr> <tr class="windowsonly" id='property-warning.findwrapped'> <td> <a name='property-warning.notfound'></a><a name='property-warning.wrongfile'></a><a name='property-warning.executeok'></a><a name='property-warning.executeko'></a><a name='property-warning.nootherbookmark'></a> warning.findwrapped<br /> warning.notfound<br /> warning.wrongfile<br /> warning.executeok<br /> warning.executeko<br /> warning.nootherbookmark </td> <td> Allows for sounds to be played and the window to be flashed on Windows when particular events occur. The values consist of three items separated by ',': flash duration, sound and sound duration. If sound is a number then it is treated as a pitch and played for the duration in milliseconds. Otherwise it is treated as a path to a sound file that is played. If you do not want a flash, specify 0 for flash duration. For example, <div class="example"> warning.wrongfile=0,C:\Windows\Media\SFX\Glass.wav </div> will play the glass sound if open selected is given a bad file name. The findwrapped warning occurs when a find operation wraps past either end of the file, notfound when the find or preprocessor conditional move commands fail to find a match, executeok when a command such as build executes successfully, executeko when a command fails, and nootherbookmark when there is no bookmark to find. </td> </tr> <tr class="gtkonly" id='property-fileselector.width'> <td> <a name='property-fileselector.height'></a> fileselector.width<br /> fileselector.height </td> <td> For the GTK+ version determines the initial size of the file selector dialog invoked by the Open and Save commands. Setting has no effect on Windows. </td> </tr> <tr id='property-fileselector.show.hidden' class="osxonly"> <td> fileselector.show.hidden </td> <td> On OS X setting this to 0 makes the file selector dialog invoked by the Open command not show hidden files. </td> </tr> <tr id='property-locale.properties'> <td> locale.properties </td> <td> Set the name of the localisation file. For a multi-user installation this allows each user to set a preferred user interface language.<br /> On OS X, localisation files for some languages are installed in the translations subdirectory of the user home directory which allows setting the user interface to, for example, German with <div class="example"> locale.properties=$(SciteUserHome)/translations/locale.de.properties </div> </td> </tr> <tr id='property-translation.missing'> <td> translation.missing </td> <td> When using a localised version, if a term is not found in the locale.properties translation file then use the value of translation.missing instead. By setting this to a marker such as "***" it is easier to check where terms have not been provided with translations. </td> </tr> <tr id='property-menu.language'> <td> menu.language </td> <td> Defines the entries in the Language menu and the file extensions they map to. Each menu item is defined by 3 elements, language name, extension and an optional keyboard equivalent. Each element is terminated by '|'. For example:<br /> H&ypertext|html|F12|<br /> Menu items may be commented out by prefixing the name with '#'. </td> </tr> <tr class="gtkonly" id='property-menukey.*'> <td> menukey.* </td> <td> The menukey.* settings allow the user to redefine accelerator keys for menus without having to resort to modifying the SciTE source code. The syntax for the setting is: <div class="example"> menukey.menu_title.menu_name=<modifier>key </div> For example, the File | Exit command accelerator could be specifed as follows: <div class="example"> menukey.file.exit=<control>Q </div> Note that spaces in menu titles and names must be converted to underscores, and trailing ellipses removed. For example, "File | Save As...." is referenced as "menukey.file.save_as". <br /><br /> Multiple modifiers may be specified, though each must be surrounded by angle brackets. The recognised modifiers are the same as for the user.shortcuts setting described above. The recognised named keys are also the same as for user.shortcuts, with the addition of "none" to indicate that no accelerator key should be defined for a particular menu. </td> </tr> <tr class="windowsonly" id='property-source.default.extensions'> <td> source.default.extensions </td> <td> If the name specified on the command line cannot be found as a directory or file - including a wild-card search, the contents of the property are treated as default extensions to be used to locate the file name.<br /> An example is: .cxx|.cpp|.c|.hxx|.hpp|.h|.bat|.txt|.lua<br /> Attempting to open win32\SciTEWin would open win32\SciTEWin.cxx since it matches before win32\SciTEWin.h <br /> If the property contains an entry such as Bar.cxx|.cxx and you attempt to open win32\SciTEWin, it will open ScTEWinBar.cxx since that is the first match. </td> </tr> <tr id='property-ext.lua.startup.script'> <td> <a name='property-ext.lua.auto.reload'></a><a name='property-ext.lua.reset'></a><a name='property-extension'></a> ext.lua.startup.script<br /> ext.lua.auto.reload<br /> ext.lua.reset<br /> extension.<i>filepattern</i> </td> <td> The ext.lua properties are specific to the <a href="SciTELua.html"> SciTE Lua Scripting Extension</a>. The extension.<i>filepattern</i> property is part of the generic <a href="SciTEExtension.html">SciTE Extension Interface</a> but is currently only used by the Lua Scripting Extension. <br /> The ext.lua.startup.script property defines the filename of a Lua script that will be loaded when SciTE starts to set up the global state for Lua. The default value is $(SciteUserHome)/SciTEStartup.lua. You should use an absolute path for this property, but can reference the $(SciteDefaultHome) or $(SciteUserHome) properties. Global event handlers, command functions, as well as other functions and objects can be defined here. <br /> The ext.lua.auto.reload property determines what happens if you save the startup script, or the active extension script, from within SciTE. If it is set to 0, the startup script only applied at startup time or when you switch buffers (depending on ext.lua.reset), and changes to the extension script are only applied when you switch buffers. If ext.lua.auto.reload is set to 1 (the default), SciTE will re-initialize the global scope immediately when either script is saved from within SciTE. <i>Even when ext.lua.auto.reload is enabled, SciTE will not notice if the files are changed from outside the current SciTE instance. For that, see ext.lua.reset below.</i> <br /> The ext.lua.reset property is primarily for debugging. If ext.lua.reset is 0 (the default), the startup script property is checked only once - when SciTE starts. If ext.lua.reset is changed to 1, SciTE will check the startup script property, and reload the new startup script, each time you switch buffers. As such, it has a different (larger) set of side effects than ext.lua.auto.reload. In some situations it will make sense for both auto.reload and reset to be enabled, but usually ext.lua.auto.reload alone will suffice. <br /> Aside from ext.lua.startup.script, the extension.<i>filepattern</i> property provides a way to load additional functions and event handlers that may be specific to a given file type. If the extension property value ends in .lua and names a file that exists, the Lua extension evaluates the script so that event handlers and commands defined in the script are available while that buffer is active. Functions and objects defined through ext.lua.startup.script are still accessible, unless they are overridden. <br /> The extension property can also define behavior that is specific to a given directory. If a bare filename (no path) is specified in the extension property, SciTE looks for the file in the standard property file locations, starting with the local directory. This can be very useful in combination with a local SciTE.properties file. </td> </tr> <tr id='property-caret.sticky'> <td> caret.sticky </td> <td> Controls when the last position of the caret on the line is modified. When set to 1, the position is not modified when you type a character, a tab, paste the clipboard content or press backspace. The default is 0 which turns off this feature. </td> </tr> <tr id='property-properties.directory.enable'> <td> properties.directory.enable </td> <td> Enables or disables the evaluation of the directory properties file. The default is 0 which disables the evaluation. Any other value enables this properties file. </td> </tr> </table> <p> caret.policy.{x|y}<param> interaction: </p> <table cellpadding="1" cellspacing="0" border="1" summary="Caret policy"> <tr> <th>slop</th> <th>strict</th> <th>jumps</th> <th>even</th> <th>Caret can go to the margin</th> <th>When reaching limit<br /> (going out of visibility or<br /> going into the UZ)<br /> display is...</th> </tr> <tr> <td align="center">0</td> <td align="center">0</td> <td align="center">0</td> <td align="center">0</td> <td>Yes</td> <td>moved to put caret on top/on right</td> </tr> <tr> <td align="center">0</td> <td align="center">0</td> <td align="center">0</td> <td align="center">1</td> <td>Yes</td> <td>moved by one position</td> </tr> <tr> <td align="center">0</td> <td align="center">0</td> <td align="center">1</td> <td align="center">0</td> <td>Yes</td> <td>moved to put caret on top/on right</td> </tr> <tr> <td align="center">0</td> <td align="center">0</td> <td align="center">1</td> <td align="center">1</td> <td>Yes</td> <td>centred on the caret</td> </tr> <tr> <td align="center">0</td> <td align="center">1</td> <td align="center">-</td> <td align="center">0</td> <td>Caret is always on top/on right of display</td> <td>-</td> </tr> <tr> <td align="center">0</td> <td align="center">1</td> <td align="center">-</td> <td align="center">1</td> <td>No, caret is always centred</td> <td>-</td> </tr> <tr> <td align="center">1</td> <td align="center">0</td> <td align="center">0</td> <td align="center">0</td> <td>Yes</td> <td>moved to put caret out of the asymmetrical UZ</td> </tr> <tr> <td align="center">1</td> <td align="center">0</td> <td align="center">0</td> <td align="center">1</td> <td>Yes</td> <td>moved to put caret out of the UZ</td> </tr> <tr> <td align="center">1</td> <td align="center">0</td> <td align="center">1</td> <td align="center">0</td> <td>Yes</td> <td>moved to put caret at 3UZ of the top or right margin</td> </tr> <tr> <td align="center">1</td> <td align="center">0</td> <td align="center">1</td> <td align="center">1</td> <td>Yes</td> <td>moved to put caret at 3UZ of the margin</td> </tr> <tr> <td align="center">1</td> <td align="center">1</td> <td align="center">-</td> <td align="center">0</td> <td>Caret is always at UZ of top/right margin</td> <td>-</td> </tr> <tr> <td align="center">1</td> <td align="center">1</td> <td align="center">0</td> <td align="center">1</td> <td>No, kept out of UZ</td> <td>moved by one position</td> </tr> <tr> <td align="center">1</td> <td align="center">1</td> <td align="center">1</td> <td align="center">0</td> <td>No, kept out of UZ</td> <td>moved to put caret at 3UZ of the margin</td> </tr> </table> <h3 id="NewLanguage"> Supporting a new language </h3> <p> For languages very similar to existing supported languages, which may only differ in a minor feature such as the keywords used, the existing lexers can often be reused. The set of keywords can then be changed to suit the new language. Java and JavaScript could have reasonably reused the C++ lexer. The Java lexer was added only to support doc comments. </p> <p> For languages that can not be lexed with the existing lexers, a new lexer can be coded in C++. These can either be built into Scintilla, or put into an external module and loaded when SciTE runs (See lexerpath).</p> <a href="SciTELexer.html">Installing a lexer into SciTE</a> <br /> <a href="SciTEExternalLexer.html">Creating and installing an external lexer</a><br /> <p> The open.filter should be modified to include the file extensions used for the new language and entries added for command.compile, command.build, command.go and command.go.needs for the language. </p> <h3 id="APIFiles"> Creating API files </h3> <p> The .api files can be generated by hand or by using a program. There are also <a href="http://code.google.com/p/scite-files/wiki/Customization">downloadable ready-to-use .api files.</a> </p> <p> For C/C++ headers, an API file can be generated using <a href="http://ctags.sourceforge.net/">ctags</a> and then the <a href="tags2api.py"> tags2api Python script</a> (which assumes C/C++ source) on the tags file to grab complete multiple line function prototypes. Some common headers surround parameter lists with a __P macro and may have comments. The <a href="cleanapi.cc">cleanapi</a> utility may be used on these files. </p> <p> To generate an API file for Python modules, there is a <a href="gen_python_api.zip">gen_python script</a>. </p> <p> To generate an API file for Java classes, there is a <a href="ApiBuilder.java">ApiBuilder.java</a> program. </p> <h3 id="OpenSelected"> Open Selected Filename </h3> <p> This command opens the file for the file name selected in either the edit or output pane. It uses the current selection or searches around the caret to try to find a file name based on which characters are normally used in a path. If there is no extension then an extension may be inferred from the current file using the open.suffix property which defaults to .properties in a .properties file. If the file name is followed by a number (in a format similar to ctags, grep output, or Visual Studio messages) then that line is displayed in the opened file. If the file name is an absolute path then it is opened directly otherwise it is looked for in the current directory and then in the directory specified by the openpath property. On Windows, web, ftp, mail and news URLs are handled by opening their associated application. </p> <h3 id="Translations"> SciTE in other languages </h3> <p> SciTE can be and has been <a href="http://code.google.com/p/scite-files/wiki/Translations">translated into other languages</a>. </p> <h3 id="Building"> Building SciTE </h3> <p> The procedure for building and installing SciTE is described in the README file in the scite directory. </p> <h3 id="Extending"> Extending SciTE </h3> <p> There are two formal extension interfaces for SciTE, the <a href="SciTEExtension.html">SciTE Extension Interface</a> is for extending SciTE with code compiled into the SciTE executable and the <a href="SciTEDirector.html">SciTE Director Interface</a> is for manipulating SciTE on Windows from another application. </p> </body> </html> |
Added doc/SciTEDownload.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="HTML Tidy, see www.w3.org" /> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title> Download Scintilla and SciTE </title> <style type="text/css"> h3 { background-color: #CCCCFF; } </style> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5">Download Scintilla and SciTE</font></a> </td> </tr> </table> <table bgcolor="#CCCCCC" width="100%" cellspacing="0" cellpadding="8" border="0"> <tr> <td> <font size="4"> <a href="http://prdownloads.sourceforge.net/scintilla/scite325.zip?download"> Windows</a> <a href="http://prdownloads.sourceforge.net/scintilla/scite325.tgz?download"> GTK+/Linux</a> </font> </td> </tr> </table> <h2> Download </h2> <p> The <a href="License.txt">license</a> for using Scintilla or SciTE is similar to that of Python containing very few restrictions. </p> <h2> Release 3.2.5 </h2> <h3> Source Code </h3> The source code package contains all of the source code for Scintilla and SciTE but no binary executable code and is available in <ul> <li><a href="http://prdownloads.sourceforge.net/scintilla/scite325.zip?download">zip format</a> (2250K) commonly used on Windows</li> <li><a href="http://prdownloads.sourceforge.net/scintilla/scite325.tgz?download">tgz format</a> (2000K) commonly used on Linux and compatible operating systems</li> </ul> Instructions for building on both Windows and Linux are included in the readme file. <h3> Windows </h3> <h4> Windows Executables </h4> <p> Windows executables only support Windows XP and later. It may be possible to build with older compilers for Windows 2000 but that is no longer tested. </p> <p> A <a href="http://prdownloads.sourceforge.net/scintilla/wscite325.zip?download">full download</a> (1100K) includes the SciTE executable, any required DLLs, configuration files and documentation. After downloading the file, unzip it, and run SciTE.EXE. The files required to run SciTE are SciTE.EXE, SciLexer.DLL, and SciTEGlobal.properties. </p> <p> A <a href="http://prdownloads.sourceforge.net/scintilla/Sc325.exe">single file executable called Sc1</a> (700K) does not need any DLL or properties files as these are linked into the executable. You may still create properties files if you wish. Sc1.exe has been compressed with the <a href="http://upx.sourceforge.net">UPX compressor</a> so that it is a fast download. It does not need to be decompressed to be used. </p> <h4> Windows Installer </h4> <p> <a href="http://opensource.ebswift.com/SciTEInstaller/">An installer</a> created by Troy Simpson. </p> <h3> GTK+ / Linux </h3> <h4> Linux executable for 32-bit Intel compatible processors </h4> <p> This binary release requires GTK+ 2.8 or later and was tested on Ubuntu 10.4. If you are using a Linux distribution more than a year old you may need to rebuild SciTE to use your installed version of GTK+. If the target system is 64-bit, you may also need to build SciTE from source. </p> <p> A <a href="http://prdownloads.sourceforge.net/scintilla/gscite325.tgz?download">full download</a> (1000K) includes the 32-bit SciTE executable, configuration files and documentation. After downloading the file, gunzip and untar it, and run SciTE. The files required to run SciTE are SciTE which is best located on the path (I put it in /usr/local/bin) 70 properties files which should be located in the /usr/share/scite directory, and Sci48M.png which should be copied to /usr/share/pixmaps. </p> <h4> Debian Packages </h4> <p> Official Debian Packages are available from Apt. There is a <a href="http://packages.debian.org/etch/scite">package page</a>. </p> <p> Contributed by Aubin Paul. </p> <h3> SciTE localised for other languages </h3> <p> SciTE can be and has been <a href="http://code.google.com/p/scite-files/wiki/Translations">translated into other languages</a>. </p> <p> Previous versions can be downloaded from the <a href="ScintillaHistory.html">history page</a>. </p> </body> </html> |
Added doc/SciTEExtension.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title> SciTE Extension Interface </title> <style type="text/css"> .example { color: #00A000; font-weight: bold; } DIV.example { background: #F7FCF7; border: 1px solid #C0D7C0; margin: 0.3em 3em; padding: 0.3em 0.6em; font-size: 80%; } </style> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5"> SciTE Extension Interface</font></a> </td> </tr> </table> <h3> Purpose. </h3> <p>Some people want to create enhanced versions of the SciTE editor, while still receiving the benefits of new SciTE features. This could be for an editor designed for a particular environment such as developing games, to incorporate a scripting capability within SciTE or to allow SciTE to be controlled by another process through an IPC mechanism.</p> <p>There are two example extensions. The <a href="SciTEDirector.html">SciTE Director Interface</a> allows SciTE on Windows to be controlled by an external application such as a project manager. The <a href="SciTELua.html">SciTE Lua Scripting Extension</a> is an integration of the Lua scripting language into SciTE, done using the Extension interface.</p> <h3> Extension Interface. </h3> <div class="example"> bool Initialise(ExtensionAPI *host_);<br /> bool Finalise();<br /> bool Clear();<br /> bool Load(const char *filename);<br /> bool InitBuffer(int index);<br /> bool ActivateBuffer(int index);<br /> bool RemoveBuffer(int index);<br /> bool OnOpen(const char *path);<br /> bool OnSwitchFile(const char *path);<br /> bool OnBeforeSave(const char *path);<br /> bool OnSave(const char *path);<br /> bool OnChar(char ch);<br /> bool OnExecute(const char *s);<br /> bool OnSavePointReached();<br /> bool OnSavePointLeft();<br /> bool OnStyle(unsigned int, int, int, Accessor *);<br /> bool OnDoubleClick();<br /> bool OnUpdateUI();<br /> bool OnMarginClick();<br /> bool OnMacro(const char *, const char *);<br /> bool SendProperty(const char *);<br /> bool OnKey(int keyval, int modifiers);<br /> bool OnDwellStart(int pos, const char *word);<br /> bool OnClose(const char *filename);<br /> </div> <p>An extension must implement the Extension interface defined in scite/src/Extender.h Only the first 4 methods must be implemented although an implementation can be as simple as just returning false. The other methods have empty default implementations. Methods added to this interface in the future should have default implementations so existing extensions will continue to compile.</p> <p>Each method returns a bool indicating whether the method handled all processing that is needed and so no additional processing is required. Normally, false is returned to indicate that further processing may be done.</p> <p>The extension should use the Initialise and Finalise methods to allocate and deallocate resources. The ExtensionAPI pointer should be saved in the Initialise method so the extension can communicate back to SciTE.</p> <p>The Clear and Load methods are used to support extensions that need to load a resource such as a script file when a file is opened. When a file is opened in SciTE, first the extension is asked to clear any data associated with the previous file through Clear. Then SciTE checks for a property called "extension" which matches the file name, so for x.cpp, looks for extension.*.cpp. A file with this name is searched for in standard property file locations and if found Load is called with the path as an argument.</p> <p>The InitBuffer, ActivateBuffer, and RemoveBuffer methods provide the necessary hooks so that extensions have a mechanism to associate data with a specific buffer, similar to the way SciTE itself remembers the monospace setting of each buffer. InitBuffer is called whenever a new document is opened in a given buffer. The buffer might be a newly allocated one, or it might be recycled if the maximum number of buffers has been reached. Once the buffer has been initialized, it will be the active buffer. Thereafter, ActivateBuffer is called whenever the user switches to another loaded buffer. RemoveBuffer is called when an existing buffer is closed. Thereafter, the indexes of the buffers that come after the removed buffer are shifted down by one. After RemoveBuffer, the extension will receive an InitBuffer or ActivateBuffer to establish the new active buffer.</p> <p>OnExecute is called only when an extension command is executed. These are indicated in properties as subsystem 3.</p> <p>OnBeforeSave is called before saving the file and an extension may implement file saving itself and return true to prevent the default file save code from executing.</p> <p>Other methods are called upon events occurring in SciTE allowing an extension to respond to those events.</p> <h3> ExtensionAPI Interface. </h3> <div class="example"> enum Pane { paneEditor=1, paneOutput=2, paneFindOutput=3 };<br /> sptr_t Send(Pane p, unsigned int msg, uptr_t wParam=0, sptr_t lParam=0);<br /> char *Range(Pane p, int start, int end);<br /> void Remove(Pane p, int start, int end);<br /> void Insert(Pane p, int pos, const char *s);<br /> void Trace(const char *s);<br /> char *Property(const char *key);<br /> void SetProperty(const char *key, const char *val);<br /> uptr_t GetInstance();<br /> void ShutDown();<br /> void Perform(const char *actions);<br /> void DoMenuCommand(int cmdID);<br /> void UpdateStatusBar(bool bUpdateSlowData);<br /> </div> <p>An extension can call back into SciTE using this interface which is a simplified way to access the functionality of SciTE.</p> <p>As well as the normal editor pane and output pane, this interface allows for a future feature where a third pane may be used for the output of search commands. This is currently mapped to the output pane.</p> <p>Send allows sending messages to the Scintilla control contained in each pane.</p> <p>Range retrieves text from the pane. This must be deleted with delete[]. Remove and Insert are used to remove and insert text in a pane.</p> <p>Trace displays a string at the end of the output pane.</p> <p>SciTE's properties can be read and written with Property and SetProperty. The result from Property should be deleted with delete[].</p> <p>GetInstance is Windows specific and returns the HINSTANCE of the application which is needed when accessing platform facilities.</p> <p>ShutDown is equivalent to the user choosing the Quit menu item. If there are any unsaved files loaded, then the user is asked whether to save them and may cancel from this dialog. So under some circumstances, the application will continue to run after ShutDown is called.</p> <p>Perform takes a string containing an action, a ':' character, and an argument. Currently the only known action is open and then the argument is a path. This is used by the <a href="SciTEDirector.html">Director extension</a> to relay commands from another application. In the future more actions will be possible through this method.</p> <h3> Attaching the extension. </h3> <p>Extensions are currently added explicitly by code in the start up function. On Windows, the DirectorExtension is attached with code similar to this simplified example:</p> <div class="example"> DirectorExtension director;<br /> Extension *extender = &director;<br /> //...<br /> SciTEWin MainWind(extender); </div> <p>It would be better to move to an implicit attachment mechanism similar to the way lexers are attached to Scintilla, determining which extensions are used by simply linking their object files into SciTE. It would also be good to allow run-time attachment of extensions housed in DLLs or shared object libraries.</p> <h3> Multiplexing. </h3> <p>SciTE supports multiple extensions at a time. A multiplexer extension maintains a list of extensions and calls each in turn for each method. Once an extension returns true indicating processing should stop, the multiplexer returns without traversing any remaining list members. However, for some methods such as Initialise and Finalise, the remaining extensions are traversed regardless of the return value of the previous extension.</p> <h3> Thread safety. </h3> <p>In general, SciTE is a single threaded application. However, on Windows, command tools call OnExecute from a separate worker thread. The SingleThreadExtension adapter class can be used to wrap an extension so that OnExecute calls are marshalled to the main thread. Of course, this is not necessary if your extension is thread safe, or if it does not implement OnExecute, or if it is a GTK-specific extension. </body> </html> |
Added doc/SciTEExternalLexer.html.
> > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
</html> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0" id="table1"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5"> Add an external lexer to SciTE</font></a> </td> </tr> </table> <h2> Lexer addition. </h2> <p>This document has been superceded by the new <a href="http://www.scintilla.org/nulex.html">lexer object design</a> </p> </body> </html> |
Added doc/SciTEExtras.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title> SciTE Extras </title> <style type="text/css"> table { border: 1px solid black; border-collapse: collapse; } td { border: 1px solid black; padding: 1px 5px 1px 5px; } th { border: 1px solid black; padding: 1px 5px 1px 5px; } </style> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5"> API files and property files for SciTE</font></a> </td> </tr> </table> <h2 style="background: #FFB000"> <a href="http://code.google.com/p/scite-files/wiki/Customization">The current version of this page has moved here</a>. </h2> <h3> This page contains various contributed files that can be used with SciTE. </h3> <h3> Shells </h3> <ul> <li><a href="http://llt.chez.tiscali.fr/">Filerx</a> provides project management and macro features on Windows.</li> <li><a href="http://www.frykholm.se/scitecmd.html">scitecmd</a> is a simple utility for opening files as tabs in SciTE from the command line on Windows.</li> </ul> <h3> APDL </h3> <ul> <li><a href="http://www.scintilla.org/apdl.zip">APDL properties and API</a></li> </ul> <h3> ASP </h3> <ul> <li><a href="http://www.scintilla.org/asp.api">ASP API methods</a></li> </ul> <h3> AutoHotkey </h3> <ul> <li><a href="http://www.scintilla.org/ahk.properties">AutoHotkey properties</a></li> </ul> </ul> <h3> AutoIt3 </h3> <ul> <li><a href="http://www.autoitscript.com/autoit3/scite">SciTE4AutoIt3 Website containing AutoIt3 related properties and API files.</a></li> </ul> <h3> C </h3> <ul> <li><a href="http://www.scintilla.org/c.api">C standard library</a></li> </ul> <h3> C++ </h3> <ul> <li><a href="http://www.nbk.orc.ru/scintilla/cpp.api.zip">Windows API</a></li> <li><a href="http://www.scintilla.org/opengl.zip">OpenGL API</a></li> <li><a href="http://www.scintilla.org/glut.zip">Glut API</a></li> </ul> <h3> C# </h3> <ul> <li><a href="http://www.scintilla.org/genapi.zip">C# API file and generator program.</a></li> </ul> <h3> CIL </h3> <ul> <li><a href="http://www.scintilla.org/il.properties">Properties for CIL/MSIL</a></li> </ul> <h3> CMake </h3> <ul> <li><a href="http://www.scintilla.org/cmake.api">CMake API</a></li> </ul> <h3> FORTRAN </h3> <ul> <li><a href="http://www.scintilla.org/fortran.api">Standard FORTRAN API functions</a></li> </ul> <h3> Java </h3> <ul> <li><a href="http://www.burgaud.com/scite.php">Java API and Java Help</a></li> </ul> <h3> Lua </h3> <ul> <li><a href="http://www.geocities.com/keinhong/scite/lua5api.zip">Lua 5 C API and Lua functions</a></li> </ul> <h3> Microsoft SQL </h3> <ul> <li><a href="http://www.scintilla.org/mssql.properties">Replaces sql.properties</a></li> </ul> <h3> MySQL </h3> <ul> <li><a href="http://jakub.vrana.cz/utility/scite_mysql.zip">Keywords</a></li> </ul> </ul> <h3> nncron </h3> <ul> <li><a href="http://www.nbk.orc.ru/scintilla/nncron.api">nncron.api</a></li> </ul> <h3> Oracle </h3> <ul> <li><a href="http://www.scintilla.org/sql.properties_ext">Extended properties file</a> with additional keywords and standard package names.</li> </ul> <h3> osCommerce </h3> <ul> <li><a href="http://www.rvdesign.de/index.php/SciTE"> API. German language site.</a></li> </ul> <h3> Perl </h3> <ul> <li><a href="http://www.scintilla.org/perl.api">Perl API</a></li> </ul> <h3> PHP </h3> <ul> <li><a href="http://www.scintilla.org/html.properties">html.properties</a></li> <li><a href="http://www.scintilla.org/php.api">php.api for PHP 4.3.3</a></li> <li><a href="http://www.scintilla.org/php.properties">PHP properties</a></li> <li><a href="http://www.scintilla.org/phpfunctions.properties">PHP functions</a></li> <li><a href="http://jakub.vrana.cz/utility/scite_php_t.zip"> Utilities for making PHP support files.</a></li> <li><a href="http://www.scintilla.org/phpapi.php.txt">A script for creating api file out of your own php source code</a></li> </ul> <h3> POV-Ray </h3> <ul> <li><a href="http://www.scintilla.org/pov.api">POV-Ray API</a></li> </ul> <h3> TADS3 </h3> <ul> <li><a href="http://www.scintilla.org/tads3.properties"> TADS3 property file</a></li> <li><a href="http://www.scintilla.org/TADS3.txt"> Explanation</a></li> </ul> <h3> Windows Scripting </h3> <ul> <li><a href="http://dev.remotenetworktechnology.com/SciTE/index.htm"> Properties files and scripts.</a></li> </ul> </body> </html> |
Added doc/SciTEFAQ.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="HTML Tidy, see www.w3.org" /> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html" /> <title> SciTE FAQ </title> <style type="text/css"> table { border: 1px solid #1F1F1F; border-collapse: collapse; } td { border: 1px solid #1F1F1F; padding: 1px 5px 1px 5px; } th { border: 1px solid #1F1F1F; padding: 1px 5px 1px 5px; } h4 { background-color: #000000; color: #FFFFFF; padding: 2px 6px; } .example { color: #00A000; font-weight: bold; } DIV.example { background: #F7FCF7; border: 1px solid #C0D7C0; margin: 0.3em 3em; padding: 0.3em 0.6em; font-size: 80%; } </style> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0" summary="banner"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5"> SciTE</font></a> </td> </tr> </table> <h2> SciTE Frequently Asked Question </h2> <ul> <li><a class="toc" href="#FixedWidth"> How do I use a fixed width font for all text?</a></li> <li><a class="toc" href="#Monospaced"> What happened to <span class="example">use.monospaced</span>?</a></li> <li><a class="toc" href="#LineNumbers"> Why doesn't my <span class="example">line.numbers</span> setting work?</a></li> <li><a class="toc" href="#BlackBackground"> How do I change SciTE to use black as the background colour?</a></li> <li><a class="toc" href="#OutputColour"> How do I change the colours of the output pane?</a></li> <li><a class="toc" href="#HorizontalScrollBar"> How do I make the horizontal scroll bar adjust to the width of text?</a></li> <li><a class="toc" href="#TabbedMode"> How do I enable tabbed window mode in SciTE?</a></li> <li><a class="toc" href="#Autocomplete"> How do I enable autocomplete?</a></li> <li><a class="toc" href="#CannotFindFile"> When I try to compile/build/run my [some language] source files, I get the following error: 'The system cannot find the file specified'.</a></li> <li><a class="toc" href="#ToolsMenu"> How can I add [some external application] to the Tools menu on SciTE?</a></li> <li><a class="toc" href="#ToolsNoMenu"> How can I add a keyboard command without adding it to the Tools menu?</a></li> <li><a class="toc" href="#ReplaceInFiles"> Is there a command to replace a string in multiple files together?</a></li> <li><a class="toc" href="#SpeedUpGTK"> How do I make SciTE run faster on GTK+?</a></li> <li><a class="toc" href="#NewlineInRegEx"> Is it possible to use the newline character (\n) in a regular expression?</a></li> <li><a class="toc" href="#CompilerErrors"> How do I get SciTE to understand the error messages from my compiler?</a></li> <li><a class="toc" href="#GCCUTF8"> Why do GCC error messages include ugly characters?</a></li> <li><a class="toc" href="#WindowsSpaces"> How do I make Windows open a file associated with SciTE when its path contains spaces?</a></li> <li><a class="toc" href="#ExplicitFolds"> Why does a //{ comment affect folding?</a></li> </ul> <h4 id="FixedWidth"> How do I use a fixed width font for all text? </h4> <p> Use these properties:</p><div class="example"> font.base=$(font.monospace)<br /> font.small=$(font.monospace)<br /> font.comment=$(font.monospace)<br /> font.text=$(font.monospace)<br /> font.text.comment=$(font.monospace)<br /> font.embedded.base=$(font.monospace)<br /> font.embedded.comment=$(font.monospace)<br /> font.vbs=$(font.monospace)</div> <h4 id="Monospaced"> What happened to <span class="example">use.monospaced</span>? </h4> <p> The <span class="example">use.monospaced</span> property was removed as people were using it to ask for fixed width fonts and then requiring support to cope with its limitations. The correct way to set fixed width fonts is <a class="toc" href="#FixedWidth">here</a>. </p> <h4 id="LineNumbers"> Why doesn't my <span class="example">line.numbers</span> setting work? </h4> <p> <span class="example">line.numbers</span> has been replaced with two properties: <span class="example">line.margin.visible</span> and <span class="example">line.margin.width</span> which are explained earlier in <a href="SciTEDoc.html"> the main SciTE document</a>. </p> <h4 id="BlackBackground"> How do I change SciTE to use black as the background colour? </h4> <p> You need to change the style settings. The main change is in the user options file to the global default style and caret colour but you may have to change other style settings to make this work well:</p><div class="example"> style.*.32=$(font.base),back:#000000,fore:#ffffff<br /> style.*.33=back:#C0C0C0,$(font.base)<br /> style.*.37=fore:#939393<br /> caret.fore=#FFFFFF<br /> selection.alpha=75<br /> selection.back=#FFFFFF<br /> colour.keyword=fore:#649bff<br /> colour.operator=fore:#727272</div> <h4 id="OutputColour"> How do I change the colours of the output pane? </h4> <p> The output pane often lists error and warning messages and is styled by the "errorlist" lexer. The default errorlist styles are found in others.properties. To change the output pane background to black and the default text to white set</p><div class="example"> style.errorlist.32=$(font.small),back:#000000<br /> style.errorlist.0=fore:#FFFFFF</div> <h4 id="HorizontalScrollBar"> How do I make the horizontal scroll bar adjust to the width of text? </h4> <p> To avoid slow performance the horizontal scroll bar does not automatically adjust. You can use the <span class="example">horizontal.scroll.width</span> property to change the horizontal scroll range. </p> <h4 id="TabbedMode"> How do I enable tabbed window mode in SciTE? </h4> <p> Multiple buffers must be allocated by setting, for example, <span class="example">buffers=10</span> in your SciTEGlobal.properties. To have the tab bar visible upon starting SciTE, set <span class="example">tabbar.visible=1</span>. You can also set <span class="example">tabbar.hide.one=0</span> to always show tabs, or 1 to hide when only one file is open. <span class="example">tabbar.multiline=1</span> splits tabs across various lines if necessary. </p> <h4 id="Autocomplete"> How do I enable autocomplete? </h4> <p> Goto Options | Open Global Options File and uncomment</p> <div class="example">autocompleteword.automatic=1</div> <h4 id="CannotFindFile"> When I try to compile/build/run my [some language] source files, I get the following error: 'The system cannot find the file specified'. </h4> <p> Make sure that the path to your compiler is set correctly on your system. Try to execute from console the same command you get in SciTE and see if it works. You can also search in your [language].properties for the compile commands used. If you have a different compiler or use different arguments, edit the commands to suit your needs. The lines to look for:</p><div class="example"> command.compile.filepattern=<br /> command.build.filepattern=<br /> command.go.filepattern=</div> <h4 id="ToolsMenu"> How can I add [some external application] to the Tools menu on SciTE? </h4> <p> In your properties file, you'll need to add some lines: </p> <p> <span class="example">command.name.number.filepattern</span><br /> (e.g.: <span class="example">command.name.1.$(file.patterns.web)=HTML Tidy</span>)<br /> This defines the Text that will appear on the Tools Menu. </p> <p> <span class="example">command.number.filepattern</span><br /> (e.g.: <span class="example">command.1.$(file.patterns.web)=tidy -i -wrap 0 -m $(FilePath)</span> )<br /> This is the actual command that SciTE executes. You should provide the appropriate paths, options and parameters as you would from a command line. See SciTEDoc.html for more information on parameters and how to make SciTE prompt a Parameters Dialog. </p> <p> <span class="example">command.is.filter.number.filepattern</span><br /> (e.g.: <span class="example">command.is.filter.1.$(file.patterns.web)=1</span>)<br /> The external application may have modified your file, so setting this to true makes SciTE reload the file after execution of the command. </p> <p> <span class="example">command.subsystem.number.filepattern</span><br /> (e.g.: <span class="example">command.subsystem.1.$(file.patterns.web)=2</span>)<br /> This is for Windows and defines the subsystem through which the program is called. See SciTEDoc.html for more information on this. </p> <p> You can set a command for all files using * as a file pattern. Up to 10 commands (0 - 9) can be defined in the Tools Menu at any time. Commands also get executed with Ctrl+number. </p> <h4 id="ToolsNoMenu"> How can I add a keyboard command without adding it to the Tools menu? </h4> <p> This is similar to <a href="#ToolsMenu">adding to the tools menu</a> except that you set the name to be empty. Then the command is included in <span class="example">user.shortcuts</span> by adding 1100 to produce its command ID. For example,</p> <div class="example"> command.name.21.*.properties=<br /> command.21.*.properties=cmd /c echo $(FileNameExt)<br /> user.shortcuts=\<br /> Ctrl+Shift+V|1121|<br /> </div> <h4 id="ReplaceInFiles"> Is there a command to replace a string in multiple files together? </h4> <p> It is possible to replace a string in all opened buffers with the Replace in Buffers button in the Replace dialog. However this button is hidden by default, it can be displayed with <span class="example">find.replace.advanced=1</span>. </p> <h4 id="SpeedUpGTK"> How do I make SciTE run faster on GTK+? </h4> <p> The default settings for SciTE were changed in version 1.63 to use the Pango font system and antialiased fonts. You can return to using X core fonts which are faster with these settings:</p><div class="example"> font.base=font:lucidatypewriter,size:12<br /> font.small=font:lucidatypewriter,size:10<br /> font.comment=font:new century schoolbook,size:12<br /> font.code.comment.box=$(font.comment)<br /> font.code.comment.line=$(font.comment)<br /> font.code.comment.doc=$(font.comment)<br /> font.text=font:times,size:14<br /> font.text.comment=font:lucidatypewriter,size:10<br /> font.embedded.base=font:lucidatypewriter,size:12<br /> font.embedded.comment=font:lucidatypewriter,size:12<br /> font.monospace=font:courier,size:12<br /> font.vbs=font:new century schoolbook,size:12<br /> </div> <p>Line wrapping also slows SciTE down and this can be turned off with <span class="example">wrap=0</span>. </p> <h4 id="NewlineInRegEx"> Is it possible to use the newline character (\n) in a regular expression? </h4> <p> No. </p> <p> The "Transform backslash expressions" option allows using \n and \r but that option does not work with regular expressions. </p> <h4 id="CompilerErrors"> How do I get SciTE to understand the error messages from my compiler? </h4> <p> The set of error message formats is embedded in the Scintilla and SciTE code. To add support for another compiler, you will need to add a new style to scintilla/include/Scintilla.iface after the other SCE_ERR_* values, run HFacer.py, edit RecogniseErrorListLine in scintilla/src/LexOthers.cxx to recognise the error message, and edit DecodeMessage in scite/src/SciTEBuffers.cxx to extract the file name and line number. </p> <h4 id="GCCUTF8"> Why do GCC error messages include ugly characters? </h4> <p> Linux distributions now often set the locale to UTF-8 by, for example, setting LANG=en_US.UTF-8. gcc takes this as an indication that it can use any Unicode character encoded as UTF-8 so quotes using ‘these’ rather than ASCII. To see these as intended, set</p> <div class="example"> output.code.page=65001</div> <h4 id="WindowsSpaces"> How do I make Windows open a file associated with SciTE when its path contains spaces? </h4> <p> On some versions of Windows, associating a particular file type with SciTE does not allow paths containing spaces to work. To fix this, the path variable %1 needs to be surrounded by double quotes. This is done either directly in the registry or through the Explorer in Tools | Folder Options | File Types | (Select type) | Advanced | open | Edit. Change the "Application used to perform action" field to be similar to</p> <div class="example">"C:\bin\SciTE\SciTE.exe" "%1"</div> <h4 id="ExplicitFolds"> Why does a //{ comment affect folding? </h4> <p> For C++ and similar languages, explicit folds can be added with //{ and //} . This feature can be turned off with</p> <div class="example"> fold.comment=0</div> </body> </html> |
Added doc/SciTEIco.png.
cannot compute difference between binary files
Added doc/SciTEImage.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="HTML Tidy, see www.w3.org" /> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title> Scintilla and SciTE </title> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5">Scintilla and SciTE</font></a> </td> </tr> </table> <br /> <img src="SciTE224.png" /> </body> </html> |
Added doc/SciTELexer.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="HTML Tidy, see www.w3.org" /> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title> Download Scintilla and SciTE </title> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5"> Add a lexer to Scintilla and SciTE</font></a> </td> </tr> </table> <h2> Lexer addition. </h2> <p>The process of adding a new lexer to both Scintilla and SciTE is fairly long. Here is my response when asked how to add a lexer for Apache CONF files to SciTE. There is more information on writing the lexer code (steps 4 and 5, here) in the documentation for Scintilla.</p> <p> Don't bother about steps which are for configurations you don't use all 6 makefiles - I'll patch them up later if you want to contribute the lexer.</p> <ol> <li> In scintilla/include/Scintilla.iface, add a lexer ID value:<br /> val SCLEX_CONF=17 </li> <li> And any lexical class IDs:<br /> val SCE_CONF_DEFAULT=0<br /> val SCE_CONF_COMMENT=1 </li> <li> In the scintilla/include directory run HFacer.py to regenerate the SciLexer.h file. Alternatively (if you don't want to run a Python script) just add these values to SciLexer.h as #defines and I'll put them in Scintilla.iface. </li> <li> In the scintilla/src/LexOthers.cxx write a ColouriseConfDoc function similar to one of the other functions such as ColouriseLatexDoc.<br /> static void ColouriseConfDoc (unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { </li> <li> At the end of the file associate the lexer ID and name with the function:<br /> LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf"); </li> <li> If this is a complex lexer then it may be better off in its own file, in which case clone one of the current files and then add the file to all of the make files where LexOthers is currently referenced - scintilla/win32/makefile, scintilla/win32/scintilla.mak, scintilla/gtk/makefile, scite/win32/makefile, and scite/win32/scite.mak. </li> <li> To the scite/src/others.properties add an entry to associate the file extension with the lexer:<br /> lexer.*.conf=conf<br /> If a new lexer file was created instead of adding to LexOthers, then a new properties file should be created by cloning scite/src/others.properties and modifying that file in the following steps. </li> <li> Set up the styles:<br /> # Default<br /> style.conf.0=fore:#FF0000,bold<br /> # Comment<br /> style.conf.1=fore:#007F7F,$(font.comment)<br /> </li> <li> If on Windows (someday this may work on GTK+ too), a filter should be added for conf files in scite/src/others.properties: filter.conf=Configuration (.conf)|*.conf| </li> <li> In scite/src/SciTEGlobal.properties add $(filter.conf) to the definition of open.filter. </li> <li> To add this language to the Language menu of SciTE, add an entry to the menu.language property including the name of the language and the file extension used most commonly for it. </li> <li> Build both Scintilla and SciTE. </li> <li> Share and enjoy </li> </ol> <p> For more extensive information on building lexers, see the <a href ="http://www.scintilla.org/ScintillaDoc.html#BuildingScintilla"> instructions in the Scintilla documentation</a>. </p> </body> </html> |
Added doc/SciTELua.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title> SciTE Lua Scripting Extension </title> <style type="text/css"> .example { color: #00A000; font-weight: bold; } DIV.example { background: #F7FCF7; border: 1px solid #C0D7C0; margin: 0.3em 3em; padding: 0.3em 0.6em; font-size: 80%; } </style> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5"> SciTE Lua Scripting Extension</font></a> </td> </tr> </table> <h3>Lua Scripting Extension Notes</h3> The SciTE Lua Scripting Extension uses a copy of Lua 5.1 as its scripting engine. Currently, all of the standard libraries are included, although this list may be trimmed in a future revision. <p> Lua is Copyright (C) 1994-2007 Lua.org, PUC-Rio. The complete Lua license is included in <tt>luaCOPYRIGHT</tt> in the SciTE installation directory. To find more information about Lua, including documentation for the language itself, visit <a href="http://www.lua.org">www.lua.org</a>. </p><p> For more ideas about what Lua can do, you may also want to check out the community portal, <a href="http://lua-users.org/">lua-users.org</a>, <a href="http://lua-users.org/wiki/UsingLuaWithScite">an introduction to using Lua with SciTE,</a> and <a href="http://lua-users.org/wiki/SciteScripts">some example scripts</a>. </p> <h4>SciTE Properties and Lua Event / Command Handlers</h4> <p> The properties ext.lua.startup.script and extension.<i>filepattern</i> can be used to define commands and event handlers that will be called by the SciTE. Other properties beginning with ext.lua may also influence how Lua behaves. See the <a href="SciTEDoc.html">SciTE Documentation</a> for more details on this. </p><p> By defining functions in the startup script or the active extension script, you can tailor SciTE to your needs, adding new behavior and functionality that is tightly integrated. </p><p> To begin, you can handle any many of the events exposed by the <a href="SciTEExtension.html">SciTE Extension Interface</a>. You do this simply by defining functions with the same name as the event. Currently, <tt>OnOpen</tt>, <tt>OnClose</tt>, <tt>OnSwitchFile</tt>, <tt>OnSave</tt>, <tt>OnBeforeSave</tt>, <tt>OnChar</tt>, <tt>OnKey</tt>, <tt>OnSavePointReached</tt>, <tt>OnSavePointLeft</tt>, <tt>OnDwellStart</tt>, <tt>OnDoubleClick</tt>, <tt>OnMarginClick</tt>, and <tt>OnUserListSelection</tt> are supported. </p><p> For some of these events, SciTE will pass one or more arguments to the event handler function: <tt>OnOpen</tt>, <tt>OnClose</tt>, <tt>OnSwitchFile</tt>, <tt>OnSave</tt>, and <tt>OnBeforeSave</tt> will receive the filename of the affected buffer as their first argument. An <tt>OnChar</tt> handler should expect a single-character string argument. An <tt>OnKey</tt> handler should expect an integer keycode and boolean shift, control, and alt arguments. The keycode is currently a platform specific value but this may change in future. <tt>OnDwellStart</tt> will receive the position of the mouse and the word under the mouse as arguments and the word will be empty when the mouse starts moving. <tt>OnUserListSelection</tt> receives two arguments: a number indicating the list type, and a string indicating the selected item text. The other event handlers will not be passed any arguments. </p><p> Event handlers return a boolean value to indicate whether SciTE should continue processing the event. Return a true value to indicate that the event has been fully handled, and that no further handlers should be called. Return a false value to give other extensions a chance to process the same event. In many but not all cases, a well behaved event handler will return false. Remember that, in Lua, the only non-true values are <tt>false</tt> and <tt>nil</tt>. Unlike in C++, Python and many other languages, 0 evaluates to <tt>true</tt>. </p><p> There is one additional event handler, <tt>OnClear</tt>, that is not expressly defined in the Extension interface, but is exposed to Lua. Whenever SciTE re-reads the properties (which occurs every time you switch buffers or open a new file, but can also occur at other times), the Lua Extension removes any globals that were created since the last time properties were read, and restores any globals that were overwritten. Then, if the startup script defines a function <tt>OnClear</tt>, that function will be called so that scripts have a chance to clean up other changes they might have made outside of the Lua global scope (e.g. dynamic properties modified through the props object; see below) and/or to tailor the Lua environment according to local properties for the current buffer. </p><p> After this, SciTE reads the properties and ultimately loads the extension script, if one is defined. However, at the time when the <tt>OnClear</tt> event fires, the extension script is not yet loaded. Thus, <tt>OnClear</tt> can only be defined in the startup script, not in an extension script. </p><p> In addition to event handlers, you can also use define new commands that are available through the Tools menu or through keyboard shortcuts. To specify that a command that will be handled by Lua, specify subsystem 3 for the command. Then, to implement the command using Lua, just define a global function. The command name is the function name. </p><p> You can also use predefined functions like <tt>dofile</tt> and <tt>dostring</tt> as tool commands. </p><p> Anything specified after the command name is passed to the Lua function as a single string argument. An example of a command, using the built-in dofile command, is shown below. </p> <div class="example"> command.name.1.*=Run My Script<br /> command.subsystem.1.*=3<br /> command.1.*=dofile $(SciteDefaultHome)/My Script.lua<br /> </div> <p> Note that the command line is "not" evaluated directly as a Lua script. </p><p> If there is no function matching the command name, no error will be displayed. This is because Lua assumes in this case that the command is meant for some other extension, such as the <a href="SciTEDirector.html">SciTE Director Extension</a>. However, if the command function is found, but fails to execute, an error is reported. </p> <h4>Multiple handlers</h4> <p> <a href="http://lua-users.org/wiki/SciteExtMan">Scite Ext Man</a> can help in more complex applications where you have multiple scripts needing to handle an event. </p> <hr noshade="noshade" width="80%" align="left" /> <h4>Predefined Lua Functions and Objects:</h4> <p> Within Lua scripts you can use the following functions / objects: </p><pre><tt> trace(s) - writes s to the output pane (no prefix, no newlines) dostring(s) - executes s as a Lua string, like Lua 4's dostring editor - the editor pane output - the output pane props - a pseudo-table representing the SciTE properties buffer - a table associated with the current buffer or document scite - a namespace for functions which control SciTE. </tt></pre><p> In addition, all constants defined in Scintilla.iface are exposed as Lua globals variables. Function names are exposed as their block capital equivalents, with the SCI_ prefix. </p><p> All functions and objects defined in the Lua standard library are also available. Although dostring was deprecated in Lua 5, it is restored since some have said it would be useful in tool commands. </p><p> A function <tt>_ALERT()</tt> is also defined to be an alias for the built-in <tt>print()</tt>, which prints the alert message (plus a newline) to the window. This provides a reasonable way for Lua to present error messages to the user. You are free to override <tt>_ALERT</tt> with a different definition if you prefer. </p><p> The props pseudo-table allows you to read or write properties by name using normal Lua table-access semantics, e.g. <tt>props["property.name"]</tt>. As with Lua tables, you can also un-set a property by assigning nil to its key. </p><p> When you assign a value to a property from Lua, this overrides any values specified in the configuration files for that setting. The underlying file properties are not changed. If you later assign nil to the same property from Lua, this removes the run-time setting, allowing any file-based property setting to show through once again. </p><p> The editor and output panes support the following properties and methods: </p><pre><tt> textrange(startPos, endPos) - gets the text in the specified range findtext(text, [flags], [startPos, [endPos]]) - returns the start and end of the first match, or nil if no match - flags can be 0 (the default), or a combination of <a href="http://www.scintilla.org/ScintillaDoc.html#searchFlags">SCFIND constants</a> such as SCFIND_WHOLEWORD, SCFIND_MATCHCASE, and SCFIND_REGEXP match(text, [flags], [startPos]) - returns a generator that allows you to loop over the matches i.e. for m in editor:match(text, flags) do ... end - the match object (i.e. the loop counter m in the above example) supports read-only properties pos, len, and text; and also supports a function replace(replaceText) to support search and replace. - while looping through matches, if the document is modified by any method other than the loop counter's replace method, this may cause the match generator to lose its place. - also, do not attempt to store the match object for later access outside the loop; it will not be useable. append(text) - appends text to the end of the document insert(pos, text) - inserts text at the specified position remove(startPos, endPos) - removes the text in the range </tt></pre><p> Most of the functions defined in Scintilla.iface are also be exposed as pane methods. Those functions having simple parameters (string, boolean, and numeric types) are fully supported. For example, <tt>editor:InsertText(pos, text)</tt> does practically the same thing as <tt>editor:insert(pos, text)</tt>. Functions having a stringresult parameter will include a string in the return value. For both strings and stringresults, if the function is documented as expecting a length as its first parameter, you do not pass the length from Lua. Instead, it is inferred from the context. </p><p> The keymod parameter type has partial support. When an iface function is declared as taking a keymod, the Lua equivalent expects two numbers: first the key code (e.g. <tt>SCK_LEFT</tt> or <tt>string.byte("'")</tt>, and second the modifiers (e.g. <tt>SCMOD_CTRL</tt>). </p><p> Functions that have more complex parameters are not supported. </p><p> Functions that are declared to return a numeric type have the result added to their return value. If the function also has a stringresult, that comes first, followed by the numeric return value. </p><p> Some functions are declared as 'get' or 'set' rather than 'fun' in the iface file. These are generally exposed to Lua as properties, e.g. <tt>editor.TabSize = 8</tt>. Some of the getters and setters also have a parameter. Where possible, these are exposed to Lua as indexed properties, e.g. <tt>editor.StyleBold[SCE_PROPS_DEFAULT] = true</tt>. However, if an iface function is declared as get / set but cannot be mapped to a Lua property, it is exposed as a Lua function instead. </p><p> The possible Scintilla calls are listed as the <a href="http://www.scintilla.org/PaneAPI.html">Pane API</a> and in <a href="http://scite-files.googlecode.com/svn-history/trunk/extras/SciTELua.api">API file format.</a> The Scintilla API is described in <a href="http://www.scintilla.org/ScintillaDoc.html">ScintillaDoc</a>. </p> <p> The <tt>scite</tt> namespace includes the following functions: </p><pre><tt> scite.Open(filename) - opens a file in a new buffer - activates the file's buffer if it is already opened. scite.SendEditor(SCI_constant, ...) - sends a message to the editor pane - equivalent to the corresponding iface function or property scite.SendOutput(SCI_constant, ...) - sends a message to the output pane scite.ConstantName(number) - returns the symbolic name of a Scintilla / SciTE constant scite.MenuCommand(IDM_constant) - equivalent to the corresponding IDM_ command defined in SciTE.h </tt></pre><p> <tt>Open</tt> requires special care. When the buffer changes in SciTE, the Lua global namespace is reset to its initial state, and any extension script associated with the new buffer is loaded. Thus, when you call Open, this may change the environment in which your current script is running. When possible, you can avoid confusion by simply returning after scite.Open, but when that is not possible, just bear in mind that there are side effects. Local variables, unlike globals, will be retained after the buffer change until your script returns. </p><p> The <tt>SendEditor</tt> and <tt>SendOuput</tt> functions duplicate the functionality of the editor and output objects, providing access to these through an interface that is more familiar to Scintilla C++ developers. This may be useful for prototyping C++ code using Lua. Internally, <tt>SendEditor</tt> and <tt>SendOutput</tt> are translated to the corresponding iface function or property, so their arguments and return types are identical. (Although the calling convention for properties is obviously different.) </p><p> The <tt>ConstantName</tt> function may be useful when generating debug messages, or if extending the SciTE LuaExtension to support macro recording. </p><p> The <tt>MenuCommand</tt> function enables usage of SciTE's menu commands as defined in SciTE.h. </p> <h4>Scripting user interfaces with strips</h4> <p>Simple user interfaces may be defined from Lua as strips similar to the find and replace strips. An example looks like<br /> <img src="http://scintilla.org/UserStrip.png"></img></p> <p>Strips are shown with StripShow which takes a string describing the user interface then builds and displays it as a strip at the bottom of the application window. There are 5 supported elements: labels, editable text, combo boxes, buttons and default buttons. These are surrounded by different indicator strings: ' for labels; [] for editable text; {} for combo boxes; () for buttons; and (()) for default buttons. There can also be a newline to start a new line and a ! to show a close box on Windows only.</p> <p>A default button looks like ((OK)) and can be triggered by pressing the Enter key. Buttons may include accelerator keys prefixed with &. On Windows and GTK+ but not OS X, labels may also define accelerator keys which cause focus to move to the next element which accepts focus. Literal ampersands are defined with &&. For example, the code<pre><tt> scite.StripShow("!'Explanation:'{}(&Search)\n'Name:'[Name](OK)(Cancel)") </tt></pre> shows the strip displayed in the picture. The strip can be closed by passing an empty string.</p> <p>On GTK+ a table is used for layout and the approach was copied to the other platforms. It is not yet as capable on the other platforms yet as on GTK+ - columns containing editable text and combo boxes can expand and other columns are fixed to the their natural width of their widest element.</p> <p>Events from the user are communicated back to the script through the OnStrip function which takes an element number (starting at 0 and including static text elements) and a change type (clicked=1, change=2, focusIn=3, focusOut=4). 'clicked' is for button presses, 'change' for changes to editable text or the editable text part of a combo boxes and 'focusIn' and 'focusOut' are when the user moves focus between elements. The value of editable text or combo boxes can be retrieved with StripValue(element).</p> <p>There are some bugs and limitations with these events currently. Focus events may not occur or may occur only when text is edited. Selecting an item from the list in a combo box may not send a 'change' event.</p> <p>The editable part of combo boxes and editable text can be set with StripSet(element, value) and the list part of combo boxes can be set with StripSetList(element, value) where the items in 'value' are separated with new lines.</p> <h4>Lua 5.1</h4> <pre> Despite some of the big changes in Lua 5.1 dealing with changes in the language, most of the compatibility options have been turned on. Compatibilities: - table.getn still works, but the '#' operator should be used - Lua 5.0's varargs are still available - Lua 5.0's math.mod is still available, as well as 5.1's math.fmod - Lua 5.0's string.gfind is still available, as well as 5.1's string.gmatch - [C API] Lua 5.0's luaL_openlib behavior is still available Changes: - table.setn was deprecated - loadlib was moved into the package table (package.loadlib) - Lua 5.0's long string nesting throws an error </pre> <hr noshade="noshade" width="80%" align="left" /> <h4>Disabling Lua</h4> <p> Lua is currently loaded just-in-time, before it is first used. The ways that Lua can become are through the ext.lua.startup.script property, by naming a lua file named in the extension.<i>filepattern</i> property, or by using the extension mechanism to define tool commands (i.e. subsystem 3). If you do not do any of these things, the Lua scripting engine is not loaded, and for all practical purposes, SciTE should behave as it did before Lua was added. </p><p> Nevertheless, it is still possible to build SciTE without the Lua support. To do this, simply define the variable <tt>NO_LUA</tt> when you build it, e.g. for MSVC, <tt>nmake -f scite.mak -DNO_LUA</tt>; or with GNU tools, <tt>make NO_LUA=1</tt>. </p> </body> </html> |
Added doc/SciTERegEx.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title> SciTE Regular Expressions </title> <style type="text/css"> h3 { background-color: #FEC; } .ref { color: #80C; } code { font-weight: bold; } dt { margin-top: 15px; } </style> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5"> Regular Expressions</font></a> </td> </tr> </table> <h2> Regular Expressions in SciTE </h2> <h3>Purpose</h3> <p> Regular expressions can be used for searching for patterns rather than literals. For example, it is possible to search for variables in SciTE property files, which look like $(name.subname) with the regular expression:<br /> <code>\$([a-z.]+)</code> (or <code>\$\([a-z.]+\)</code> in posix mode). </p> <p> Replacement with regular expressions allows complex transformations with the use of tagged expressions. For example, pairs of numbers separated by a ',' could be reordered by replacing the regular expression:<br /> <code>\([0-9]+\),\([0-9]+\)</code> (or <code>([0-9]+),([0-9]+)</code> in posix mode, or even <code>(\d+),(\d+)</code>)<br /> with:<br /> <code>\2,\1</code> </p> <h3>Syntax</h3> <p> Regular expression syntax depends on a parameter: find.replace.regexp.posix<br /> If set to 0, syntax uses the old Unix style where <code>\(</code> and <code>\)</code> mark capturing sections while <code>(</code> and <code>)</code> are themselves.<br /> If set to 1, syntax uses the more common style where <code>(</code> and <code>)</code> mark capturing sections while <code>\(</code> and <code>\)</code> are plain parentheses. </p> <dl><dt><span class="ref">[1]</span> char</dt> <dd>matches itself, unless it is a special character (metachar): <code>. \ [ ] * + ? ^ $</code> and <code>( )</code> in posix mode. </dd><dt><span class="ref">[2]</span> <code>.</code></dt> <dd>matches any character. </dd><dt><span class="ref">[3]</span> <code>\</code></dt> <dd>matches the character following it, except: <ul><li><code>\a</code>, <code>\b</code>, <code>\f</code>, <code>\n</code>, <code>\r</code>, <code>\t</code>, <code>\v</code> match the corresponding C escape char, respectively BEL, BS, FF, LF, CR, TAB and VT;<br /> Note that <code>\r</code> and <code>\n</code> are never matched because in Scintilla, regular expression searches are made line per line (stripped of end-of-line chars). </li><li>if not in posix mode, when followed by a left or right round bracket (see <span class="ref">[8]</span>); </li><li>when followed by a digit 1 to 9 (see <span class="ref">[9]</span>); </li><li>when followed by a left or right angle bracket (see <span class="ref">[10]</span>); </li><li>when followed by d, D, s, S, w or W (see <span class="ref">[11]</span>); </li><li>when followed by x and two hexa digits (see <span class="ref">[12]</span>); </li></ul> Backslash is used as an escape character for all other meta-characters, and itself. </dd><dt><span class="ref">[4]</span> <code>[</code>set<code>]</code></dt> <dd>matches one of the characters in the set. If the first character in the set is <code>^</code>, it matches the characters NOT in the set, i.e. complements the set. A shorthand <code>S-E</code> (start dash end) is used to specify a set of characters S up to E, inclusive. The special characters <code>]</code> and <code>-</code> have no special meaning if they appear as the first chars in the set. To include both, put - first: <code>[-]A-Z]</code> (or just backslash them). <table><tr><td>example</td><td>match</td></tr> <tr><td><code>[-]|]</code></td><td>matches these 3 chars,</td></tr> <tr><td><code>[]-|]</code></td><td>matches from ] to | chars</td></tr> <tr><td><code>[a-z]</code></td><td>any lowercase alpha</td></tr> <tr><td><code>[^-]]</code></td><td>any char except - and ]</td></tr> <tr><td><code>[^A-Z]</code></td><td>any char except uppercase alpha</td></tr> <tr><td><code>[a-zA-Z]</code></td><td>any alpha</td></tr> </table> </dd><dt><span class="ref">[5]</span> <code>*</code></dt> <dd>any regular expression form <span class="ref">[1]</span> to <span class="ref">[4]</span> (except <span class="ref">[8]</span>, <span class="ref">[9]</span> and <span class="ref">[10]</span> forms of <span class="ref">[3]</span>), followed by closure char (<code>*</code>) matches zero or more matches of that form. </dd><dt><span class="ref">[6]</span> <code>+</code></dt> <dd>same as <span class="ref">[5]</span>, except it matches one or more. </dd><dt><span class="ref">[5-6]</span></dt> <dd>Both <span class="ref">[5]</span> and <span class="ref">[6]</span> are greedy (they match as much as possible) unless they are followed by the 'lazy' quantifier (<code>?</code>) in which case both <span class="ref">[5]</span> and <span class="ref">[6]</span> try to match as little as possible. </dd><dt><span class="ref">[7]</span> <code>?</code></dt> <dd>same as <span class="ref">[5]</span>, except it matches zero or one. </dd><dt><span class="ref">[8]</span></dt> <dd>a regular expression in the form <span class="ref">[1]</span> to <span class="ref">[13]</span>, enclosed as <code>\(<i>form</i>\)</code> (or <code>(<i>form</i>)</code> with posix flag) matches what <i>form</i> matches. The enclosure creates a set of tags, used for <span class="ref">[9]</span> and for pattern substitution. The tagged forms are numbered starting from 1. </dd><dt><span class="ref">[9]</span></dt> <dd>a <code>\</code> followed by a digit 1 to 9 matches whatever a previously tagged regular expression (<span class="ref">[8]</span>) matched. </dd><dt><span class="ref">[10]</span> <code>\< \></code></dt> <dd>a regular expression starting with a <code>\<</code> construct and/or ending with a <code>\></code> construct, restricts the pattern matching to the beginning of a word, and/or the end of a word. A word is defined to be a character string beginning and/or ending with the characters A-Z a-z 0-9 and _. Scintilla extends this definition by user setting. The word must also be preceded and/or followed by any character outside those mentioned. </dd><dt><span class="ref">[11]</span> <code>\l</code></dt> <dd>a backslash followed by d, D, s, S, w or W, becomes a character class (both inside and outside sets []). <ul><li>d: decimal digits </li><li>D: any char except decimal digits </li><li>s: whitespace (space, \t \n \r \f \v) </li><li>S: any char except whitespace (see above) </li><li>w: alphanumeric & underscore (changed by user setting) </li><li>W: any char except alphanumeric & underscore (see above) </li></ul> </dd><dt><span class="ref">[12]</span> <code>\xHH</code></dt> <dd>a backslash followed by x and two hexa digits, becomes the character whose Ascii code is equal to these digits. If not followed by two digits, it is 'x' char itself. </dd><dt><span class="ref">[13]</span></dt> <dd>a composite regular expression xy where x and y are in the form <span class="ref">[1]</span> to <span class="ref">[12]</span> matches the longest match of x followed by a match for y. </dd><dt><span class="ref">[14]</span> <code>^ $</code></dt> <dd>a regular expression starting with a ^ character and/or ending with a $ character, restricts the pattern matching to the beginning of the line, or the end of line. [anchors] Elsewhere in the pattern, ^ and $ are treated as ordinary characters. </dd></dl> <h3>Acknowledgments</h3> <p> Most of this documentation was originally written by Ozan S. Yigit.<br /> Additions by Neil Hodgson and Philippe Lhoste.<br /> All of this document is in the public domain. </p> </body> </html> |
Added doc/SciTEWord.jpg.
cannot compute difference between binary files
Added doc/SciWord.jpg.
cannot compute difference between binary files
Added doc/ScintillaDoc.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 7049 7050 7051 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164 7165 7166 7167 7168 7169 7170 7171 7172 7173 7174 7175 7176 7177 7178 7179 7180 7181 7182 7183 7184 7185 7186 7187 7188 7189 7190 7191 7192 7193 7194 7195 7196 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="HTML Tidy for Windows (vers 1st August 2002), see www.w3.org" /> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Scintilla Documentation</title> <style type="text/css"> <!-- /*<![CDATA[*/ CODE { font-weight: bold; font-family: Consolas,Bitstream Vera Sans Mono,Courier New,monospace; } A:visited { color: blue; } A:hover { text-decoration: underline ! important; } A.message { text-decoration: none; font-weight: bold; font-family: Consolas,Bitstream Vera Sans Mono,Courier New,monospace; } A.toc { text-decoration: none; } A.jump { text-decoration: none; } .S0 { color: #808080; } .S2 { font-family: 'Comic Sans MS'; color: #007F00; font-size: 9pt; } .S3 { font-family: 'Comic Sans MS'; color: #3F703F; font-size: 9pt; } .S4 { color: #007F7F; } .S5 { font-weight: bold; color: #00007F; } .S9 { color: #7F7F00; } .S10 { font-weight: bold; color: #000000; } .S17 { font-family: 'Comic Sans MS'; color: #3060A0; font-size: 9pt; } DIV.highlighted { background: #F7FCF7; border: 1px solid #C0D7C0; margin: 0.3em 3em; padding: 0.3em 0.6em; font-family: 'Verdana'; color: #000000; font-size: 10pt; } .provisional { background: #FFB000; } /*]]>*/ --> </style> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0" summary="Banner"> <tr> <td><img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /></td> <td><a href="index.html" style="color:white;text-decoration:none;font-size:200%">Scintilla</a></td> </tr> </table> <h1>Scintilla Documentation</h1> <p>Last edited 18/January/2013 NH</p> <p>There is <a class="jump" href="Design.html">an overview of the internal design of Scintilla</a>.<br /> <a class="jump" href="ScintillaUsage.html">Some notes on using Scintilla</a>.<br /> <a class="jump" href="Steps.html">How to use the Scintilla Edit Control on Windows</a>.<br /> <a class="jump" href="http://www.scintilla.org/dmapp.zip">A simple sample using Scintilla from C++ on Windows</a>.<br /> <a class="jump" href="http://www.scintilla.org/SciTry.vb">A simple sample using Scintilla from Visual Basic</a>.<br /> <a class="jump" href="http://www.scintilla.org/bait.zip">Bait is a tiny sample using Scintilla on GTK+</a>.<br /> <a class="jump" href="Lexer.txt">A detailed description of how to write a lexer, including a discussion of folding</a>.<br /> <a class="jump" href="http://sphere.sourceforge.net/flik/docs/scintilla-container_lexer.html"> How to implement a lexer in the container</a>.<br /> <a class="jump" href="http://sphere.sourceforge.net/flik/docs/scintilla-folding.html"> How to implement folding</a>.<br /> The <a class="jump" href="SciCoding.html">coding style</a> used in Scintilla and SciTE is worth following if you want to contribute code to Scintilla but is not compulsory.</p> <h2>Introduction</h2> <p>The Windows version of Scintilla is a Windows Control. As such, its primary programming interface is through Windows messages. Early versions of Scintilla emulated much of the API defined by the standard Windows Edit and RichEdit controls but those APIs are now deprecated in favour of Scintilla's own, more consistent API. In addition to messages performing the actions of a normal Edit control, Scintilla allows control of syntax styling, folding, markers, autocompletion and call tips.</p> <p>The GTK+ version also uses messages in a similar way to the Windows version. This is different to normal GTK+ practice but made it easier to implement rapidly.</p> <p>Scintilla does not properly support right-to-left languages like Arabic and Hebrew. While text in these languages may appear correct, it is not possible to interact with this text as is normal with other editing components.</p> <p>This documentation describes the individual messages and notifications used by Scintilla. It does not describe how to link them together to form a useful editor. For now, the best way to work out how to develop using Scintilla is to see how SciTE uses it. SciTE exercises most of Scintilla's facilities.</p> <p>In the descriptions that follow, the messages are described as function calls with zero, one or two arguments. These two arguments are the standard <code>wParam</code> and <code>lParam</code> familiar to Windows programmers. These parameters are integers that are large enough to hold pointers, and the return value is also an integer large enough to contain a pointer. Although the commands only use the arguments described, because all messages have two arguments whether Scintilla uses them or not, it is strongly recommended that any unused arguments are set to 0. This allows future enhancement of messages without the risk of breaking existing code. Common argument types are:</p> <table cellpadding="1" cellspacing="2" border="0" summary="Common argument types"> <tbody valign="top"> <tr> <th align="left">bool</th> <td>Arguments expect the values 0 for <code>false</code> and 1 for <code>true</code>.</td> </tr> <tr> <th align="left">int</th> <td>Arguments are 32-bit signed integers.</td> </tr> <tr> <th align="left">const char *</th> <td>Arguments point at text that is being passed to Scintilla but not modified. The text may be zero terminated or another argument may specify the character count, the description will make this clear.</td> </tr> <tr> <th align="left">char *</th> <td>Arguments point at text buffers that Scintilla will fill with text. In some cases, another argument will tell Scintilla the buffer size. In others, you must make sure that the buffer is big enough to hold the requested text. If a NULL pointer (0) is passed then, for SCI_* calls, the length that should be allocated is returned.</td> </tr> <tr> <th align="left" id="colour">colour</th> <td>Colours are set using the RGB format (Red, Green, Blue). The intensity of each colour is set in the range 0 to 255. If you have three such intensities, they are combined as: red | (green << 8) | (blue << 16). If you set all intensities to 255, the colour is white. If you set all intensities to 0, the colour is black. When you set a colour, you are making a request. What you will get depends on the capabilities of the system and the current screen mode.</td> </tr> <tr> <th align="left" id="alpha">alpha</th> <td>Translucency is set using an alpha value. Alpha ranges from 0 (SC_ALPHA_TRANSPARENT) which is completely transparent to 255 (SC_ALPHA_OPAQUE) which is opaque. The value 256 (SC_ALPHA_NOALPHA) is opaque and uses code that is not alpha-aware and may be faster. Not all platforms support translucency and only some Scintilla features implement translucency. The default alpha value for most features is SC_ALPHA_NOALPHA.</td> </tr> <tr> <th align="left"><unused></th> <td>This is an unused argument. Setting it to 0 will ensure compatibility with future enhancements.</td> </tr> </tbody> </table> <h2 id="MessageCategories">Contents</h2> <table cellpadding="4" cellspacing="2" border="0" summary="Message categories"> <tbody> <tr> <td>o <a class="toc" href="#TextRetrievalAndModification">Text retrieval and modification</a></td> <td>o <a class="toc" href="#Searching">Searching and replacing</a></td> <td>o <a class="toc" href="#Overtype">Overtype</a></td> </tr> <tr> <td>o <a class="toc" href="#CutCopyAndPaste">Cut, copy and paste</a></td> <td>o <a class="toc" href="#ErrorHandling">Error handling</a></td> <td>o <a class="toc" href="#UndoAndRedo">Undo and Redo</a></td> </tr> <tr> <td>o <a class="toc" href="#SelectionAndInformation">Selection and information</a></td> <td>o <a class="toc" href="#MultipleSelectionAndVirtualSpace">Multiple Selection and Virtual Space</a></td> <td>o <a class="toc" href="#ScrollingAndAutomaticScrolling">Scrolling and automatic scrolling</a></td> </tr> <tr> <td>o <a class="toc" href="#WhiteSpace">White space</a></td> <td>o <a class="toc" href="#Cursor">Cursor</a></td> <td>o <a class="toc" href="#MouseCapture">Mouse capture</a></td> </tr> <tr> <td>o <a class="toc" href="#LineEndings">Line endings</a></td> <td>o <a class="toc" href="#Styling">Styling</a></td> <td>o <a class="toc" href="#StyleDefinition">Style definition</a></td> </tr> <tr> <td>o <a class="toc" href="#CaretAndSelectionStyles">Caret, selection, and hotspot styles</a></td> <td>o <a class="toc" href="#Margins">Margins</a></td> <td>o <a class="toc" href="#Annotations">Annotations</a></td> </tr> <tr> <td>o <a class="toc" href="#OtherSettings">Other settings</a></td> <td>o <a class="toc" href="#BraceHighlighting">Brace highlighting</a></td> <td>o <a class="toc" href="#TabsAndIndentationGuides">Tabs and Indentation Guides</a></td> </tr> <tr> <td>o <a class="toc" href="#Markers">Markers</a></td> <td>o <a class="toc" href="#Indicators">Indicators</a></td> <td>o <a class="toc" href="#Autocompletion">Autocompletion</a></td> </tr> <tr> <td>o <a class="toc" href="#UserLists">User lists</a></td> <td>o <a class="toc" href="#CallTips">Call tips</a></td> <td>o <a class="toc" href="#KeyboardCommands">Keyboard commands</a></td> </tr> <tr> <td>o <a class="toc" href="#KeyBindings">Key bindings</a></td> <td>o <a class="toc" href="#PopupEditMenu">Popup edit menu</a></td> <td>o <a class="toc" href="#MacroRecording">Macro recording</a></td> </tr> <tr> <td>o <a class="toc" href="#Printing">Printing</a></td> <td>o <a class="toc" href="#DirectAccess">Direct access</a></td> <td>o <a class="toc" href="#MultipleViews">Multiple views</a></td> </tr> <tr> <td>o <a class="toc" href="#BackgroundLoadSave">Background loading and saving</a></td> <td>o <a class="toc" href="#Folding">Folding</a></td> <td>o <a class="toc" href="#LineWrapping">Line wrapping</a></td> </tr> <tr> <td>o <a class="toc" href="#Zooming">Zooming</a></td> <td>o <a class="toc" href="#LongLines">Long lines</a></td> <td>o <a class="toc" href="#Lexer">Lexer</a></td> </tr> <tr> <td>o <a class="toc" href="#LexerObjects">Lexer objects</a></td> <td>o <a class="toc" href="#Notifications">Notifications</a></td> <td>o <a class="toc" href="#Images">Images</a></td> </tr> <tr> <td>o <a class="toc" href="#GTK">GTK+</a></td> <td>o <a class="toc" href="#ProvisionalMessages"><span class="provisional">Provisional messages</span></a></td> <td>o <a class="toc" href="#DeprecatedMessages">Deprecated messages</a></td> </tr> <tr> <td>o <a class="toc" href="#EditMessagesNeverSupportedByScintilla">Edit messages never supported by Scintilla</a></td> <td>o <a class="toc" href="#BuildingScintilla">Building Scintilla</a></td> </tr> </tbody> </table> <p>Messages with names of the form <code>SCI_SETxxxxx</code> often have a companion <code>SCI_GETxxxxx</code>. To save tedious repetition, if the <code>SCI_GETxxxxx</code> message returns the value set by the <code>SCI_SETxxxxx</code> message, the <code>SET</code> routine is described and the <code>GET</code> routine is left to your imagination.</p> <h2 id="TextRetrievalAndModification">Text retrieval and modification</h2> <p>Each byte in a Scintilla document is followed by an associated byte of styling information. The combination of a character byte and a style byte is called a cell. Style bytes are interpreted an index into an array of styles. Style bytes may be split into an index and a set of indicator bits but this use is discouraged and indicators should now use <a class="message" href ="#SCI_INDICATORFILLRANGE">SCI_INDICATORFILLRANGE</a> and related calls. The default split is with the index in the low 5 bits and 3 high bits as <a class="jump" href="#Indicators">indicators</a>. This allows 32 fundamental styles, which is enough for most languages, and three independent indicators so that, for example, syntax errors, deprecated names and bad indentation could all be displayed at once. The number of bits used for styles can be altered with <a class="message" href="#SCI_SETSTYLEBITS"><code>SCI_SETSTYLEBITS</code></a> up to a maximum of 8 bits. The remaining bits can be used for indicators.</p> <p>In this document, 'character' normally refers to a byte even when multi-byte characters are used. Lengths measure the numbers of bytes, not the amount of characters in those bytes.</p> <p>Positions within the Scintilla document refer to a character or the gap before that character. The first character in a document is 0, the second 1 and so on. If a document contains <code>nLen</code> characters, the last character is numbered <code>nLen</code>-1. The caret exists between character positions and can be located from before the first character (0) to after the last character (<code>nLen</code>).</p> <p>There are places where the caret can not go where two character bytes make up one character. This occurs when a DBCS character from a language like Japanese is included in the document or when line ends are marked with the CP/M standard of a carriage return followed by a line feed. The <code>INVALID_POSITION</code> constant (-1) represents an invalid position within the document.</p> <p>All lines of text in Scintilla are the same height, and this height is calculated from the largest font in any current style. This restriction is for performance; if lines differed in height then calculations involving positioning of text would require the text to be styled first.</p> <code><a class="message" href="#SCI_GETTEXT">SCI_GETTEXT(int length, char *text)</a><br /> <a class="message" href="#SCI_SETTEXT">SCI_SETTEXT(<unused>, const char *text)</a><br /> <a class="message" href="#SCI_SETSAVEPOINT">SCI_SETSAVEPOINT</a><br /> <a class="message" href="#SCI_GETLINE">SCI_GETLINE(int line, char *text)</a><br /> <a class="message" href="#SCI_REPLACESEL">SCI_REPLACESEL(<unused>, const char *text)</a><br /> <a class="message" href="#SCI_SETREADONLY">SCI_SETREADONLY(bool readOnly)</a><br /> <a class="message" href="#SCI_GETREADONLY">SCI_GETREADONLY</a><br /> <a class="message" href="#SCI_GETTEXTRANGE">SCI_GETTEXTRANGE(<unused>, Sci_TextRange *tr)</a><br /> <a class="message" href="#SCI_ALLOCATE">SCI_ALLOCATE(int bytes, <unused>)</a><br /> <a class="message" href="#SCI_ADDTEXT">SCI_ADDTEXT(int length, const char *s)</a><br /> <a class="message" href="#SCI_ADDSTYLEDTEXT">SCI_ADDSTYLEDTEXT(int length, cell *s)</a><br /> <a class="message" href="#SCI_APPENDTEXT">SCI_APPENDTEXT(int length, const char *s)</a><br /> <a class="message" href="#SCI_INSERTTEXT">SCI_INSERTTEXT(int pos, const char *text)</a><br /> <a class="message" href="#SCI_CLEARALL">SCI_CLEARALL</a><br /> <a class="message" href="#SCI_DELETERANGE">SCI_DELETERANGE(int pos, int deleteLength)</a><br /> <a class="message" href="#SCI_CLEARDOCUMENTSTYLE">SCI_CLEARDOCUMENTSTYLE</a><br /> <a class="message" href="#SCI_GETCHARAT">SCI_GETCHARAT(int position)</a><br /> <a class="message" href="#SCI_GETSTYLEAT">SCI_GETSTYLEAT(int position)</a><br /> <a class="message" href="#SCI_GETSTYLEDTEXT">SCI_GETSTYLEDTEXT(<unused>, Sci_TextRange *tr)</a><br /> <a class="message" href="#SCI_SETSTYLEBITS">SCI_SETSTYLEBITS(int bits)</a><br /> <a class="message" href="#SCI_GETSTYLEBITS">SCI_GETSTYLEBITS</a><br /> <a class="message" href="#SCI_RELEASEALLEXTENDEDSTYLES">SCI_RELEASEALLEXTENDEDSTYLES</a><br /> <a class="message" href="#SCI_ALLOCATEEXTENDEDSTYLES">SCI_ALLOCATEEXTENDEDSTYLES(int numberStyles)</a><br /> <a class="message" href="#SCI_TARGETASUTF8">SCI_TARGETASUTF8(<unused>, char *s)</a><br /> <a class="message" href="#SCI_ENCODEDFROMUTF8">SCI_ENCODEDFROMUTF8(const char *utf8, char *encoded)</a><br /> <a class="message" href="#SCI_SETLENGTHFORENCODE">SCI_SETLENGTHFORENCODE(int bytes)</a><br /> </code> <p><b id="SCI_GETTEXT">SCI_GETTEXT(int length, char *text)</b><br /> This returns <code>length</code>-1 characters of text from the start of the document plus one terminating 0 character. To collect all the text in a document, use <code>SCI_GETLENGTH</code> to get the number of characters in the document (<code>nLen</code>), allocate a character buffer of length <code>nLen+1</code> bytes, then call <code>SCI_GETTEXT(nLen+1, char *text)</code>. If the text argument is 0 then the length that should be allocated to store the entire document is returned. If you then save the text, you should use <code>SCI_SETSAVEPOINT</code> to mark the text as unmodified.</p> <p>See also: <code><a class="message" href="#SCI_GETSELTEXT">SCI_GETSELTEXT</a>, <a class="message" href="#SCI_GETCURLINE">SCI_GETCURLINE</a>, <a class="message" href="#SCI_GETLINE">SCI_GETLINE</a>, <a class="message" href="#SCI_GETSTYLEDTEXT">SCI_GETSTYLEDTEXT</a>, <a class="message" href="#SCI_GETTEXTRANGE">SCI_GETTEXTRANGE</a></code></p> <p><b id="SCI_SETTEXT">SCI_SETTEXT(<unused>, const char *text)</b><br /> This replaces all the text in the document with the zero terminated text string you pass in.</p> <p><b id="SCI_SETSAVEPOINT">SCI_SETSAVEPOINT</b><br /> This message tells Scintilla that the current state of the document is unmodified. This is usually done when the file is saved or loaded, hence the name "save point". As Scintilla performs undo and redo operations, it notifies the container that it has entered or left the save point with <code><a class="message" href="#SCN_SAVEPOINTREACHED">SCN_SAVEPOINTREACHED</a></code> and <code><a class="message" href="#SCN_SAVEPOINTLEFT">SCN_SAVEPOINTLEFT</a></code> <a class="jump" href="#Notifications">notification messages</a>, allowing the container to know if the file should be considered dirty or not.</p> <p>See also: <code><a class="message" href="#SCI_EMPTYUNDOBUFFER">SCI_EMPTYUNDOBUFFER</a>, <a class="message" href="#SCI_GETMODIFY">SCI_GETMODIFY</a></code></p> <p><b id="SCI_GETLINE">SCI_GETLINE(int line, char *text)</b><br /> This fills the buffer defined by text with the contents of the nominated line (lines start at 0). The buffer is not terminated by a 0 character. It is up to you to make sure that the buffer is long enough for the text, use <a class="message" href="#SCI_LINELENGTH"><code>SCI_LINELENGTH(int line)</code></a>. The returned value is the number of characters copied to the buffer. The returned text includes any end of line characters. If you ask for a line number outside the range of lines in the document, 0 characters are copied. If the text argument is 0 then the length that should be allocated to store the entire line is returned.</p> <p>See also: <code><a class="message" href="#SCI_GETCURLINE">SCI_GETCURLINE</a>, <a class="message" href="#SCI_GETSELTEXT">SCI_GETSELTEXT</a>, <a class="message" href="#SCI_GETTEXTRANGE">SCI_GETTEXTRANGE</a>, <a class="message" href="#SCI_GETSTYLEDTEXT">SCI_GETSTYLEDTEXT</a>, <a class="message" href="#SCI_GETTEXT">SCI_GETTEXT</a></code></p> <p><b id="SCI_REPLACESEL">SCI_REPLACESEL(<unused>, const char *text)</b><br /> The currently selected text between the <a class="jump" href="#SelectionAndInformation">anchor and the current position</a> is replaced by the 0 terminated text string. If the anchor and current position are the same, the text is inserted at the caret position. The caret is positioned after the inserted text and the caret is scrolled into view.</p> <p><b id="SCI_SETREADONLY">SCI_SETREADONLY(bool readOnly)</b><br /> <b id="SCI_GETREADONLY">SCI_GETREADONLY</b><br /> These messages set and get the read-only flag for the document. If you mark a document as read only, attempts to modify the text cause the <a class="message" href="#SCN_MODIFYATTEMPTRO"><code>SCN_MODIFYATTEMPTRO</code></a> notification.</p> <p><b id="SCI_GETTEXTRANGE">SCI_GETTEXTRANGE(<unused>, <a class="jump" href="#Sci_TextRange">Sci_TextRange</a> *tr)</b><br /> This collects the text between the positions <code>cpMin</code> and <code>cpMax</code> and copies it to <code>lpstrText</code> (see <code>struct Sci_TextRange</code> in <code>Scintilla.h</code>). If <code>cpMax</code> is -1, text is returned to the end of the document. The text is 0 terminated, so you must supply a buffer that is at least 1 character longer than the number of characters you wish to read. The return value is the length of the returned text not including the terminating 0.</p> <p>See also: <code><a class="message" href="#SCI_GETSELTEXT">SCI_GETSELTEXT</a>, <a class="message" href="#SCI_GETLINE">SCI_GETLINE</a>, <a class="message" href="#SCI_GETCURLINE">SCI_GETCURLINE</a>, <a class="message" href="#SCI_GETSTYLEDTEXT">SCI_GETSTYLEDTEXT</a>, <a class="message" href="#SCI_GETTEXT">SCI_GETTEXT</a></code></p> <p><b id="SCI_GETSTYLEDTEXT">SCI_GETSTYLEDTEXT(<unused>, <a class="jump" href="#Sci_TextRange">Sci_TextRange</a> *tr)</b><br /> This collects styled text into a buffer using two bytes for each cell, with the character at the lower address of each pair and the style byte at the upper address. Characters between the positions <code>cpMin</code> and <code>cpMax</code> are copied to <code>lpstrText</code> (see <code>struct Sci_TextRange</code> in <code>Scintilla.h</code>). Two 0 bytes are added to the end of the text, so the buffer that <code>lpstrText</code> points at must be at least <code>2*(cpMax-cpMin)+2</code> bytes long. No check is made for sensible values of <code>cpMin</code> or <code>cpMax</code>. Positions outside the document return character codes and style bytes of 0.</p> <p>See also: <code><a class="message" href="#SCI_GETSELTEXT">SCI_GETSELTEXT</a>, <a class="message" href="#SCI_GETLINE">SCI_GETLINE</a>, <a class="message" href="#SCI_GETCURLINE">SCI_GETCURLINE</a>, <a class="message" href="#SCI_GETTEXTRANGE">SCI_GETTEXTRANGE</a>, <a class="message" href="#SCI_GETTEXT">SCI_GETTEXT</a></code></p> <p><b id="SCI_ALLOCATE">SCI_ALLOCATE(int bytes, <unused>)</b><br /> Allocate a document buffer large enough to store a given number of bytes. The document will not be made smaller than its current contents.</p> <p><b id="SCI_ADDTEXT">SCI_ADDTEXT(int length, const char *s)</b><br /> This inserts the first <code>length</code> characters from the string <code>s</code> at the current position. This will include any 0's in the string that you might have expected to stop the insert operation. The current position is set at the end of the inserted text, but it is not scrolled into view.</p> <p><b id="SCI_ADDSTYLEDTEXT">SCI_ADDSTYLEDTEXT(int length, cell *s)</b><br /> This behaves just like <code>SCI_ADDTEXT</code>, but inserts styled text.</p> <p><b id="SCI_APPENDTEXT">SCI_APPENDTEXT(int length, const char *s)</b><br /> This adds the first <code>length</code> characters from the string <code>s</code> to the end of the document. This will include any 0's in the string that you might have expected to stop the operation. The current selection is not changed and the new text is not scrolled into view.</p> <p><b id="SCI_INSERTTEXT">SCI_INSERTTEXT(int pos, const char *text)</b><br /> This inserts the zero terminated <code>text</code> string at position <code>pos</code> or at the current position if <code>pos</code> is -1. If the current position is after the insertion point then it is moved along with its surrounding text but no scrolling is performed.</p> <p><b id="SCI_CLEARALL">SCI_CLEARALL</b><br /> Unless the document is read-only, this deletes all the text.</p> <p><b id="SCI_DELETERANGE">SCI_DELETERANGE(int pos, int deleteLength)</b><br /> Deletes a range of text in the document.</p> <p><b id="SCI_CLEARDOCUMENTSTYLE">SCI_CLEARDOCUMENTSTYLE</b><br /> When wanting to completely restyle the document, for example after choosing a lexer, the <code>SCI_CLEARDOCUMENTSTYLE</code> can be used to clear all styling information and reset the folding state.</p> <p><b id="SCI_GETCHARAT">SCI_GETCHARAT(int pos)</b><br /> This returns the character at <code>pos</code> in the document or 0 if <code>pos</code> is negative or past the end of the document.</p> <p><b id="SCI_GETSTYLEAT">SCI_GETSTYLEAT(int pos)</b><br /> This returns the style at <code>pos</code> in the document, or 0 if <code>pos</code> is negative or past the end of the document.</p> <p><b id="SCI_SETSTYLEBITS">SCI_SETSTYLEBITS(int bits)</b><br /> <b id="SCI_GETSTYLEBITS">SCI_GETSTYLEBITS</b><br /> This pair of routines sets and reads back the number of bits in each cell to use for styling, to a maximum of 8 style bits. The remaining bits can be used as indicators. The standard setting is <code>SCI_SETSTYLEBITS(5)</code>. The number of styling bits needed by the current lexer can be found with <a class="message" href="#SCI_GETSTYLEBITSNEEDED">SCI_GETSTYLEBITSNEEDED</a>.</p> <p><b id="SCI_RELEASEALLEXTENDEDSTYLES">SCI_RELEASEALLEXTENDEDSTYLES</b><br /> <b id="SCI_ALLOCATEEXTENDEDSTYLES">SCI_ALLOCATEEXTENDEDSTYLES(int numberStyles)</b><br /> Extended styles are used for features like textual margins and annotations as well as internally by Scintilla. They are outside the range 0..255 used for the styles bytes associated with document bytes. These functions manage the use of extended styles to ensures that components cooperate in defining styles. <code>SCI_RELEASEALLEXTENDEDSTYLES</code> releases any extended styles allocated by the container. <code>SCI_ALLOCATEEXTENDEDSTYLES</code> allocates a range of style numbers after the byte style values and returns the number of the first allocated style. Ranges for margin and annotation styles should be allocated before calling <a class="message" href="#SCI_MARGINSETSTYLEOFFSET">SCI_MARGINSETSTYLEOFFSET</a> or <a class="message" href="#SCI_ANNOTATIONSETSTYLEOFFSET">SCI_ANNOTATIONSETSTYLEOFFSET</a>.</p> <p><b id="Sci_TextRange">Sci_TextRange</b> and <b id="Sci_CharacterRange">Sci_CharacterRange</b><br /> These structures are defined to be exactly the same shape as the Win32 <code>TEXTRANGE</code> and <code>CHARRANGE</code>, so that older code that treats Scintilla as a RichEdit will work.</p> <pre> struct Sci_CharacterRange { long cpMin; long cpMax; }; struct Sci_TextRange { struct Sci_CharacterRange chrg; char *lpstrText; }; </pre> <h3 id="EncodedAccess">GTK+-specific: Access to encoded text</h3> <p><b id="SCI_TARGETASUTF8">SCI_TARGETASUTF8(<unused>, char *s)</b><br /> This method retrieves the value of the target encoded as UTF-8 which is the default encoding of GTK+ so is useful for retrieving text for use in other parts of the user interface, such as find and replace dialogs. The length of the encoded text in bytes is returned. </p> <p><b id="SCI_ENCODEDFROMUTF8">SCI_ENCODEDFROMUTF8(const char *utf8, char *encoded)</b><br /> <b id="SCI_SETLENGTHFORENCODE">SCI_SETLENGTHFORENCODE(int bytes)</b><br /> <code>SCI_ENCODEDFROMUTF8</code> converts a UTF-8 string into the document's encoding which is useful for taking the results of a find dialog, for example, and receiving a string of bytes that can be searched for in the document. Since the text can contain nul bytes, the <code>SCI_SETLENGTHFORENCODE</code> method can be used to set the length that will be converted. If set to -1, the length is determined by finding a nul byte. The length of the converted string is returned. </p> <h2 id="Searching">Searching</h2> <p> There are methods to search for text and for regular expressions. The regular expression support is limited and should only be used for simple cases and initial development. A different regular expression library can be <a class="jump" href="#AlternativeRegEx">integrated into Scintilla</a> or can be called from the container using direct access to the buffer contents through <a class="message" href="#SCI_GETCHARACTERPOINTER">SCI_GETCHARACTERPOINTER</a>. </p> <code><a class="message" href="#SCI_FINDTEXT">SCI_FINDTEXT(int flags, Sci_TextToFind *ttf)</a><br /> <a class="message" href="#SCI_SEARCHANCHOR">SCI_SEARCHANCHOR</a><br /> <a class="message" href="#SCI_SEARCHNEXT">SCI_SEARCHNEXT(int searchFlags, const char *text)</a><br /> <a class="message" href="#SCI_SEARCHPREV">SCI_SEARCHPREV(int searchFlags, const char *text)</a><br /> <a class="jump" href="#SearchAndReplaceUsingTheTarget">Search and replace using the target</a><br /> </code> <p><b id="searchFlags"><code>searchFlags</code></b><br /> Several of the search routines use flag options, which include a simple regular expression search. Combine the flag options by adding them:</p> <table border="0" summary="Search flags"> <tbody> <tr> <td><code>SCFIND_MATCHCASE</code></td> <td>A match only occurs with text that matches the case of the search string.</td> </tr> <tr> <td><code>SCFIND_WHOLEWORD</code></td> <td>A match only occurs if the characters before and after are not word characters.</td> </tr> <tr> <td><code>SCFIND_WORDSTART</code></td> <td>A match only occurs if the character before is not a word character.</td> </tr> <tr> <td><code>SCFIND_REGEXP</code></td> <td>The search string should be interpreted as a regular expression.</td> </tr> <tr> <td><code>SCFIND_POSIX</code></td> <td>Treat regular expression in a more POSIX compatible manner by interpreting bare ( and ) for tagged sections rather than \( and \).</td> </tr> </tbody> </table> <p>You can search backwards to find the previous occurrence of a search string by setting the end of the search range before the start.</p> <p>In a regular expression, special characters interpreted are:</p> <table border="0" summary="Regular expression synopsis"> <tbody> <tr> <td><code>.</code></td> <td>Matches any character</td> </tr> <tr> <td><code>\(</code></td> <td>This marks the start of a region for tagging a match.</td> </tr> <tr> <td><code>\)</code></td> <td>This marks the end of a tagged region.</td> </tr> <tr> <td><code>\n</code></td> <td>Where <code>n</code> is 1 through 9 refers to the first through ninth tagged region when replacing. For example, if the search string was <code>Fred\([1-9]\)XXX</code> and the replace string was <code>Sam\1YYY</code>, when applied to <code>Fred2XXX</code> this would generate <code>Sam2YYY</code>. <code>\0</code> refers to all of the matching text.</td> </tr> <tr> <td><code>\<</code></td> <td>This matches the start of a word using Scintilla's definitions of words.</td> </tr> <tr> <td><code>\></code></td> <td>This matches the end of a word using Scintilla's definition of words.</td> </tr> <tr> <td><code>\x</code></td> <td>This allows you to use a character x that would otherwise have a special meaning. For example, \[ would be interpreted as [ and not as the start of a character set.</td> </tr> <tr> <td><code>[...]</code></td> <td>This indicates a set of characters, for example, [abc] means any of the characters a, b or c. You can also use ranges, for example [a-z] for any lower case character.</td> </tr> <tr> <td><code>[^...]</code></td> <td>The complement of the characters in the set. For example, [^A-Za-z] means any character except an alphabetic character.</td> </tr> <tr> <td><code>^</code></td> <td>This matches the start of a line (unless used inside a set, see above).</td> </tr> <tr> <td><code>$</code></td> <td>This matches the end of a line.</td> </tr> <tr> <td><code>*</code></td> <td>This matches 0 or more times. For example, <code>Sa*m</code> matches <code>Sm</code>, <code>Sam</code>, <code>Saam</code>, <code>Saaam</code> and so on.</td> </tr> <tr> <td><code>+</code></td> <td>This matches 1 or more times. For example, <code>Sa+m</code> matches <code>Sam</code>, <code>Saam</code>, <code>Saaam</code> and so on.</td> </tr> </tbody> </table> <p>Regular expressions will only match ranges within a single line, never matching over multiple lines.</p> <p><b id="SCI_FINDTEXT">SCI_FINDTEXT(int searchFlags, <a class="jump" href="#Sci_TextToFind">Sci_TextToFind</a> *ttf)</b><br /> This message searches for text in the document. It does not use or move the current selection. The <a class="jump" href="#searchFlags"><code>searchFlags</code></a> argument controls the search type, which includes regular expression searches.</p> <p>The <code>Sci_TextToFind</code> structure is defined in <code>Scintilla.h</code>; set <code>chrg.cpMin</code> and <code>chrg.cpMax</code> with the range of positions in the document to search. You can search backwards by setting <code>chrg.cpMax</code> less than <code>chrg.cpMin</code>. Set the <code>lpstrText</code> member of <code>Sci_TextToFind</code> to point at a zero terminated text string holding the search pattern. If your language makes the use of <code>Sci_TextToFind</code> difficult, you should consider using <code>SCI_SEARCHINTARGET</code> instead.</p> <p>The return value is -1 if the search fails or the position of the start of the found text if it succeeds. The <code>chrgText.cpMin</code> and <code>chrgText.cpMax</code> members of <code>Sci_TextToFind</code> are filled in with the start and end positions of the found text.</p> <p>See also: <code><a class="message" href="#SCI_SEARCHINTARGET">SCI_SEARCHINTARGET</a></code></p> <p><b id="Sci_TextToFind">Sci_TextToFind</b><br /> This structure is defined to have exactly the same shape as the Win32 structure <code>FINDTEXTEX</code> for old code that treated Scintilla as a RichEdit control.</p> <pre> struct Sci_TextToFind { struct <a class="jump" href="#Sci_CharacterRange">Sci_CharacterRange</a> chrg; // range to search char *lpstrText; // the search pattern (zero terminated) struct Sci_CharacterRange chrgText; // returned as position of matching text }; </pre> <p><b id="SCI_SEARCHANCHOR">SCI_SEARCHANCHOR</b><br /> <b id="SCI_SEARCHNEXT">SCI_SEARCHNEXT(int searchFlags, const char *text)</b><br /> <b id="SCI_SEARCHPREV">SCI_SEARCHPREV(int searchFlags, const char *text)</b><br /> These messages provide relocatable search support. This allows multiple incremental interactive searches to be macro recorded while still setting the selection to found text so the find/select operation is self-contained. These three messages send <a class="message" href="#SCN_MACRORECORD"><code>SCN_MACRORECORD</code></a> <a class="jump" href="#Notifications">notifications</a> if macro recording is enabled.</p> <p><code>SCI_SEARCHANCHOR</code> sets the search start point used by <code>SCI_SEARCHNEXT</code> and <code>SCI_SEARCHPREV</code> to the start of the current selection, that is, the end of the selection that is nearer to the start of the document. You should always call this before calling either of <code>SCI_SEARCHNEXT</code> or <code>SCI_SEARCHPREV</code>.</p> <p><code>SCI_SEARCHNEXT</code> and <code>SCI_SEARCHPREV</code> search for the next and previous occurrence of the zero terminated search string pointed at by text. The search is modified by the <a class="jump" href="#searchFlags"><code>searchFlags</code></a>. </p> <p>The return value is -1 if nothing is found, otherwise the return value is the start position of the matching text. The selection is updated to show the matched text, but is not scrolled into view.</p> <p>See also: <a class="message" href="#SCI_SEARCHINTARGET"><code>SCI_SEARCHINTARGET</code></a>, <a class="message" href="#SCI_FINDTEXT"><code>SCI_FINDTEXT</code></a></p> <h3 id="SearchAndReplaceUsingTheTarget">Search and replace using the target</h3> <p>Using <a class="message" href="#SCI_REPLACESEL"><code>SCI_REPLACESEL</code></a>, modifications cause scrolling and other visible changes, which may take some time and cause unwanted display updates. If performing many changes, such as a replace all command, the target can be used instead. First, set the target, ie. the range to be replaced. Then call <code>SCI_REPLACETARGET</code> or <code>SCI_REPLACETARGETRE</code>.</p> <p>Searching can be performed within the target range with <code>SCI_SEARCHINTARGET</code>, which uses a counted string to allow searching for null characters. It returns the position of the start of the matching text range or -1 for failure, in which case the target is not moved. The flags used by <code>SCI_SEARCHINTARGET</code> such as <code>SCFIND_MATCHCASE</code>, <code>SCFIND_WHOLEWORD</code>, <code>SCFIND_WORDSTART</code>, and <code>SCFIND_REGEXP</code> can be set with <code>SCI_SETSEARCHFLAGS</code>. <code>SCI_SEARCHINTARGET</code> may be simpler for some clients to use than <a class="message" href="#SCI_FINDTEXT"><code>SCI_FINDTEXT</code></a>, as that requires using a pointer to a structure.</p> <code><a class="message" href="#SCI_SETTARGETSTART">SCI_SETTARGETSTART(int pos)</a><br /> <a class="message" href="#SCI_GETTARGETSTART">SCI_GETTARGETSTART</a><br /> <a class="message" href="#SCI_SETTARGETEND">SCI_SETTARGETEND(int pos)</a><br /> <a class="message" href="#SCI_GETTARGETEND">SCI_GETTARGETEND</a><br /> <a class="message" href="#SCI_TARGETFROMSELECTION">SCI_TARGETFROMSELECTION</a><br /> <a class="message" href="#SCI_SETSEARCHFLAGS">SCI_SETSEARCHFLAGS(int searchFlags)</a><br /> <a class="message" href="#SCI_GETSEARCHFLAGS">SCI_GETSEARCHFLAGS</a><br /> <a class="message" href="#SCI_SEARCHINTARGET">SCI_SEARCHINTARGET(int length, const char *text)</a><br /> <a class="message" href="#SCI_REPLACETARGET">SCI_REPLACETARGET(int length, const char *text)</a><br /> <a class="message" href="#SCI_REPLACETARGETRE">SCI_REPLACETARGETRE(int length, const char *text)</a><br /> <a class="message" href="#SCI_GETTAG">SCI_GETTAG(int tagNumber, char *tagValue)</a><br /> </code> <p><b id="SCI_SETTARGETSTART">SCI_SETTARGETSTART(int pos)</b><br /> <b id="SCI_GETTARGETSTART">SCI_GETTARGETSTART</b><br /> <b id="SCI_SETTARGETEND">SCI_SETTARGETEND(int pos)</b><br /> <b id="SCI_GETTARGETEND">SCI_GETTARGETEND</b><br /> These functions set and return the start and end of the target. When searching in non-regular expression mode, you can set start greater than end to find the last matching text in the target rather than the first matching text. The target is also set by a successful <code>SCI_SEARCHINTARGET</code>.</p> <p><b id="SCI_TARGETFROMSELECTION">SCI_TARGETFROMSELECTION</b><br /> Set the target start and end to the start and end positions of the selection.</p> <p><b id="SCI_SETSEARCHFLAGS">SCI_SETSEARCHFLAGS(int searchFlags)</b><br /> <b id="SCI_GETSEARCHFLAGS">SCI_GETSEARCHFLAGS</b><br /> These get and set the <a class="jump" href="#searchFlags"><code>searchFlags</code></a> used by <code>SCI_SEARCHINTARGET</code>. There are several option flags including a simple regular expression search.</p> <p><b id="SCI_SEARCHINTARGET">SCI_SEARCHINTARGET(int length, const char *text)</b><br /> This searches for the first occurrence of a text string in the target defined by <code>SCI_SETTARGETSTART</code> and <code>SCI_SETTARGETEND</code>. The text string is not zero terminated; the size is set by <code>length</code>. The search is modified by the search flags set by <code>SCI_SETSEARCHFLAGS</code>. If the search succeeds, the target is set to the found text and the return value is the position of the start of the matching text. If the search fails, the result is -1.</p> <p><b id="SCI_REPLACETARGET">SCI_REPLACETARGET(int length, const char *text)</b><br /> If <code>length</code> is -1, <code>text</code> is a zero terminated string, otherwise <code>length</code> sets the number of character to replace the target with. After replacement, the target range refers to the replacement text. The return value is the length of the replacement string.<br /> Note that the recommended way to delete text in the document is to set the target to the text to be removed, and to perform a replace target with an empty string.</p> <p><b id="SCI_REPLACETARGETRE">SCI_REPLACETARGETRE(int length, const char *text)</b><br /> This replaces the target using regular expressions. If <code>length</code> is -1, <code>text</code> is a zero terminated string, otherwise <code>length</code> is the number of characters to use. The replacement string is formed from the text string with any sequences of <code>\1</code> through <code>\9</code> replaced by tagged matches from the most recent regular expression search. <code>\0</code> is replaced with all the matched text from the most recent search. After replacement, the target range refers to the replacement text. The return value is the length of the replacement string.</p> <p><b id="SCI_GETTAG">SCI_GETTAG(int tagNumber, char *tagValue)</b><br /> Discover what text was matched by tagged expressions in a regular expression search. This is useful if the application wants to interpret the replacement string itself.</p> <p>See also: <a class="message" href="#SCI_FINDTEXT"><code>SCI_FINDTEXT</code></a></p> <h2 id="Overtype">Overtype</h2> <p><b id="SCI_SETOVERTYPE">SCI_SETOVERTYPE(bool overType)</b><br /> <b id="SCI_GETOVERTYPE">SCI_GETOVERTYPE</b><br /> When overtype is enabled, each typed character replaces the character to the right of the text caret. When overtype is disabled, characters are inserted at the caret. <code>SCI_GETOVERTYPE</code> returns <code>TRUE</code> (1) if overtyping is active, otherwise <code>FALSE</code> (0) will be returned. Use <code>SCI_SETOVERTYPE</code> to set the overtype mode.</p> <h2 id="CutCopyAndPaste">Cut, copy and paste</h2> <code><a class="message" href="#SCI_CUT">SCI_CUT</a><br /> <a class="message" href="#SCI_COPY">SCI_COPY</a><br /> <a class="message" href="#SCI_PASTE">SCI_PASTE</a><br /> <a class="message" href="#SCI_CLEAR">SCI_CLEAR</a><br /> <a class="message" href="#SCI_CANPASTE">SCI_CANPASTE</a><br /> <a class="message" href="#SCI_COPYRANGE">SCI_COPYRANGE(int start, int end)</a><br /> <a class="message" href="#SCI_COPYTEXT">SCI_COPYTEXT(int length, const char *text)</a><br /> <a class="message" href="#SCI_COPYALLOWLINE">SCI_COPYALLOWLINE</a><br /> <a class="message" href="#SCI_SETPASTECONVERTENDINGS">SCI_SETPASTECONVERTENDINGS(bool convert)</a><br /> <a class="message" href="#SCI_GETPASTECONVERTENDINGS">SCI_GETPASTECONVERTENDINGS</a><br /> </code> <p><b id="SCI_CUT">SCI_CUT</b><br /> <b id="SCI_COPY">SCI_COPY</b><br /> <b id="SCI_PASTE">SCI_PASTE</b><br /> <b id="SCI_CLEAR">SCI_CLEAR</b><br /> <b id="SCI_CANPASTE">SCI_CANPASTE</b><br /> <b id="SCI_COPYALLOWLINE">SCI_COPYALLOWLINE</b><br /> These commands perform the standard tasks of cutting and copying data to the clipboard, pasting from the clipboard into the document, and clearing the document. <code>SCI_CANPASTE</code> returns non-zero if the document isn't read-only and if the selection doesn't contain protected text. If you need a "can copy" or "can cut", use <code>SCI_GETSELECTIONEMPTY()</code>, which will be zero if there are any non-empty selection ranges implying that a copy or cut to the clipboard should work.</p> <p>GTK+ does not really support <code>SCI_CANPASTE</code> and always returns <code>TRUE</code> unless the document is read-only.</p> <p>On X, the clipboard is asynchronous and may require several messages between the destination and source applications. Data from SCI_PASTE will not arrive in the document immediately.</p> <p><code>SCI_COPYALLOWLINE</code> works the same as SCI_COPY except that if the selection is empty then the current line is copied. On Windows, an extra "MSDEVLineSelect" marker is added to the clipboard which is then used in <code>SCI_PASTE</code> to paste the whole line before the current line.</p> <b id="SCI_COPYRANGE">SCI_COPYRANGE(int start, int end)</b><br /> <b id="SCI_COPYTEXT">SCI_COPYTEXT(int length, const char *text)</b><br /> <p><code>SCI_COPYRANGE</code> copies a range of text from the document to the system clipboard and <code>SCI_COPYTEXT</code> copies a supplied piece of text to the system clipboard.</p> <p><b id="SCI_SETPASTECONVERTENDINGS">SCI_SETPASTECONVERTENDINGS(bool convert)</b><br /> <b id="SCI_GETPASTECONVERTENDINGS">SCI_GETPASTECONVERTENDINGS</b><br /> If this property is set then when text is pasted any line ends are converted to match the document's end of line mode as set with <a class="message" href="#SCI_SETEOLMODE">SCI_SETEOLMODE</a>. Currently only changeable on Windows. On GTK+ pasted text is always converted.</p> <h2 id="ErrorHandling">Error handling</h2> <p><b id="SCI_SETSTATUS">SCI_SETSTATUS(int status)</b><br /> <b id="SCI_GETSTATUS">SCI_GETSTATUS</b><br /> If an error occurs, Scintilla may set an internal error number that can be retrieved with <code>SCI_GETSTATUS</code>. To clear the error status call <code>SCI_SETSTATUS(0)</code>. The currently defined statuses are: </p> <table cellpadding="1" cellspacing="2" border="0" summary="Status values"> <tbody valign="top"> <tr> <th align="left">SC_STATUS_OK</th> <td>0</td> <td>No failures</td> </tr> <tr> <th align="left">SC_STATUS_FAILURE</th> <td>1</td> <td>Generic failure</td> </tr> <tr> <th align="left">SC_STATUS_BADALLOC</th> <td>2</td> <td>Memory is exhausted</td> </tr> </tbody> </table> <h2 id="UndoAndRedo">Undo and Redo</h2> <p>Scintilla has multiple level undo and redo. It will continue to collect undoable actions until memory runs out. Scintilla saves actions that change the document. Scintilla does not save caret and selection movements, view scrolling and the like. Sequences of typing or deleting are compressed into single transactions to make it easier to undo and redo at a sensible level of detail. Sequences of actions can be combined into transactions that are undone as a unit. These sequences occur between <code>SCI_BEGINUNDOACTION</code> and <code>SCI_ENDUNDOACTION</code> messages. These transactions can be nested and only the top-level sequences are undone as units.</p> <code><a class="message" href="#SCI_UNDO">SCI_UNDO</a><br /> <a class="message" href="#SCI_CANUNDO">SCI_CANUNDO</a><br /> <a class="message" href="#SCI_EMPTYUNDOBUFFER">SCI_EMPTYUNDOBUFFER</a><br /> <a class="message" href="#SCI_REDO">SCI_REDO</a><br /> <a class="message" href="#SCI_CANREDO">SCI_CANREDO</a><br /> <a class="message" href="#SCI_SETUNDOCOLLECTION">SCI_SETUNDOCOLLECTION(bool collectUndo)</a><br /> <a class="message" href="#SCI_GETUNDOCOLLECTION">SCI_GETUNDOCOLLECTION</a><br /> <a class="message" href="#SCI_BEGINUNDOACTION">SCI_BEGINUNDOACTION</a><br /> <a class="message" href="#SCI_ENDUNDOACTION">SCI_ENDUNDOACTION</a><br /> <a class="message" href="#SCI_ADDUNDOACTION">SCI_ADDUNDOACTION(int token, int flags)</a><br /> </code> <p><b id="SCI_UNDO">SCI_UNDO</b><br /> <b id="SCI_CANUNDO">SCI_CANUNDO</b><br /> <code>SCI_UNDO</code> undoes one action, or if the undo buffer has reached a <code>SCI_ENDUNDOACTION</code> point, all the actions back to the corresponding <code>SCI_BEGINUNDOACTION</code>.</p> <p><code>SCI_CANUNDO</code> returns 0 if there is nothing to undo, and 1 if there is. You would typically use the result of this message to enable/disable the Edit menu Undo command.</p> <p><b id="SCI_REDO">SCI_REDO</b><br /> <b id="SCI_CANREDO">SCI_CANREDO</b><br /> <code>SCI_REDO</code> undoes the effect of the last <code>SCI_UNDO</code> operation.</p> <p><code>SCI_CANREDO</code> returns 0 if there is no action to redo and 1 if there are undo actions to redo. You could typically use the result of this message to enable/disable the Edit menu Redo command.</p> <p><b id="SCI_EMPTYUNDOBUFFER">SCI_EMPTYUNDOBUFFER</b><br /> This command tells Scintilla to forget any saved undo or redo history. It also sets the save point to the start of the undo buffer, so the document will appear to be unmodified. This does not cause the <code><a class="message" href="#SCN_SAVEPOINTREACHED">SCN_SAVEPOINTREACHED</a></code> notification to be sent to the container.</p> <p>See also: <a class="message" href="#SCI_SETSAVEPOINT"><code>SCI_SETSAVEPOINT</code></a></p> <p><b id="SCI_SETUNDOCOLLECTION">SCI_SETUNDOCOLLECTION(bool collectUndo)</b><br /> <b id="SCI_GETUNDOCOLLECTION">SCI_GETUNDOCOLLECTION</b><br /> You can control whether Scintilla collects undo information with <code>SCI_SETUNDOCOLLECTION</code>. Pass in <code>true</code> (1) to collect information and <code>false</code> (0) to stop collecting. If you stop collection, you should also use <code>SCI_EMPTYUNDOBUFFER</code> to avoid the undo buffer being unsynchronized with the data in the buffer.</p> <p>You might wish to turn off saving undo information if you use the Scintilla to store text generated by a program (a Log view) or in a display window where text is often deleted and regenerated.</p> <p><b id="SCI_BEGINUNDOACTION">SCI_BEGINUNDOACTION</b><br /> <b id="SCI_ENDUNDOACTION">SCI_ENDUNDOACTION</b><br /> Send these two messages to Scintilla to mark the beginning and end of a set of operations that you want to undo all as one operation but that you have to generate as several operations. Alternatively, you can use these to mark a set of operations that you do not want to have combined with the preceding or following operations if they are undone.</p> <p><b id="SCI_ADDUNDOACTION">SCI_ADDUNDOACTION(int token, int flags)</b><br /> The container can add its own actions into the undo stack by calling <code>SCI_ADDUNDOACTION</code> and an <code>SCN_MODIFIED</code> notification will be sent to the container with the <a class="message" href="#SC_MOD_CONTAINER"><code>SC_MOD_CONTAINER</code></a> flag when it is time to undo (<code>SC_PERFORMED_UNDO</code>) or redo (<code>SC_PERFORMED_REDO</code>) the action. The token argument supplied is returned in the <code>token</code> field of the notification.</p> <p>For example, if the container wanted to allow undo and redo of a 'toggle bookmark' command then it could call <code>SCI_ADDUNDOACTION(line, 0)</code> each time the command is performed. Then when it receives a notification to undo or redo it toggles a bookmark on the line given by the token field. If there are different types of commands or parameters that need to be stored into the undo stack then the container should maintain a stack of its own for the document and use the current position in that stack as the argument to <code>SCI_ADDUNDOACTION(line)</code>. <code>SCI_ADDUNDOACTION</code> commands are not combined together into a single undo transaction unless grouped with <code>SCI_BEGINUNDOACTION</code> and <code>SCI_ENDUNDOACTION</code>.</p> <p>The flags argument can be <code>UNDO_MAY_COALESCE</code> (1) if the container action may be coalesced along with any insertion and deletion actions into a single compound action, otherwise 0. Coalescing treats coalescible container actions as transparent so will still only group together insertions that look like typing or deletions that look like multiple uses of the Backspace or Delete keys. </p> <h2 id="SelectionAndInformation">Selection and information</h2> <p>Scintilla maintains a selection that stretches between two points, the anchor and the current position. If the anchor and the current position are the same, there is no selected text. Positions in the document range from 0 (before the first character), to the document size (after the last character). If you use messages, there is nothing to stop you setting a position that is in the middle of a CRLF pair, or in the middle of a 2 byte character. However, keyboard commands will not move the caret into such positions.</p> <code><a class="message" href="#SCI_GETTEXTLENGTH">SCI_GETTEXTLENGTH</a><br /> <a class="message" href="#SCI_GETLENGTH">SCI_GETLENGTH</a><br /> <a class="message" href="#SCI_GETLINECOUNT">SCI_GETLINECOUNT</a><br /> <a class="message" href="#SCI_SETFIRSTVISIBLELINE">SCI_SETFIRSTVISIBLELINE(int lineDisplay)</a><br /> <a class="message" href="#SCI_GETFIRSTVISIBLELINE">SCI_GETFIRSTVISIBLELINE</a><br /> <a class="message" href="#SCI_LINESONSCREEN">SCI_LINESONSCREEN</a><br /> <a class="message" href="#SCI_GETMODIFY">SCI_GETMODIFY</a><br /> <a class="message" href="#SCI_SETSEL">SCI_SETSEL(int anchorPos, int currentPos)</a><br /> <a class="message" href="#SCI_GOTOPOS">SCI_GOTOPOS(int position)</a><br /> <a class="message" href="#SCI_GOTOLINE">SCI_GOTOLINE(int line)</a><br /> <a class="message" href="#SCI_SETCURRENTPOS">SCI_SETCURRENTPOS(int position)</a><br /> <a class="message" href="#SCI_GETCURRENTPOS">SCI_GETCURRENTPOS</a><br /> <a class="message" href="#SCI_SETANCHOR">SCI_SETANCHOR(int position)</a><br /> <a class="message" href="#SCI_GETANCHOR">SCI_GETANCHOR</a><br /> <a class="message" href="#SCI_SETSELECTIONSTART">SCI_SETSELECTIONSTART(int position)</a><br /> <a class="message" href="#SCI_GETSELECTIONSTART">SCI_GETSELECTIONSTART</a><br /> <a class="message" href="#SCI_SETSELECTIONEND">SCI_SETSELECTIONEND(int position)</a><br /> <a class="message" href="#SCI_GETSELECTIONEND">SCI_GETSELECTIONEND</a><br /> <a class="message" href="#SCI_SETEMPTYSELECTION">SCI_SETEMPTYSELECTION(int pos)</a><br /> <a class="message" href="#SCI_SELECTALL">SCI_SELECTALL</a><br /> <a class="message" href="#SCI_LINEFROMPOSITION">SCI_LINEFROMPOSITION(int position)</a><br /> <a class="message" href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE(int line)</a><br /> <a class="message" href="#SCI_GETLINEENDPOSITION">SCI_GETLINEENDPOSITION(int line)</a><br /> <a class="message" href="#SCI_LINELENGTH">SCI_LINELENGTH(int line)</a><br /> <a class="message" href="#SCI_GETCOLUMN">SCI_GETCOLUMN(int position)</a><br /> <a class="message" href="#SCI_FINDCOLUMN">SCI_FINDCOLUMN(int line, int column)</a><br /> <a class="message" href="#SCI_POSITIONFROMPOINT">SCI_POSITIONFROMPOINT(int x, int y)</a><br /> <a class="message" href="#SCI_POSITIONFROMPOINTCLOSE">SCI_POSITIONFROMPOINTCLOSE(int x, int y)</a><br /> <a class="message" href="#SCI_CHARPOSITIONFROMPOINT">SCI_CHARPOSITIONFROMPOINT(int x, int y)</a><br /> <a class="message" href="#SCI_CHARPOSITIONFROMPOINTCLOSE">SCI_CHARPOSITIONFROMPOINTCLOSE(int x, int y)</a><br /> <a class="message" href="#SCI_POINTXFROMPOSITION">SCI_POINTXFROMPOSITION(<unused>, int position)</a><br /> <a class="message" href="#SCI_POINTYFROMPOSITION">SCI_POINTYFROMPOSITION(<unused>, int position)</a><br /> <a class="message" href="#SCI_HIDESELECTION">SCI_HIDESELECTION(bool hide)</a><br /> <a class="message" href="#SCI_GETSELTEXT">SCI_GETSELTEXT(<unused>, char *text)</a><br /> <a class="message" href="#SCI_GETCURLINE">SCI_GETCURLINE(int textLen, char *text)</a><br /> <a class="message" href="#SCI_SELECTIONISRECTANGLE">SCI_SELECTIONISRECTANGLE</a><br /> <a class="message" href="#SCI_SETSELECTIONMODE">SCI_SETSELECTIONMODE(int mode)</a><br /> <a class="message" href="#SCI_GETSELECTIONMODE">SCI_GETSELECTIONMODE</a><br /> <a class="message" href="#SCI_GETLINESELSTARTPOSITION">SCI_GETLINESELSTARTPOSITION(int line)</a><br /> <a class="message" href="#SCI_GETLINESELENDPOSITION">SCI_GETLINESELENDPOSITION(int line)</a><br /> <a class="message" href="#SCI_MOVECARETINSIDEVIEW">SCI_MOVECARETINSIDEVIEW</a><br /> <a class="message" href="#SCI_WORDENDPOSITION">SCI_WORDENDPOSITION(int position, bool onlyWordCharacters)</a><br /> <a class="message" href="#SCI_WORDSTARTPOSITION">SCI_WORDSTARTPOSITION(int position, bool onlyWordCharacters)</a><br /> <a class="message" href="#SCI_POSITIONBEFORE">SCI_POSITIONBEFORE(int position)</a><br /> <a class="message" href="#SCI_POSITIONAFTER">SCI_POSITIONAFTER(int position)</a><br /> <a class="message" href="#SCI_COUNTCHARACTERS">SCI_COUNTCHARACTERS(int startPos, int endPos)</a><br /> <a class="message" href="#SCI_TEXTWIDTH">SCI_TEXTWIDTH(int styleNumber, const char *text)</a><br /> <a class="message" href="#SCI_TEXTHEIGHT">SCI_TEXTHEIGHT(int line)</a><br /> <a class="message" href="#SCI_CHOOSECARETX">SCI_CHOOSECARETX</a><br /> <a class="message" href="#SCI_MOVESELECTEDLINESUP">SCI_MOVESELECTEDLINESUP</a><br /> <a class="message" href="#SCI_MOVESELECTEDLINESDOWN">SCI_MOVESELECTEDLINESDOWN</a><br /> </code> <p><b id="SCI_GETTEXTLENGTH">SCI_GETTEXTLENGTH</b><br /> <b id="SCI_GETLENGTH">SCI_GETLENGTH</b><br /> Both these messages return the length of the document in bytes.</p> <p><b id="SCI_GETLINECOUNT">SCI_GETLINECOUNT</b><br /> This returns the number of lines in the document. An empty document contains 1 line. A document holding only an end of line sequence has 2 lines.</p> <p><b id="SCI_SETFIRSTVISIBLELINE">SCI_SETFIRSTVISIBLELINE(int lineDisplay)</b><br /> <b id="SCI_GETFIRSTVISIBLELINE">SCI_GETFIRSTVISIBLELINE</b><br /> These messages retrieve and set the line number of the first visible line in the Scintilla view. The first line in the document is numbered 0. The value is a visible line rather than a document line.</p> <p><b id="SCI_LINESONSCREEN">SCI_LINESONSCREEN</b><br /> This returns the number of complete lines visible on the screen. With a constant line height, this is the vertical space available divided by the line separation. Unless you arrange to size your window to an integral number of lines, there may be a partial line visible at the bottom of the view.</p> <p><b id="SCI_GETMODIFY">SCI_GETMODIFY</b><br /> This returns non-zero if the document is modified and 0 if it is unmodified. The modified status of a document is determined by the undo position relative to the save point. The save point is set by <a class="message" href="#SCI_SETSAVEPOINT"><code>SCI_SETSAVEPOINT</code></a>, usually when you have saved data to a file.</p> <p>If you need to be notified when the document becomes modified, Scintilla notifies the container that it has entered or left the save point with the <a class="message" href="#SCN_SAVEPOINTREACHED"><code>SCN_SAVEPOINTREACHED</code></a> and <a class="message" href="#SCN_SAVEPOINTLEFT"><code>SCN_SAVEPOINTLEFT</code></a> <a class="jump" href="#Notifications">notification messages</a>.</p> <p><b id="SCI_SETSEL">SCI_SETSEL(int anchorPos, int currentPos)</b><br /> This message sets both the anchor and the current position. If <code>currentPos</code> is negative, it means the end of the document. If <code>anchorPos</code> is negative, it means remove any selection (i.e. set the anchor to the same position as <code>currentPos</code>). The caret is scrolled into view after this operation.</p> <p><b id="SCI_GOTOPOS">SCI_GOTOPOS(int pos)</b><br /> This removes any selection, sets the caret at <code>pos</code> and scrolls the view to make the caret visible, if necessary. It is equivalent to <code>SCI_SETSEL(pos, pos)</code>. The anchor position is set the same as the current position.</p> <p><b id="SCI_GOTOLINE">SCI_GOTOLINE(int line)</b><br /> This removes any selection and sets the caret at the start of line number <code>line</code> and scrolls the view (if needed) to make it visible. The anchor position is set the same as the current position. If <code>line</code> is outside the lines in the document (first line is 0), the line set is the first or last.</p> <p><b id="SCI_SETCURRENTPOS">SCI_SETCURRENTPOS(int pos)</b><br /> This sets the current position and creates a selection between the anchor and the current position. The caret is not scrolled into view.</p> <p>See also: <a class="message" href="#SCI_SCROLLCARET"><code>SCI_SCROLLCARET</code></a></p> <p><b id="SCI_GETCURRENTPOS">SCI_GETCURRENTPOS</b><br /> This returns the current position.</p> <p><b id="SCI_SETANCHOR">SCI_SETANCHOR(int pos)</b><br /> This sets the anchor position and creates a selection between the anchor position and the current position. The caret is not scrolled into view.</p> <p>See also: <a class="message" href="#SCI_SCROLLCARET"><code>SCI_SCROLLCARET</code></a></p> <p><b id="SCI_GETANCHOR">SCI_GETANCHOR</b><br /> This returns the current anchor position.</p> <p><b id="SCI_SETSELECTIONSTART">SCI_SETSELECTIONSTART(int pos)</b><br /> <b id="SCI_SETSELECTIONEND">SCI_SETSELECTIONEND(int pos)</b><br /> These set the selection based on the assumption that the anchor position is less than the current position. They do not make the caret visible. The table shows the positions of the anchor and the current position after using these messages.</p> <table cellpadding="3" cellspacing="0" border="1" summary="SetSelection caret positioning"> <thead align="center"> <tr> <th> </th> <th>anchor</th> <th>current</th> </tr> </thead> <tbody align="center"> <tr> <th><code>SCI_SETSELECTIONSTART</code></th> <td><code>pos</code></td> <td><code>Max(pos, current)</code></td> </tr> <tr> <th><code>SCI_SETSELECTIONEND</code></th> <td><code>Min(anchor, pos)</code></td> <td><code>pos</code></td> </tr> </tbody> </table> <p>See also: <a class="message" href="#SCI_SCROLLCARET"><code>SCI_SCROLLCARET</code></a></p> <p><b id="SCI_GETSELECTIONSTART">SCI_GETSELECTIONSTART</b><br /> <b id="SCI_GETSELECTIONEND">SCI_GETSELECTIONEND</b><br /> These return the start and end of the selection without regard to which end is the current position and which is the anchor. <code>SCI_GETSELECTIONSTART</code> returns the smaller of the current position or the anchor position. <code>SCI_GETSELECTIONEND</code> returns the larger of the two values.</p> <p><b id="SCI_SETEMPTYSELECTION">SCI_SETEMPTYSELECTION(int pos)</b><br /> This removes any selection and sets the caret at <code>pos</code>. The caret is not scrolled into view.</p> <p><b id="SCI_SELECTALL">SCI_SELECTALL</b><br /> This selects all the text in the document. The current position is not scrolled into view.</p> <p><b id="SCI_LINEFROMPOSITION">SCI_LINEFROMPOSITION(int pos)</b><br /> This message returns the line that contains the position <code>pos</code> in the document. The return value is 0 if <code>pos</code> <= 0. The return value is the last line if <code>pos</code> is beyond the end of the document.</p> <p><b id="SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE(int line)</b><br /> This returns the document position that corresponds with the start of the line. If <code>line</code> is negative, the position of the line holding the start of the selection is returned. If <code>line</code> is greater than the lines in the document, the return value is -1. If <code>line</code> is equal to the number of lines in the document (i.e. 1 line past the last line), the return value is the end of the document.</p> <p><b id="SCI_GETLINEENDPOSITION">SCI_GETLINEENDPOSITION(int line)</b><br /> This returns the position at the end of the line, before any line end characters. If <code>line</code> is the last line in the document (which does not have any end of line characters), the result is the size of the document. If <code>line</code> is negative or <code>line</code> >= <a class="message" href="#SCI_GETLINECOUNT"><code>SCI_GETLINECOUNT()</code></a>, the result is undefined.</p> <p><b id="SCI_LINELENGTH">SCI_LINELENGTH(int line)</b><br /> This returns the length of the line, including any line end characters. If <code>line</code> is negative or beyond the last line in the document, the result is 0. If you want the length of the line not including any end of line characters, use <a class="message" href="#SCI_GETLINEENDPOSITION"><code>SCI_GETLINEENDPOSITION(line)</code></a> - <a class="message" href="#SCI_POSITIONFROMLINE"><code>SCI_POSITIONFROMLINE(line)</code></a>.</p> <p><b id="SCI_GETSELTEXT">SCI_GETSELTEXT(<unused>, char *text)</b><br /> This copies the currently selected text and a terminating 0 byte to the <code>text</code> buffer. The buffer size should be determined by calling with a NULL pointer for the <code>text</code> argument <code>SCI_GETSELTEXT(0,0)</code>. This allows for rectangular and discontiguous selections as well as simple selections. See <a class="toc" href="#MultipleSelectionAndVirtualSpace">Multiple Selection</a> for information on how multiple and rectangular selections and virtual space are copied.</p> <p>See also: <code><a class="message" href="#SCI_GETCURLINE">SCI_GETCURLINE</a>, <a class="message" href="#SCI_GETLINE">SCI_GETLINE</a>, <a class="message" href="#SCI_GETTEXT">SCI_GETTEXT</a>, <a class="message" href="#SCI_GETSTYLEDTEXT">SCI_GETSTYLEDTEXT</a>, <a class="message" href="#SCI_GETTEXTRANGE">SCI_GETTEXTRANGE</a> </code></p> <p><b id="SCI_GETCURLINE">SCI_GETCURLINE(int textLen, char *text)</b><br /> This retrieves the text of the line containing the caret and returns the position within the line of the caret. Pass in <code>char* text</code> pointing at a buffer large enough to hold the text you wish to retrieve and a terminating 0 character. Set <code>textLen</code> to the length of the buffer which must be at least 1 to hold the terminating 0 character. If the text argument is 0 then the length that should be allocated to store the entire current line is returned.</p> <p>See also: <code><a class="message" href="#SCI_GETSELTEXT">SCI_GETSELTEXT</a>, <a class="message" href="#SCI_GETLINE">SCI_GETLINE</a>, <a class="message" href="#SCI_GETTEXT">SCI_GETTEXT</a>, <a class="message" href="#SCI_GETSTYLEDTEXT">SCI_GETSTYLEDTEXT</a>, <a class="message" href="#SCI_GETTEXTRANGE">SCI_GETTEXTRANGE</a></code></p> <p><b id="SCI_SELECTIONISRECTANGLE">SCI_SELECTIONISRECTANGLE</b><br /> This returns 1 if the current selection is in rectangle mode, 0 if not.</p> <p><b id="SCI_SETSELECTIONMODE">SCI_SETSELECTIONMODE(int mode)</b><br /> <b id="SCI_GETSELECTIONMODE">SCI_GETSELECTIONMODE</b><br /> The two functions set and get the selection mode, which can be stream (<code>SC_SEL_STREAM</code>=0) or rectangular (<code>SC_SEL_RECTANGLE</code>=1) or by lines (<code>SC_SEL_LINES</code>=2) or thin rectangular (<code>SC_SEL_THIN</code>=3). When set in these modes, regular caret moves will extend or reduce the selection, until the mode is cancelled by a call with same value or with <code>SCI_CANCEL</code>. The get function returns the current mode even if the selection was made by mouse or with regular extended moves. <code>SC_SEL_THIN</code> is the mode after a rectangular selection has been typed into and ensures that no characters are selected.</p> <p><b id="SCI_GETLINESELSTARTPOSITION">SCI_GETLINESELSTARTPOSITION(int line)</b><br /> <b id="SCI_GETLINESELENDPOSITION">SCI_GETLINESELENDPOSITION(int line)</b><br /> Retrieve the position of the start and end of the selection at the given line with INVALID_POSITION returned if no selection on this line.</p> <p><b id="SCI_MOVECARETINSIDEVIEW">SCI_MOVECARETINSIDEVIEW</b><br /> If the caret is off the top or bottom of the view, it is moved to the nearest line that is visible to its current position. Any selection is lost.</p> <p><b id="SCI_WORDENDPOSITION">SCI_WORDENDPOSITION(int position, bool onlyWordCharacters)</b><br /> <b id="SCI_WORDSTARTPOSITION">SCI_WORDSTARTPOSITION(int position, bool onlyWordCharacters)</b><br /> These messages return the start and end of words using the same definition of words as used internally within Scintilla. You can set your own list of characters that count as words with <a class="message" href="#SCI_SETWORDCHARS"><code>SCI_SETWORDCHARS</code></a>. The position sets the start or the search, which is forwards when searching for the end and backwards when searching for the start.</p> <p>Set <code>onlyWordCharacters</code> to <code>true</code> (1) to stop searching at the first non-word character in the search direction. If <code>onlyWordCharacters</code> is <code>false</code> (0), the first character in the search direction sets the type of the search as word or non-word and the search stops at the first non-matching character. Searches are also terminated by the start or end of the document.</p> <p>If "w" represents word characters and "." represents non-word characters and "|" represents the position and <code>true</code> or <code>false</code> is the state of <code>onlyWordCharacters</code>:</p> <table cellpadding="3" cellspacing="0" border="1" summary="Word start and end positions"> <thead align="center"> <tr> <th>Initial state</th> <th>end, true</th> <th>end, false</th> <th>start, true</th> <th>start, false</th> </tr> </thead> <tbody align="center"> <tr> <td>..ww..|..ww..</td> <td>..ww..|..ww..</td> <td>..ww....|ww..</td> <td>..ww..|..ww..</td> <td>..ww|....ww..</td> </tr> <tr> <td>....ww|ww....</td> <td>....wwww|....</td> <td>....wwww|....</td> <td>....|wwww....</td> <td>....|wwww....</td> </tr> <tr> <td>..ww|....ww..</td> <td>..ww|....ww..</td> <td>..ww....|ww..</td> <td>..|ww....ww..</td> <td>..|ww....ww..</td> </tr> <tr> <td>..ww....|ww..</td> <td>..ww....ww|..</td> <td>..ww....ww|..</td> <td>..ww....|ww..</td> <td>..ww|....ww..</td> </tr> </tbody> </table> <p><b id="SCI_POSITIONBEFORE">SCI_POSITIONBEFORE(int position)</b><br /> <b id="SCI_POSITIONAFTER">SCI_POSITIONAFTER(int position)</b><br /> These messages return the position before and after another position in the document taking into account the current code page. The minimum position returned is 0 and the maximum is the last position in the document. If called with a position within a multi byte character will return the position of the start/end of that character.</p> <p><b id="SCI_COUNTCHARACTERS">SCI_COUNTCHARACTERS(int startPos, int endPos)</b><br /> Returns the number of whole characters between two positions..</p> <p><b id="SCI_TEXTWIDTH">SCI_TEXTWIDTH(int styleNumber, const char *text)</b><br /> This returns the pixel width of a string drawn in the given <code>styleNumber</code> which can be used, for example, to decide how wide to make the line number margin in order to display a given number of numerals.</p> <p><b id="SCI_TEXTHEIGHT">SCI_TEXTHEIGHT(int line)</b><br /> This returns the height in pixels of a particular line. Currently all lines are the same height.</p> <p><b id="SCI_GETCOLUMN">SCI_GETCOLUMN(int pos)</b><br /> This message returns the column number of a position <code>pos</code> within the document taking the width of tabs into account. This returns the column number of the last tab on the line before <code>pos</code>, plus the number of characters between the last tab and <code>pos</code>. If there are no tab characters on the line, the return value is the number of characters up to the position on the line. In both cases, double byte characters count as a single character. This is probably only useful with monospaced fonts.</p> <p><b id="SCI_FINDCOLUMN">SCI_FINDCOLUMN(int line, int column)</b><br /> This message returns the position of a <code>column</code> on a <code>line</code> taking the width of tabs into account. It treats a multi-byte character as a single column. Column numbers, like lines start at 0.</p> <p><b id="SCI_POSITIONFROMPOINT">SCI_POSITIONFROMPOINT(int x, int y)</b><br /> <b id="SCI_POSITIONFROMPOINTCLOSE">SCI_POSITIONFROMPOINTCLOSE(int x, int y)</b><br /> <code>SCI_POSITIONFROMPOINT</code> finds the closest character position to a point and <code>SCI_POSITIONFROMPOINTCLOSE</code> is similar but returns -1 if the point is outside the window or not close to any characters.</p> <p><b id="SCI_CHARPOSITIONFROMPOINT">SCI_CHARPOSITIONFROMPOINT(int x, int y)</b><br /> <b id="SCI_CHARPOSITIONFROMPOINTCLOSE">SCI_CHARPOSITIONFROMPOINTCLOSE(int x, int y)</b><br /> <code>SCI_CHARPOSITIONFROMPOINT</code> finds the closest character to a point and <code>SCI_CHARPOSITIONFROMPOINTCLOSE</code> is similar but returns -1 if the point is outside the window or not close to any characters. This is similar to the previous methods but finds characters rather than inter-character positions.</p> <p><b id="SCI_POINTXFROMPOSITION">SCI_POINTXFROMPOSITION(<unused>, int pos)</b><br /> <b id="SCI_POINTYFROMPOSITION">SCI_POINTYFROMPOSITION(<unused>, int pos)</b><br /> These messages return the x and y display pixel location of text at position <code>pos</code> in the document.</p> <p><b id="SCI_HIDESELECTION">SCI_HIDESELECTION(bool hide)</b><br /> The normal state is to make the selection visible by drawing it as set by <a class="message" href="#SCI_SETSELFORE"><code>SCI_SETSELFORE</code></a> and <a class="message" href="#SCI_SETSELBACK"><code>SCI_SETSELBACK</code></a>. However, if you hide the selection, it is drawn as normal text.</p> <p><b id="SCI_CHOOSECARETX">SCI_CHOOSECARETX</b><br /> Scintilla remembers the x value of the last position horizontally moved to explicitly by the user and this value is then used when moving vertically such as by using the up and down keys. This message sets the current x position of the caret as the remembered value.</p> <p><b id="SCI_MOVESELECTEDLINESUP">SCI_MOVESELECTEDLINESUP</b><br /> Move the selected lines up one line, shifting the line above after the selection. The selection will be automatically extended to the beginning of the selection's first line and the end of the seletion's last line. If nothing was selected, the line the cursor is currently at will be selected.</p> <p><b id="SCI_MOVESELECTEDLINESDOWN">SCI_MOVESELECTEDLINESDOWN</b><br /> Move the selected lines down one line, shifting the line below before the selection. The selection will be automatically extended to the beginning of the selection's first line and the end of the seletion's last line. If nothing was selected, the line the cursor is currently at will be selected.</p> <h2 id="MultipleSelectionAndVirtualSpace">Multiple Selection and Virtual Space</h2> <code> <a class="message" href="#SCI_SETMULTIPLESELECTION">SCI_SETMULTIPLESELECTION(bool multipleSelection)</a><br /> <a class="message" href="#SCI_GETMULTIPLESELECTION">SCI_GETMULTIPLESELECTION</a><br /> <a class="message" href="#SCI_SETADDITIONALSELECTIONTYPING">SCI_SETADDITIONALSELECTIONTYPING(bool additionalSelectionTyping)</a><br /> <a class="message" href="#SCI_GETADDITIONALSELECTIONTYPING">SCI_GETADDITIONALSELECTIONTYPING</a><br /> <a class="message" href="#SCI_SETMULTIPASTE">SCI_SETMULTIPASTE(int multiPaste)</a><br /> <a class="message" href="#SCI_GETMULTIPASTE">SCI_GETMULTIPASTE</a><br /> <a class="message" href="#SCI_SETVIRTUALSPACEOPTIONS">SCI_SETVIRTUALSPACEOPTIONS(int virtualSpaceOptions)</a><br /> <a class="message" href="#SCI_GETVIRTUALSPACEOPTIONS">SCI_GETVIRTUALSPACEOPTIONS</a><br /> <a class="message" href="#SCI_SETRECTANGULARSELECTIONMODIFIER">SCI_SETRECTANGULARSELECTIONMODIFIER(int modifier)</a><br /> <a class="message" href="#SCI_GETRECTANGULARSELECTIONMODIFIER">SCI_GETRECTANGULARSELECTIONMODIFIER</a><br /> <br /> <a class="message" href="#SCI_GETSELECTIONS">SCI_GETSELECTIONS</a><br /> <a class="message" href="#SCI_GETSELECTIONEMPTY">SCI_GETSELECTIONEMPTY</a><br /> <a class="message" href="#SCI_CLEARSELECTIONS">SCI_CLEARSELECTIONS</a><br /> <a class="message" href="#SCI_SETSELECTION">SCI_SETSELECTION(int caret, int anchor)</a><br /> <a class="message" href="#SCI_ADDSELECTION">SCI_ADDSELECTION(int caret, int anchor)</a><br /> <a class="message" href="#SCI_SETMAINSELECTION">SCI_SETMAINSELECTION(int selection)</a><br /> <a class="message" href="#SCI_GETMAINSELECTION">SCI_GETMAINSELECTION</a><br /> <br /> <a class="message" href="#SCI_SETSELECTIONNCARET">SCI_SETSELECTIONNCARET(int selection, int pos)</a><br /> <a class="message" href="#SCI_GETSELECTIONNCARET">SCI_GETSELECTIONNCARET(int selection)</a><br /> <a class="message" href="#SCI_SETSELECTIONNCARETVIRTUALSPACE">SCI_SETSELECTIONNCARETVIRTUALSPACE(int selection, int space)</a><br /> <a class="message" href="#SCI_GETSELECTIONNCARETVIRTUALSPACE">SCI_GETSELECTIONNCARETVIRTUALSPACE(int selection)</a><br /> <a class="message" href="#SCI_SETSELECTIONNANCHOR">SCI_SETSELECTIONNANCHOR(int selection, int posAnchor)</a><br /> <a class="message" href="#SCI_GETSELECTIONNANCHOR">SCI_GETSELECTIONNANCHOR(int selection)</a><br /> <a class="message" href="#SCI_SETSELECTIONNANCHORVIRTUALSPACE">SCI_SETSELECTIONNANCHORVIRTUALSPACE(int selection, int space)</a><br /> <a class="message" href="#SCI_GETSELECTIONNANCHORVIRTUALSPACE">SCI_GETSELECTIONNANCHORVIRTUALSPACE(int selection)</a><br /> <a class="message" href="#SCI_SETSELECTIONNSTART">SCI_SETSELECTIONNSTART(int selection, int pos)</a><br /> <a class="message" href="#SCI_GETSELECTIONNSTART">SCI_GETSELECTIONNSTART(int selection)</a><br /> <a class="message" href="#SCI_SETSELECTIONNEND">SCI_SETSELECTIONNEND(int selection, int pos)</a><br /> <a class="message" href="#SCI_GETSELECTIONNEND">SCI_GETSELECTIONNEND(int selection)</a><br /> <br /> <a class="message" href="#SCI_SETRECTANGULARSELECTIONCARET">SCI_SETRECTANGULARSELECTIONCARET(int pos)</a><br /> <a class="message" href="#SCI_GETRECTANGULARSELECTIONCARET">SCI_GETRECTANGULARSELECTIONCARET</a><br /> <a class="message" href="#SCI_SETRECTANGULARSELECTIONCARETVIRTUALSPACE">SCI_SETRECTANGULARSELECTIONCARETVIRTUALSPACE(int space)</a><br /> <a class="message" href="#SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE">SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE</a><br /> <a class="message" href="#SCI_SETRECTANGULARSELECTIONANCHOR">SCI_SETRECTANGULARSELECTIONANCHOR(int posAnchor)</a><br /> <a class="message" href="#SCI_GETRECTANGULARSELECTIONANCHOR">SCI_GETRECTANGULARSELECTIONANCHOR</a><br /> <a class="message" href="#SCI_SETRECTANGULARSELECTIONANCHORVIRTUALSPACE">SCI_SETRECTANGULARSELECTIONANCHORVIRTUALSPACE(int space)</a><br /> <a class="message" href="#SCI_GETRECTANGULARSELECTIONANCHORVIRTUALSPACE">SCI_GETRECTANGULARSELECTIONANCHORVIRTUALSPACE</a><br /> <br /> <a class="message" href="#SCI_SETADDITIONALSELALPHA">SCI_SETADDITIONALSELALPHA(int alpha)</a><br /> <a class="message" href="#SCI_GETADDITIONALSELALPHA">SCI_GETADDITIONALSELALPHA</a><br /> <a class="message" href="#SCI_SETADDITIONALSELFORE">SCI_SETADDITIONALSELFORE(int colour)</a><br /> <a class="message" href="#SCI_SETADDITIONALSELBACK">SCI_SETADDITIONALSELBACK(int colour)</a><br /> <a class="message" href="#SCI_SETADDITIONALCARETFORE">SCI_SETADDITIONALCARETFORE(int colour)</a><br /> <a class="message" href="#SCI_GETADDITIONALCARETFORE">SCI_GETADDITIONALCARETFORE</a><br /> <a class="message" href="#SCI_SETADDITIONALCARETSBLINK">SCI_SETADDITIONALCARETSBLINK(bool additionalCaretsBlink)</a><br /> <a class="message" href="#SCI_GETADDITIONALCARETSBLINK">SCI_GETADDITIONALCARETSBLINK</a><br /> <a class="message" href="#SCI_SETADDITIONALCARETSVISIBLE">SCI_SETADDITIONALCARETSVISIBLE(bool additionalCaretsVisible)</a><br /> <a class="message" href="#SCI_GETADDITIONALCARETSVISIBLE">SCI_GETADDITIONALCARETSVISIBLE</a><br /> <br /> <a class="message" href="#SCI_SWAPMAINANCHORCARET">SCI_SWAPMAINANCHORCARET</a><br /> <a class="message" href="#SCI_ROTATESELECTION">SCI_ROTATESELECTION</a><br /> </code> <p> There may be multiple selections active at one time. More selections are made by holding down the Ctrl key while dragging with the mouse. The most recent selection is the main selection and determines which part of the document is shown automatically. Any selection apart from the main selection is called an additional selection. The calls in the previous section operate on the main selection. There is always at least one selection. </p> <p> Rectangular selections are handled as multiple selections although the original rectangular range is remembered so that subsequent operations may be handled differently for rectangular selections. For example, pasting a rectangular selection places each piece in a vertical column. </p> <p> Virtual space is space beyond the end of each line. The caret may be moved into virtual space but no real space will be added to the document until there is some text typed or some other text insertion command is used. </p> <p>When discontiguous selections are copied to the clipboard, each selection is added to the clipboard text in order with no delimiting characters. For rectangular selections the document's line end is added after each line's text. Rectangular selections are always copied from top line to bottom, not in the in order of selection.Virtual space is not copied.</p> <p> <b id="SCI_SETMULTIPLESELECTION">SCI_SETMULTIPLESELECTION(bool multipleSelection)</b><br /> <b id="SCI_GETMULTIPLESELECTION">SCI_GETMULTIPLESELECTION</b><br /> Enable or disable multiple selection. When multiple selection is disabled, it is not possible to select multiple ranges by holding down the Ctrl key while dragging with the mouse.</p> <p> <b id="SCI_SETADDITIONALSELECTIONTYPING">SCI_SETADDITIONALSELECTIONTYPING(bool additionalSelectionTyping)</b><br /> <b id="SCI_GETADDITIONALSELECTIONTYPING">SCI_GETADDITIONALSELECTIONTYPING</b><br /> Whether typing, backspace, or delete works with multiple selections simultaneously.</p> <p> <b id="SCI_SETMULTIPASTE">SCI_SETMULTIPASTE(int multiPaste)</b><br /> <b id="SCI_GETMULTIPASTE">SCI_GETMULTIPASTE</b><br /> When pasting into multiple selections, the pasted text can go into just the main selection with <code>SC_MULTIPASTE_ONCE</code>=0 or into each selection with <code>SC_MULTIPASTE_EACH</code>=1. <code>SC_MULTIPASTE_ONCE</code> is the default.</p> <p> <b id="SCI_SETVIRTUALSPACEOPTIONS">SCI_SETVIRTUALSPACEOPTIONS(int virtualSpace)</b><br /> <b id="SCI_GETVIRTUALSPACEOPTIONS">SCI_GETVIRTUALSPACEOPTIONS</b><br /> Virtual space can be enabled or disabled for rectangular selections or in other circumstances or in both. There are two bit flags <code>SCVS_RECTANGULARSELECTION</code>=1 and <code>SCVS_USERACCESSIBLE</code>=2 which can be set independently. <code>SCVS_NONE</code>=0, the default, disables all use of virtual space.</p> <p> <b id="SCI_SETRECTANGULARSELECTIONMODIFIER">SCI_SETRECTANGULARSELECTIONMODIFIER(int modifier)</b><br /> <b id="SCI_GETRECTANGULARSELECTIONMODIFIER">SCI_GETRECTANGULARSELECTIONMODIFIER</b><br /> On GTK+, the key used to indicate that a rectangular selection should be created when combined with a mouse drag can be set. The three possible values are <code>SCMOD_CTRL</code>=2 (default), <code>SCMOD_ALT</code>=4 or <code>SCMOD_SUPER</code>=8. Since <code>SCMOD_ALT</code> is often already used by a window manager, the window manager may need configuring to allow this choice. <code>SCMOD_SUPER</code> is often a system dependent modifier key such as the Left Windows key on a Windows keyboard or the Command key on a Mac.</p> <p> <b id="SCI_GETSELECTIONS">SCI_GETSELECTIONS</b><br /> Return the number of selections currently active.</p> <p> <b id="SCI_GETSELECTIONEMPTY">SCI_GETSELECTIONEMPTY</b><br /> Return 1 if every selected range is empty else 0.</p> <p> <b id="SCI_CLEARSELECTIONS">SCI_CLEARSELECTIONS</b><br /> Set a single empty selection at 0 as the only selection.</p> <p> <b id="SCI_SETSELECTION">SCI_SETSELECTION(int caret, int anchor)</b><br /> Set a single selection from <code>anchor</code> to <code>caret</code> as the only selection.</p> <p> <b id="SCI_ADDSELECTION">SCI_ADDSELECTION(int caret, int anchor)</b><br /> Add a new selection from <code>anchor</code> to <code>caret</code> as the main selection retaining all other selections as additional selections. Since there is always at least one selection, to set a list of selections, the first selection should be added with <code>SCI_SETSELECTION</code> and later selections added with <code>SCI_ADDSELECTION</code></p> <p> <b id="SCI_SETMAINSELECTION">SCI_SETMAINSELECTION(int selection)</b><br /> <b id="SCI_GETMAINSELECTION">SCI_GETMAINSELECTION</b><br /> One of the selections is the main selection which is used to determine what range of text is automatically visible. The main selection may be displayed in different colours or with a differently styled caret. Only an already existing selection can be made main.</p> <p> <b id="SCI_SETSELECTIONNCARET">SCI_SETSELECTIONNCARET(int selection, int pos)</b><br /> <b id="SCI_GETSELECTIONNCARET">SCI_GETSELECTIONNCARET(int selection)</b><br /> <b id="SCI_SETSELECTIONNCARETVIRTUALSPACE">SCI_SETSELECTIONNCARETVIRTUALSPACE(int selection, int space)</b><br /> <b id="SCI_GETSELECTIONNCARETVIRTUALSPACE">SCI_GETSELECTIONNCARETVIRTUALSPACE(int selection)</b><br /> <b id="SCI_SETSELECTIONNANCHOR">SCI_SETSELECTIONNANCHOR(int selection, int posAnchor)</b><br /> <b id="SCI_GETSELECTIONNANCHOR">SCI_GETSELECTIONNANCHOR(int selection)</b><br /> <b id="SCI_SETSELECTIONNANCHORVIRTUALSPACE">SCI_SETSELECTIONNANCHORVIRTUALSPACE(int selection, int space)</b><br /> <b id="SCI_GETSELECTIONNANCHORVIRTUALSPACE">SCI_GETSELECTIONNANCHORVIRTUALSPACE(int selection)</b><br /> Set or query the position and amount of virtual space for the caret and anchor of each already existing selection.</p> <p> <b id="SCI_SETSELECTIONNSTART">SCI_SETSELECTIONNSTART(int selection, int pos)</b><br /> <b id="SCI_GETSELECTIONNSTART">SCI_GETSELECTIONNSTART(int selection)</b><br /> <b id="SCI_SETSELECTIONNEND">SCI_SETSELECTIONNEND(int selection, int pos)</b><br /> <b id="SCI_GETSELECTIONNEND">SCI_GETSELECTIONNEND(int selection)</b><br /> Set or query the start and end position of each already existing selection. Mostly of use to query each range for its text.</p> <p> <b id="SCI_SETRECTANGULARSELECTIONCARET">SCI_SETRECTANGULARSELECTIONCARET(int pos)</b><br /> <b id="SCI_GETRECTANGULARSELECTIONCARET">SCI_GETRECTANGULARSELECTIONCARET</b><br /> <b id="SCI_SETRECTANGULARSELECTIONCARETVIRTUALSPACE">SCI_SETRECTANGULARSELECTIONCARETVIRTUALSPACE(int space)</b><br /> <b id="SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE">SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE</b><br /> <b id="SCI_SETRECTANGULARSELECTIONANCHOR">SCI_SETRECTANGULARSELECTIONANCHOR(int posAnchor)</b><br /> <b id="SCI_GETRECTANGULARSELECTIONANCHOR">SCI_GETRECTANGULARSELECTIONANCHOR</b><br /> <b id="SCI_SETRECTANGULARSELECTIONANCHORVIRTUALSPACE">SCI_SETRECTANGULARSELECTIONANCHORVIRTUALSPACE(int space)</b><br /> <b id="SCI_GETRECTANGULARSELECTIONANCHORVIRTUALSPACE">SCI_GETRECTANGULARSELECTIONANCHORVIRTUALSPACE</b><br /> Set or query the position and amount of virtual space for the caret and anchor of the rectangular selection. After setting the rectangular selection, this is broken down into multiple selections, one for each line.</p> <p> <b id="SCI_SETADDITIONALSELALPHA">SCI_SETADDITIONALSELALPHA(int alpha)</b><br /> <b id="SCI_GETADDITIONALSELALPHA">SCI_GETADDITIONALSELALPHA</b><br /> <b id="SCI_SETADDITIONALSELFORE">SCI_SETADDITIONALSELFORE(int <a class="jump" href="#colour">colour</a>)</b><br /> <b id="SCI_SETADDITIONALSELBACK">SCI_SETADDITIONALSELBACK(int <a class="jump" href="#colour">colour</a>)</b><br /> Modify the appearence of additional selections so that they can be differentiated from the main selection which has its appearence set with <a class="message" href="#SCI_SETSELALPHA"><code>SCI_SETSELALPHA</code></a>, <a class="message" href="#SCI_GETSELALPHA"><code>SCI_GETSELALPHA</code></a>, <a class="message" href="#SCI_SETSELFORE"><code>SCI_SETSELFORE</code></a>, and <a class="message" href="#SCI_SETSELBACK"><code>SCI_SETSELBACK</code></a>.</p> <p> <b id="SCI_SETADDITIONALCARETFORE">SCI_SETADDITIONALCARETFORE(int <a class="jump" href="#colour">colour</a>)</b><br /> <b id="SCI_GETADDITIONALCARETFORE">SCI_GETADDITIONALCARETFORE</b><br /> <b id="SCI_SETADDITIONALCARETSBLINK">SCI_SETADDITIONALCARETSBLINK(bool additionalCaretsBlink)</b><br /> <b id="SCI_GETADDITIONALCARETSBLINK">SCI_GETADDITIONALCARETSBLINK</b><br /> Modify the appearence of additional carets so that they can be differentiated from the main caret which has its appearence set with <a class="message" href="#SCI_SETCARETFORE"><code>SCI_SETCARETFORE</code></a>, <a class="message" href="#SCI_GETCARETFORE"><code>SCI_GETCARETFORE</code></a>, <a class="message" href="#SCI_SETCARETPERIOD"><code>SCI_SETCARETPERIOD</code></a>, and <a class="message" href="#SCI_GETCARETPERIOD"><code>SCI_GETCARETPERIOD</code></a>.</p> <p> <b id="SCI_SETADDITIONALCARETSVISIBLE">SCI_SETADDITIONALCARETSVISIBLE(bool additionalCaretsVisible)</b><br /> <b id="SCI_GETADDITIONALCARETSVISIBLE">SCI_GETADDITIONALCARETSVISIBLE</b><br /> Determine whether to show additional carets (defaults to <code>true</code>).</p> <p> <b id="SCI_SWAPMAINANCHORCARET">SCI_SWAPMAINANCHORCARET</b><br /> <b id="SCI_ROTATESELECTION">SCI_ROTATESELECTION</b><br /> These commands may be assigned to keys to make it possible to manipulate multiple selections. <code>SCI_SWAPMAINANCHORCARET</code> moves the caret to the opposite end of the main selection. <code>SCI_ROTATESELECTION</code> makes the next selection be the main selection. </p> <h2 id="ScrollingAndAutomaticScrolling">Scrolling and automatic scrolling</h2> <code><a class="message" href="#SCI_LINESCROLL">SCI_LINESCROLL(int column, int line)</a><br /> <a class="message" href="#SCI_SCROLLCARET">SCI_SCROLLCARET</a><br /> <a class="message" href="#SCI_SCROLLRANGE">SCI_SCROLLRANGE(int secondary, int primary)</a><br /> <a class="message" href="#SCI_SETXCARETPOLICY">SCI_SETXCARETPOLICY(int caretPolicy, int caretSlop)</a><br /> <a class="message" href="#SCI_SETYCARETPOLICY">SCI_SETYCARETPOLICY(int caretPolicy, int caretSlop)</a><br /> <a class="message" href="#SCI_SETVISIBLEPOLICY">SCI_SETVISIBLEPOLICY(int caretPolicy, int caretSlop)</a><br /> <a class="message" href="#SCI_SETHSCROLLBAR">SCI_SETHSCROLLBAR(bool visible)</a><br /> <a class="message" href="#SCI_GETHSCROLLBAR">SCI_GETHSCROLLBAR</a><br /> <a class="message" href="#SCI_SETVSCROLLBAR">SCI_SETVSCROLLBAR(bool visible)</a><br /> <a class="message" href="#SCI_GETVSCROLLBAR">SCI_GETVSCROLLBAR</a><br /> <a class="message" href="#SCI_GETXOFFSET">SCI_GETXOFFSET</a><br /> <a class="message" href="#SCI_SETXOFFSET">SCI_SETXOFFSET(int xOffset)</a><br /> <a class="message" href="#SCI_SETSCROLLWIDTH">SCI_SETSCROLLWIDTH(int pixelWidth)</a><br /> <a class="message" href="#SCI_GETSCROLLWIDTH">SCI_GETSCROLLWIDTH</a><br /> <a class="message" href="#SCI_SETSCROLLWIDTHTRACKING">SCI_SETSCROLLWIDTHTRACKING(bool tracking)</a><br /> <a class="message" href="#SCI_GETSCROLLWIDTHTRACKING">SCI_GETSCROLLWIDTHTRACKING</a><br /> <a class="message" href="#SCI_SETENDATLASTLINE">SCI_SETENDATLASTLINE(bool endAtLastLine)</a><br /> <a class="message" href="#SCI_GETENDATLASTLINE">SCI_GETENDATLASTLINE</a><br /> </code> <p><b id="SCI_LINESCROLL">SCI_LINESCROLL(int column, int line)</b><br /> This will attempt to scroll the display by the number of columns and lines that you specify. Positive line values increase the line number at the top of the screen (i.e. they move the text upwards as far as the user is concerned), Negative line values do the reverse.</p> <p>The column measure is the width of a space in the default style. Positive values increase the column at the left edge of the view (i.e. they move the text leftwards as far as the user is concerned). Negative values do the reverse.</p> <p>See also: <a class="message" href="#SCI_SETXOFFSET"><code>SCI_SETXOFFSET</code></a></p> <p><b id="SCI_SCROLLCARET">SCI_SCROLLCARET</b><br /> If the current position (this is the caret if there is no selection) is not visible, the view is scrolled to make it visible according to the current caret policy.</p> <p><b id="SCI_SCROLLRANGE">SCI_SCROLLRANGE(int secondary, int primary)</b><br /> Scroll the argument positions and the range between them into view giving priority to the primary position then the secondary position. The behaviour is similar to <a class="message" href="#SCI_SCROLLCARET"><code>SCI_SCROLLCARET</code></a> with the primary position used instead of the caret. An effort is then made to ensure that the secondary position and range between are also visible. This may be used to make a search match visible.</p> <p><b id="SCI_SETXCARETPOLICY">SCI_SETXCARETPOLICY(int caretPolicy, int caretSlop)</b><br /> <b id="SCI_SETYCARETPOLICY">SCI_SETYCARETPOLICY(int caretPolicy, int caretSlop)</b><br /> These set the caret policy. The value of <code>caretPolicy</code> is a combination of <code>CARET_SLOP</code>, <code>CARET_STRICT</code>, <code>CARET_JUMPS</code> and <code>CARET_EVEN</code>.</p> <table cellpadding="1" cellspacing="2" border="0" summary="Caret policy"> <tbody valign="top"> <tr> <th align="left"><code>CARET_SLOP</code></th> <td>If set, we can define a slop value: <code>caretSlop</code>. This value defines an unwanted zone (UZ) where the caret is... unwanted. This zone is defined as a number of pixels near the vertical margins, and as a number of lines near the horizontal margins. By keeping the caret away from the edges, it is seen within its context. This makes it likely that the identifier that the caret is on can be completely seen, and that the current line is seen with some of the lines following it, which are often dependent on that line.</td> </tr> <tr> <th align="left"><code>CARET_STRICT</code></th> <td>If set, the policy set by <code>CARET_SLOP</code> is enforced... strictly. The caret is centred on the display if <code>caretSlop</code> is not set, and cannot go in the UZ if <code>caretSlop</code> is set.</td> </tr> <tr> <th align="left"><code>CARET_JUMPS</code></th> <td>If set, the display is moved more energetically so the caret can move in the same direction longer before the policy is applied again. '3UZ' notation is used to indicate three time the size of the UZ as a distance to the margin.</td> </tr> <tr> <th align="left"><code>CARET_EVEN</code></th> <td>If not set, instead of having symmetrical UZs, the left and bottom UZs are extended up to right and top UZs respectively. This way, we favour the displaying of useful information: the beginning of lines, where most code reside, and the lines after the caret, for example, the body of a function.</td> </tr> </tbody> </table> <table cellpadding="3" cellspacing="0" border="1" summary="Caret positioning"> <thead align="center"> <tr> <th>slop</th> <th>strict</th> <th>jumps</th> <th>even</th> <th>Caret can go to the margin</th> <th>On reaching limit (going out of visibility<br /> or going into the UZ) display is...</th> </tr> </thead> <tbody align="center"> <tr> <td>0</td> <td>0</td> <td>0</td> <td>0</td> <td>Yes</td> <td>moved to put caret on top/on right</td> </tr> <tr> <td>0</td> <td>0</td> <td>0</td> <td>1</td> <td>Yes</td> <td>moved by one position</td> </tr> <tr> <td>0</td> <td>0</td> <td>1</td> <td>0</td> <td>Yes</td> <td>moved to put caret on top/on right</td> </tr> <tr> <td>0</td> <td>0</td> <td>1</td> <td>1</td> <td>Yes</td> <td>centred on the caret</td> </tr> <tr> <td>0</td> <td>1</td> <td>-</td> <td>0</td> <td>Caret is always on top/on right of display</td> <td>-</td> </tr> <tr> <td>0</td> <td>1</td> <td>-</td> <td>1</td> <td>No, caret is always centred</td> <td>-</td> </tr> <tr> <td>1</td> <td>0</td> <td>0</td> <td>0</td> <td>Yes</td> <td>moved to put caret out of the asymmetrical UZ</td> </tr> <tr> <td>1</td> <td>0</td> <td>0</td> <td>1</td> <td>Yes</td> <td>moved to put caret out of the UZ</td> </tr> <tr> <td>1</td> <td>0</td> <td>1</td> <td>0</td> <td>Yes</td> <td>moved to put caret at 3UZ of the top or right margin</td> </tr> <tr> <td>1</td> <td>0</td> <td>1</td> <td>1</td> <td>Yes</td> <td>moved to put caret at 3UZ of the margin</td> </tr> <tr> <td>1</td> <td>1</td> <td>-</td> <td>0</td> <td>Caret is always at UZ of top/right margin</td> <td>-</td> </tr> <tr> <td>1</td> <td>1</td> <td>0</td> <td>1</td> <td>No, kept out of UZ</td> <td>moved by one position</td> </tr> <tr> <td>1</td> <td>1</td> <td>1</td> <td>0</td> <td>No, kept out of UZ</td> <td>moved to put caret at 3UZ of the margin</td> </tr> </tbody> </table> <p><b id="SCI_SETVISIBLEPOLICY">SCI_SETVISIBLEPOLICY(int caretPolicy, int caretSlop)</b><br /> This determines how the vertical positioning is determined when <a class="message" href="#SCI_ENSUREVISIBLEENFORCEPOLICY"><code>SCI_ENSUREVISIBLEENFORCEPOLICY</code></a> is called. It takes <code>VISIBLE_SLOP</code> and <code>VISIBLE_STRICT</code> flags for the policy parameter. It is similar in operation to <a class="message" href="#SCI_SETYCARETPOLICY"><code>SCI_SETYCARETPOLICY(int caretPolicy, int caretSlop)</code></a>.</p> <p><b id="SCI_SETHSCROLLBAR">SCI_SETHSCROLLBAR(bool visible)</b><br /> <b id="SCI_GETHSCROLLBAR">SCI_GETHSCROLLBAR</b><br /> The horizontal scroll bar is only displayed if it is needed for the assumed width. If you never wish to see it, call <code>SCI_SETHSCROLLBAR(0)</code>. Use <code>SCI_SETHSCROLLBAR(1)</code> to enable it again. <code>SCI_GETHSCROLLBAR</code> returns the current state. The default state is to display it when needed.</p> <p>See also: <a class="message" href="#SCI_SETSCROLLWIDTH">SCI_SETSCROLLWIDTH</a>.</p> <p><b id="SCI_SETVSCROLLBAR">SCI_SETVSCROLLBAR(bool visible)</b><br /> <b id="SCI_GETVSCROLLBAR">SCI_GETVSCROLLBAR</b><br /> By default, the vertical scroll bar is always displayed when required. You can choose to hide or show it with <code>SCI_SETVSCROLLBAR</code> and get the current state with <code>SCI_GETVSCROLLBAR</code>.</p> <p><b id="SCI_SETXOFFSET">SCI_SETXOFFSET(int xOffset)</b><br /> <b id="SCI_GETXOFFSET">SCI_GETXOFFSET</b><br /> The <code>xOffset</code> is the horizontal scroll position in pixels of the start of the text view. A value of 0 is the normal position with the first text column visible at the left of the view.</p> <p>See also: <a class="message" href="#SCI_LINESCROLL"><code>SCI_LINESCROLL</code></a></p> <p><b id="SCI_SETSCROLLWIDTH">SCI_SETSCROLLWIDTH(int pixelWidth)</b><br /> <b id="SCI_GETSCROLLWIDTH">SCI_GETSCROLLWIDTH</b><br /> For performance, Scintilla does not measure the display width of the document to determine the properties of the horizontal scroll bar. Instead, an assumed width is used. These messages set and get the document width in pixels assumed by Scintilla. The default value is 2000. To ensure the width of the currently visible lines can be scrolled use <a class="message" href="#SCI_SETSCROLLWIDTHTRACKING"><code>SCI_SETSCROLLWIDTHTRACKING</code></a></p> <p><b id="SCI_SETSCROLLWIDTHTRACKING">SCI_SETSCROLLWIDTHTRACKING(bool tracking)</b><br /> <b id="SCI_GETSCROLLWIDTHTRACKING">SCI_GETSCROLLWIDTHTRACKING</b><br /> If scroll width tracking is enabled then the scroll width is adjusted to ensure that all of the lines currently displayed can be completely scrolled. This mode never adjusts the scroll width to be narrower.</p> <p><b id="SCI_SETENDATLASTLINE">SCI_SETENDATLASTLINE(bool endAtLastLine)</b><br /> <b id="SCI_GETENDATLASTLINE">SCI_GETENDATLASTLINE</b><br /> <code>SCI_SETENDATLASTLINE</code> sets the scroll range so that maximum scroll position has the last line at the bottom of the view (default). Setting this to <code>false</code> allows scrolling one page below the last line.</p> <h2 id="WhiteSpace">White space</h2> <code><a class="message" href="#SCI_SETVIEWWS">SCI_SETVIEWWS(int wsMode)</a><br /> <a class="message" href="#SCI_GETVIEWWS">SCI_GETVIEWWS</a><br /> <a class="message" href="#SCI_SETWHITESPACEFORE">SCI_SETWHITESPACEFORE(bool useWhitespaceForeColour, int colour)</a><br /> <a class="message" href="#SCI_SETWHITESPACEBACK">SCI_SETWHITESPACEBACK(bool useWhitespaceBackColour, int colour)</a><br /> <a class="message" href="#SCI_SETWHITESPACESIZE">SCI_SETWHITESPACESIZE(int size)</a><br /> <a class="message" href="#SCI_GETWHITESPACESIZE">SCI_GETWHITESPACESIZE</a><br /> <a class="message" href="#SCI_SETEXTRAASCENT">SCI_SETEXTRAASCENT(int extraAscent)</a><br /> <a class="message" href="#SCI_GETEXTRAASCENT">SCI_GETEXTRAASCENT</a><br /> <a class="message" href="#SCI_SETEXTRADESCENT">SCI_SETEXTRADESCENT(int extraDescent)</a><br /> <a class="message" href="#SCI_GETEXTRADESCENT">SCI_GETEXTRADESCENT</a><br /> </code> <p><b id="SCI_SETVIEWWS">SCI_SETVIEWWS(int wsMode)</b><br /> <b id="SCI_GETVIEWWS">SCI_GETVIEWWS</b><br /> White space can be made visible which may be useful for languages in which white space is significant, such as Python. Space characters appear as small centred dots and tab characters as light arrows pointing to the right. There are also ways to control the display of <a class="jump" href="#LineEndings">end of line characters</a>. The two messages set and get the white space display mode. The <code>wsMode</code> argument can be one of:</p> <table cellpadding="1" cellspacing="2" border="0" summary="White space policy"> <tbody valign="top"> <tr> <th align="left"><code>SCWS_INVISIBLE</code></th> <td>0</td> <td>The normal display mode with white space displayed as an empty background colour.</td> </tr> <tr> <th align="left"><code>SCWS_VISIBLEALWAYS</code></th> <td>1</td> <td>White space characters are drawn as dots and arrows,</td> </tr> <tr> <th align="left"><code>SCWS_VISIBLEAFTERINDENT</code></th> <td>2</td> <td>White space used for indentation is displayed normally but after the first visible character, it is shown as dots and arrows.</td> </tr> </tbody> </table> <p>The effect of using any other <code>wsMode</code> value is undefined.</p> <p><b id="SCI_SETWHITESPACEFORE">SCI_SETWHITESPACEFORE(bool useWhitespaceForeColour, int <a class="jump" href="#colour">colour</a>)</b><br /> <b id="SCI_SETWHITESPACEBACK">SCI_SETWHITESPACEBACK(bool useWhitespaceBackColour, int <a class="jump" href="#colour">colour</a>)</b><br /> By default, the colour of visible white space is determined by the lexer in use. The foreground and/or background colour of all visible white space can be set globally, overriding the lexer's colours with <code>SCI_SETWHITESPACEFORE</code> and <code>SCI_SETWHITESPACEBACK</code>.</p> <p><b id="SCI_SETWHITESPACESIZE">SCI_SETWHITESPACESIZE(int size)</b><br /> <b id="SCI_GETWHITESPACESIZE">SCI_GETWHITESPACESIZE</b><br /> <code>SCI_SETWHITESPACESIZE</code> sets the size of the dots used for mark space characters. The <code>SCI_GETWHITESPACESIZE</code> message retrieves the current size. </p> <p> <b id="SCI_SETEXTRAASCENT">SCI_SETEXTRAASCENT(int extraAscent)</b><br /> <b id="SCI_GETEXTRAASCENT">SCI_GETEXTRAASCENT</b><br /> <b id="SCI_SETEXTRADESCENT">SCI_SETEXTRADESCENT(int extraDescent)</b><br /> <b id="SCI_GETEXTRADESCENT">SCI_GETEXTRADESCENT</b><br /> Text is drawn with the base of each character on a 'baseline'. The height of a line is found from the maximum that any style extends above the baseline (its 'ascent'), added to the maximum that any style extends below the baseline (its 'descent'). Space may be added to the maximum ascent (<code>SCI_SETEXTRAASCENT</code>) and the maximum descent (<code>SCI_SETEXTRADESCENT</code>) to allow for more space between lines. This may done to make the text easier to read or to accomodate underlines or highlights. </p> <h2 id="Cursor">Cursor</h2> <p><b id="SCI_SETCURSOR">SCI_SETCURSOR(int curType)</b><br /> <b id="SCI_GETCURSOR">SCI_GETCURSOR</b><br /> The cursor is normally chosen in a context sensitive way, so it will be different over the margin than when over the text. When performing a slow action, you may wish to change to a wait cursor. You set the cursor type with <code>SCI_SETCURSOR</code>. The <code>curType</code> argument can be:</p> <table cellpadding="1" cellspacing="2" border="0" summary="Mouse cursors"> <tbody valign="top"> <tr> <th align="left"><code>SC_CURSORNORMAL</code></th> <td>-1</td> <td>The normal cursor is displayed.</td> </tr> <tr> <th align="left"><code>SC_CURSORWAIT</code></th> <td> 4</td> <td>The wait cursor is displayed when the mouse is over or owned by the Scintilla window.</td> </tr> </tbody> </table> <p>Cursor values 1 through 7 have defined cursors, but only <code>SC_CURSORWAIT</code> is usefully controllable. Other values of <code>curType</code> cause a pointer to be displayed. The <code>SCI_GETCURSOR</code> message returns the last cursor type you set, or <code>SC_CURSORNORMAL</code> (-1) if you have not set a cursor type.</p> <h2 id="MouseCapture">Mouse capture</h2> <p><b id="SCI_SETMOUSEDOWNCAPTURES">SCI_SETMOUSEDOWNCAPTURES(bool captures)</b><br /> <b id="SCI_GETMOUSEDOWNCAPTURES">SCI_GETMOUSEDOWNCAPTURES</b><br /> When the mouse is pressed inside Scintilla, it is captured so future mouse movement events are sent to Scintilla. This behavior may be turned off with <code>SCI_SETMOUSEDOWNCAPTURES(0)</code>.</p> <h2 id="LineEndings">Line endings</h2> <p>Scintilla can handle the major line end conventions <span class="provisional">and, depending on settings and the current lexer also support additional Unicode line ends</span>.</p> <p>Scintilla can interpret any of the Macintosh (\r), Unix (\n) and Windows (\r\n) line ends. When the user presses the Enter key, one of these line end strings is inserted into the buffer. The default is \r\n in Windows and \n in Unix, but this can be changed with the <code>SCI_SETEOLMODE</code> message. You can also convert the entire document to one of these line endings with <code>SCI_CONVERTEOLS</code>. Finally, you can choose to display the line endings with <code>SCI_SETVIEWEOL</code>.</p> <div class="provisional"> <p>For the UTF-8 encoding, three additional Unicode line ends, Next Line (<code>NEL=U+0085</code>), Line Separator (<code>LS=U+2028</code>), and Paragraph Separator (<code>PS=U+2029</code>) may optionally be interpreted when Unicode line ends is turned on and the current lexer also supports Unicode line ends.</p> </div> <code><a class="message" href="#SCI_SETEOLMODE">SCI_SETEOLMODE(int eolMode)</a><br /> <a class="message" href="#SCI_GETEOLMODE">SCI_GETEOLMODE</a><br /> <a class="message" href="#SCI_CONVERTEOLS">SCI_CONVERTEOLS(int eolMode)</a><br /> <a class="message" href="#SCI_SETVIEWEOL">SCI_SETVIEWEOL(bool visible)</a><br /> <a class="message" href="#SCI_GETVIEWEOL">SCI_GETVIEWEOL</a><br /> <div class="provisional"> <a class="message" href="#SCI_GETLINEENDTYPESSUPPORTED">SCI_GETLINEENDTYPESSUPPORTED</a><br /> <a class="message" href="#SCI_SETLINEENDTYPESALLOWED">SCI_SETLINEENDTYPESALLOWED(int lineEndBitSet)</a><br /> <a class="message" href="#SCI_GETLINEENDTYPESALLOWED">SCI_GETLINEENDTYPESALLOWED</a><br /> <a class="message" href="#SCI_GETLINEENDTYPESACTIVE">SCI_GETLINEENDTYPESACTIVE</a><br /> </div> </code> <p><b id="SCI_SETEOLMODE">SCI_SETEOLMODE(int eolMode)</b><br /> <b id="SCI_GETEOLMODE">SCI_GETEOLMODE</b><br /> <code>SCI_SETEOLMODE</code> sets the characters that are added into the document when the user presses the Enter key. You can set <code>eolMode</code> to one of <code>SC_EOL_CRLF</code> (0), <code>SC_EOL_CR</code> (1), or <code>SC_EOL_LF</code> (2). The <code>SCI_GETEOLMODE</code> message retrieves the current state.</p> <p><b id="SCI_CONVERTEOLS">SCI_CONVERTEOLS(int eolMode)</b><br /> This message changes all the end of line characters in the document to match <code>eolMode</code>. Valid values are: <code>SC_EOL_CRLF</code> (0), <code>SC_EOL_CR</code> (1), or <code>SC_EOL_LF</code> (2).</p> <p><b id="SCI_SETVIEWEOL">SCI_SETVIEWEOL(bool visible)</b><br /> <b id="SCI_GETVIEWEOL">SCI_GETVIEWEOL</b><br /> Normally, the end of line characters are hidden, but <code>SCI_SETVIEWEOL</code> allows you to display (or hide) them by setting <code>visible</code> <code>true</code> (or <code>false</code>). The visible rendering of the end of line characters is similar to <code>(CR)</code>, <code>(LF)</code>, or <code>(CR)(LF)</code>. <code>SCI_GETVIEWEOL</code> returns the current state.</p> <div class="provisional"> <a href="#ProvisionalMessages">These features are provisional</a><br /> <p><b id="SCI_GETLINEENDTYPESSUPPORTED">SCI_GETLINEENDTYPESSUPPORTED</b><br /> <code>SCI_GETLINEENDTYPESSUPPORTED</code> reports the different types of line ends supported by the current lexer. This is a bit set although there is currently only a single choice with either <code>SC_LINE_END_TYPE_DEFAULT</code> (0) or <code>SC_LINE_END_TYPE_UNICODE</code> (1). These values are also used by the other messages concerned with Unicode line ends.</p> <p><b id="SCI_SETLINEENDTYPESALLOWED">SCI_SETLINEENDTYPESALLOWED(int lineEndBitSet)</b><br /> <b id="SCI_GETLINEENDTYPESALLOWED">SCI_GETLINEENDTYPESALLOWED</b><br /> By default, only the ASCII line ends are interpreted. Unicode line ends may be requested with <code>SCI_SETLINEENDTYPESALLOWED(SC_LINE_END_TYPE_UNICODE)</code> but this will be ineffective unless the lexer also allows you Unicode line ends. <code>SCI_GETLINEENDTYPESALLOWED</code> returns the current state.</p> <p><b id="SCI_GETLINEENDTYPESACTIVE">SCI_GETLINEENDTYPESACTIVE</b><br /> <code>SCI_GETLINEENDTYPESACTIVE</code> reports the set of line ends currently interpreted by Scintilla. It is <code>SCI_GETLINEENDTYPESSUPPORTED & SCI_GETLINEENDTYPESALLOWED</code>.</p> </div> <h2 id="Styling">Styling</h2> <p>The styling messages allow you to assign styles to text. The standard Scintilla settings divide the 8 style bits available for each character into 5 bits (0 to 4 = <a class="jump" href="#StyleDefinition">styles 0 to 31</a>) that set a style and three bits (5 to 7) that define <a class="jump" href="#Indicators">indicators</a>. You can change the balance between styles and indicators with <a class="message" href="#SCI_SETSTYLEBITS"><code>SCI_SETSTYLEBITS</code></a>. If your styling needs can be met by one of the standard lexers, or if you can write your own, then a lexer is probably the easiest way to style your document. If you choose to use the container to do the styling you can use the <a class="message" href="#SCI_SETLEXER"><code>SCI_SETLEXER</code></a> command to select <code>SCLEX_CONTAINER</code>, in which case the container is sent a <a class="message" href="#SCN_STYLENEEDED"><code>SCN_STYLENEEDED</code></a> <a class="jump" href="#Notifications">notification</a> each time text needs styling for display. As another alternative, you might use idle time to style the document. Even if you use a lexer, you might use the styling commands to mark errors detected by a compiler. The following commands can be used.</p> <code><a class="message" href="#SCI_GETENDSTYLED">SCI_GETENDSTYLED</a><br /> <a class="message" href="#SCI_STARTSTYLING">SCI_STARTSTYLING(int position, int mask)</a><br /> <a class="message" href="#SCI_SETSTYLING">SCI_SETSTYLING(int length, int style)</a><br /> <a class="message" href="#SCI_SETSTYLINGEX">SCI_SETSTYLINGEX(int length, const char *styles)</a><br /> <a class="message" href="#SCI_SETLINESTATE">SCI_SETLINESTATE(int line, int value)</a><br /> <a class="message" href="#SCI_GETLINESTATE">SCI_GETLINESTATE(int line)</a><br /> <a class="message" href="#SCI_GETMAXLINESTATE">SCI_GETMAXLINESTATE</a><br /> </code> <p><b id="SCI_GETENDSTYLED">SCI_GETENDSTYLED</b><br /> Scintilla keeps a record of the last character that is likely to be styled correctly. This is moved forwards when characters after it are styled and moved backwards if changes are made to the text of the document before it. Before drawing text, this position is checked to see if any styling is needed and, if so, a <code><a class="message" href="#SCN_STYLENEEDED">SCN_STYLENEEDED</a></code> notification message is sent to the container. The container can send <code>SCI_GETENDSTYLED</code> to work out where it needs to start styling. Scintilla will always ask to style whole lines.</p> <p><b id="SCI_STARTSTYLING">SCI_STARTSTYLING(int pos, int mask)</b><br /> This prepares for styling by setting the styling position <code>pos</code> to start at and a <code>mask</code> indicating which bits of the style bytes can be set. The mask allows styling to occur over several passes, with, for example, basic styling done on an initial pass to ensure that the text of the code is seen quickly and correctly, and then a second slower pass, detecting syntax errors and using indicators to show where these are. For example, with the standard settings of 5 style bits and 3 indicator bits, you would use a <code>mask</code> value of 31 (0x1f) if you were setting text styles and did not want to change the indicators. After <code>SCI_STARTSTYLING</code>, send multiple <code>SCI_SETSTYLING</code> messages for each lexical entity to style.</p> <p><b id="SCI_SETSTYLING">SCI_SETSTYLING(int length, int style)</b><br /> This message sets the style of <code>length</code> characters starting at the styling position and then increases the styling position by <code>length</code>, ready for the next call. If <code>sCell</code> is the style byte, the operation is:<br /> <code>if ((sCell & mask) != style) sCell = (sCell & ~mask) | (style & mask);</code><br /> </p> <p><b id="SCI_SETSTYLINGEX">SCI_SETSTYLINGEX(int length, const char *styles)</b><br /> As an alternative to <code>SCI_SETSTYLING</code>, which applies the same style to each byte, you can use this message which specifies the styles for each of <code>length</code> bytes from the styling position and then increases the styling position by <code>length</code>, ready for the next call. The <code>length</code> styling bytes pointed at by <code>styles</code> should not contain any bits not set in mask.</p> <p><b id="SCI_SETLINESTATE">SCI_SETLINESTATE(int line, int value)</b><br /> <b id="SCI_GETLINESTATE">SCI_GETLINESTATE(int line)</b><br /> As well as the 8 bits of lexical state stored for each character there is also an integer stored for each line. This can be used for longer lived parse states such as what the current scripting language is in an ASP page. Use <code>SCI_SETLINESTATE</code> to set the integer value and <code>SCI_GETLINESTATE</code> to get the value. Changing the value produces a <a class="message" href="#SC_MOD_CHANGELINESTATE">SC_MOD_CHANGELINESTATE</a> notification. </p> <p><b id="SCI_GETMAXLINESTATE">SCI_GETMAXLINESTATE</b><br /> This returns the last line that has any line state.</p> <h2 id="StyleDefinition">Style definition</h2> <p>While the style setting messages mentioned above change the style numbers associated with text, these messages define how those style numbers are interpreted visually. There are 256 lexer styles that can be set, numbered 0 to <code>STYLE_MAX</code> (255). Unless you use <a class="message" href="#SCI_SETSTYLEBITS"><code>SCI_SETSTYLEBITS</code></a> to change the number of style bits, styles 0 to 31 are used to set the text attributes. There are also some predefined numbered styles starting at 32, The following <code>STYLE_</code>* constants are defined.</p> <table cellpadding="1" cellspacing="2" border="0" summary="Preset styles"> <tbody valign="top"> <tr> <th align="left"><code>STYLE_DEFAULT</code></th> <td>32</td> <td>This style defines the attributes that all styles receive when the <code>SCI_STYLECLEARALL</code> message is used.</td> </tr> <tr> <th align="left"><code>STYLE_LINENUMBER</code></th> <td>33</td> <td>This style sets the attributes of the text used to display line numbers in a line number margin. The background colour set for this style also sets the background colour for all margins that do not have any folding mask bits set. That is, any margin for which <code>mask & SC_MASK_FOLDERS</code> is 0. See <a class="message" href="#SCI_SETMARGINMASKN"><code>SCI_SETMARGINMASKN</code></a> for more about masks.</td> </tr> <tr> <th align="left"><code>STYLE_BRACELIGHT</code></th> <td>34</td> <td>This style sets the attributes used when highlighting braces with the <a class="message" href="#BraceHighlighting"><code>SCI_BRACEHIGHLIGHT</code></a> message and when highlighting the corresponding indentation with <a class="message" href="#SCI_SETHIGHLIGHTGUIDE"><code>SCI_SETHIGHLIGHTGUIDE</code></a>.</td> </tr> <tr> <th align="left"><code>STYLE_BRACEBAD</code></th> <td>35</td> <td>This style sets the display attributes used when marking an unmatched brace with the <a class="message" href="#BraceHighlighting"><code>SCI_BRACEBADLIGHT</code></a> message.</td> </tr> <tr> <th align="left"><code>STYLE_CONTROLCHAR</code></th> <td>36</td> <td>This style sets the font used when drawing control characters. Only the font, size, bold, italics, and character set attributes are used and not the colour attributes. See also: <a class="message" href="#SCI_SETCONTROLCHARSYMBOL"><code>SCI_SETCONTROLCHARSYMBOL</code></a>.</td> </tr> <tr> <th align="left"><code>STYLE_INDENTGUIDE</code></th> <td>37</td> <td>This style sets the foreground and background colours used when drawing the indentation guides.</td> </tr> <tr> <th align="left"><code>STYLE_CALLTIP</code></th> <td>38</td> <td> Call tips normally use the font attributes defined by <code>STYLE_DEFAULT</code>. Use of <a class="message" href="#SCI_CALLTIPUSESTYLE"><code>SCI_CALLTIPUSESTYLE</code></a> causes call tips to use this style instead. Only the font face name, font size, foreground and background colours and character set attributes are used.</td> </tr> <tr> <th align="left"><code>STYLE_LASTPREDEFINED</code></th> <td>39</td> <td>To make it easier for client code to discover the range of styles that are predefined, this is set to the style number of the last predefined style. This is currently set to 39 and the last style with an identifier is 38, which reserves space for one future predefined style.</td> </tr> <tr> <th align="left"><code>STYLE_MAX</code></th> <td>255</td> <td>This is not a style but is the number of the maximum style that can be set. Styles between <code>STYLE_LASTPREDEFINED</code> and <code>STYLE_MAX</code> would be appropriate if you used <a class="message" href="#SCI_SETSTYLEBITS"><code>SCI_SETSTYLEBITS</code></a> to set more than 5 style bits.</td> </tr> </tbody> </table> <p>For each style you can set the font name, size and use of bold, italic and underline, foreground and background colour and the character set. You can also choose to hide text with a given style, display all characters as upper or lower case and fill from the last character on a line to the end of the line (for embedded languages). There is also an experimental attribute to make text read-only.</p> <p>It is entirely up to you how you use styles. If you want to use syntax colouring you might use style 0 for white space, style 1 for numbers, style 2 for keywords, style 3 for strings, style 4 for preprocessor, style 5 for operators, and so on.</p> <code><a class="message" href="#SCI_STYLERESETDEFAULT">SCI_STYLERESETDEFAULT</a><br /> <a class="message" href="#SCI_STYLECLEARALL">SCI_STYLECLEARALL</a><br /> <a class="message" href="#SCI_STYLESETFONT">SCI_STYLESETFONT(int styleNumber, char *fontName)</a><br /> <a class="message" href="#SCI_STYLEGETFONT">SCI_STYLEGETFONT(int styleNumber, char *fontName)</a><br /> <a class="message" href="#SCI_STYLESETSIZE">SCI_STYLESETSIZE(int styleNumber, int sizeInPoints)</a><br /> <a class="message" href="#SCI_STYLEGETSIZE">SCI_STYLEGETSIZE(int styleNumber)</a><br /> <a class="message" href="#SCI_STYLESETSIZEFRACTIONAL">SCI_STYLESETSIZEFRACTIONAL(int styleNumber, int sizeInHundredthPoints)</a><br /> <a class="message" href="#SCI_STYLEGETSIZEFRACTIONAL">SCI_STYLEGETSIZEFRACTIONAL(int styleNumber)</a><br /> <a class="message" href="#SCI_STYLESETBOLD">SCI_STYLESETBOLD(int styleNumber, bool bold)</a><br /> <a class="message" href="#SCI_STYLEGETBOLD">SCI_STYLEGETBOLD(int styleNumber)</a><br /> <a class="message" href="#SCI_STYLESETWEIGHT">SCI_STYLESETWEIGHT(int styleNumber, int weight)</a><br /> <a class="message" href="#SCI_STYLEGETWEIGHT">SCI_STYLEGETWEIGHT(int styleNumber)</a><br /> <a class="message" href="#SCI_STYLESETITALIC">SCI_STYLESETITALIC(int styleNumber, bool italic)</a><br /> <a class="message" href="#SCI_STYLEGETITALIC">SCI_STYLEGETITALIC(int styleNumber)</a><br /> <a class="message" href="#SCI_STYLESETUNDERLINE">SCI_STYLESETUNDERLINE(int styleNumber, bool underline)</a><br /> <a class="message" href="#SCI_STYLEGETUNDERLINE">SCI_STYLEGETUNDERLINE(int styleNumber)</a><br /> <a class="message" href="#SCI_STYLESETFORE">SCI_STYLESETFORE(int styleNumber, int colour)</a><br /> <a class="message" href="#SCI_STYLEGETFORE">SCI_STYLEGETFORE(int styleNumber)</a><br /> <a class="message" href="#SCI_STYLESETBACK">SCI_STYLESETBACK(int styleNumber, int colour)</a><br /> <a class="message" href="#SCI_STYLEGETBACK">SCI_STYLEGETBACK(int styleNumber)</a><br /> <a class="message" href="#SCI_STYLESETEOLFILLED">SCI_STYLESETEOLFILLED(int styleNumber, bool eolFilled)</a><br /> <a class="message" href="#SCI_STYLEGETEOLFILLED">SCI_STYLEGETEOLFILLED(int styleNumber)</a><br /> <a class="message" href="#SCI_STYLESETCHARACTERSET">SCI_STYLESETCHARACTERSET(int styleNumber, int charSet)</a><br /> <a class="message" href="#SCI_STYLEGETCHARACTERSET">SCI_STYLEGETCHARACTERSET(int styleNumber)</a><br /> <a class="message" href="#SCI_STYLESETCASE">SCI_STYLESETCASE(int styleNumber, int caseMode)</a><br /> <a class="message" href="#SCI_STYLEGETCASE">SCI_STYLEGETCASE(int styleNumber)</a><br /> <a class="message" href="#SCI_STYLESETVISIBLE">SCI_STYLESETVISIBLE(int styleNumber, bool visible)</a><br /> <a class="message" href="#SCI_STYLEGETVISIBLE">SCI_STYLEGETVISIBLE(int styleNumber)</a><br /> <a class="message" href="#SCI_STYLESETCHANGEABLE">SCI_STYLESETCHANGEABLE(int styleNumber, bool changeable)</a><br /> <a class="message" href="#SCI_STYLEGETCHANGEABLE">SCI_STYLEGETCHANGEABLE(int styleNumber)</a><br /> <a class="message" href="#SCI_STYLESETHOTSPOT">SCI_STYLESETHOTSPOT(int styleNumber, bool hotspot)</a><br /> <a class="message" href="#SCI_STYLEGETHOTSPOT">SCI_STYLEGETHOTSPOT(int styleNumber)</a><br /> </code> <p><b id="SCI_STYLERESETDEFAULT">SCI_STYLERESETDEFAULT</b><br /> This message resets <code>STYLE_DEFAULT</code> to its state when Scintilla was initialised.</p> <p><b id="SCI_STYLECLEARALL">SCI_STYLECLEARALL</b><br /> This message sets all styles to have the same attributes as <code>STYLE_DEFAULT</code>. If you are setting up Scintilla for syntax colouring, it is likely that the lexical styles you set will be very similar. One way to set the styles is to:<br /> 1. Set <code>STYLE_DEFAULT</code> to the common features of all styles.<br /> 2. Use <code>SCI_STYLECLEARALL</code> to copy this to all styles.<br /> 3. Set the style attributes that make your lexical styles different.</p> <p><b id="SCI_STYLESETFONT">SCI_STYLESETFONT(int styleNumber, const char *fontName)</b><br /> <b id="SCI_STYLEGETFONT">SCI_STYLEGETFONT(int styleNumber, char *fontName)</b><br /> <b id="SCI_STYLESETSIZE">SCI_STYLESETSIZE(int styleNumber, int sizeInPoints)</b><br /> <b id="SCI_STYLEGETSIZE">SCI_STYLEGETSIZE(int styleNumber)</b><br /> <b id="SCI_STYLESETSIZEFRACTIONAL">SCI_STYLESETSIZEFRACTIONAL(int styleNumber, int sizeInHundredthPoints)</b><br /> <b id="SCI_STYLEGETSIZEFRACTIONAL">SCI_STYLEGETSIZEFRACTIONAL(int styleNumber)</b><br /> <b id="SCI_STYLESETBOLD">SCI_STYLESETBOLD(int styleNumber, bool bold)</b><br /> <b id="SCI_STYLEGETBOLD">SCI_STYLEGETBOLD(int styleNumber)</b><br /> <b id="SCI_STYLESETWEIGHT">SCI_STYLESETWEIGHT(int styleNumber, int weight)</b><br /> <b id="SCI_STYLEGETWEIGHT">SCI_STYLEGETWEIGHT(int styleNumber)</b><br /> <b id="SCI_STYLESETITALIC">SCI_STYLESETITALIC(int styleNumber, bool italic)</b><br /> <b id="SCI_STYLEGETITALIC">SCI_STYLEGETITALIC(int styleNumber)</b><br /> These messages (plus <a class="message" href="#SCI_STYLESETCHARACTERSET"><code>SCI_STYLESETCHARACTERSET</code></a>) set the font attributes that are used to match the fonts you request to those available. The <code>fontName</code> is a zero terminated string holding the name of a font. Under Windows, only the first 32 characters of the name are used and the name is not case sensitive. For internal caching, Scintilla tracks fonts by name and does care about the casing of font names, so please be consistent. On GTK+, Pango is used to display text.</p> <p>Sizes can be set to a whole number of points with <code>SCI_STYLESETSIZE</code> or to a fractional point size in hundredths of a point with <code>SCI_STYLESETSIZEFRACTIONAL</code> by multiplying the size by 100 (<code>SC_FONT_SIZE_MULTIPLIER</code>). For example, a text size of 9.4 points is set with <code>SCI_STYLESETSIZEFRACTIONAL(<style>, 940)</code>. </p> <p>The weight or boldness of a font can be set with <code>SCI_STYLESETBOLD</code> or <code>SCI_STYLESETWEIGHT</code>. The weight is a number between 1 and 999 with 1 being very light and 999 very heavy. While any value can be used, fonts often only support between 2 and 4 weights with three weights being common enough to have symbolic names: <code>SC_WEIGHT_NORMAL</code> (400), <code>SC_WEIGHT_SEMIBOLD</code> (600), and <code>SC_WEIGHT_BOLD</code> (700). The <code>SCI_STYLESETBOLD</code> message takes a boolean argument with 0 choosing <code>SC_WEIGHT_NORMAL</code> and 1 <code>SC_WEIGHT_BOLD</code>. </p> <p><b id="SCI_STYLESETUNDERLINE">SCI_STYLESETUNDERLINE(int styleNumber, bool underline)</b><br /> <b id="SCI_STYLEGETUNDERLINE">SCI_STYLEGETUNDERLINE(int styleNumber)</b><br /> You can set a style to be underlined. The underline is drawn in the foreground colour. All characters with a style that includes the underline attribute are underlined, even if they are white space.</p> <p><b id="SCI_STYLESETFORE">SCI_STYLESETFORE(int styleNumber, int <a class="jump" href="#colour">colour</a>)</b><br /> <b id="SCI_STYLEGETFORE">SCI_STYLEGETFORE(int styleNumber)</b><br /> <b id="SCI_STYLESETBACK">SCI_STYLESETBACK(int styleNumber, int <a class="jump" href="#colour">colour</a>)</b><br /> <b id="SCI_STYLEGETBACK">SCI_STYLEGETBACK(int styleNumber)</b><br /> Text is drawn in the foreground colour. The space in each character cell that is not occupied by the character is drawn in the background colour.</p> <p><b id="SCI_STYLESETEOLFILLED">SCI_STYLESETEOLFILLED(int styleNumber, bool eolFilled)</b><br /> <b id="SCI_STYLEGETEOLFILLED">SCI_STYLEGETEOLFILLED(int styleNumber)</b><br /> If the last character in the line has a style with this attribute set, the remainder of the line up to the right edge of the window is filled with the background colour set for the last character. This is useful when a document contains embedded sections in another language such as HTML pages with embedded JavaScript. By setting <code>eolFilled</code> to <code>true</code> and a consistent background colour (different from the background colour set for the HTML styles) to all JavaScript styles then JavaScript sections will be easily distinguished from HTML.</p> <p><b id="SCI_STYLESETCHARACTERSET">SCI_STYLESETCHARACTERSET(int styleNumber, int charSet)</b><br /> <b id="SCI_STYLEGETCHARACTERSET">SCI_STYLEGETCHARACTERSET(int styleNumber)</b><br /> You can set a style to use a different character set than the default. The places where such characters sets are likely to be useful are comments and literal strings. For example, <code>SCI_STYLESETCHARACTERSET(SCE_C_STRING, SC_CHARSET_RUSSIAN)</code> would ensure that strings in Russian would display correctly in C and C++ (<code>SCE_C_STRING</code> is the style number used by the C and C++ lexer to display literal strings; it has the value 6). This feature works differently on Windows and GTK+.</p> <p>The character sets supported on Windows are:<br /> <code>SC_CHARSET_ANSI</code>, <code>SC_CHARSET_ARABIC</code>, <code>SC_CHARSET_BALTIC</code>, <code>SC_CHARSET_CHINESEBIG5</code>, <code>SC_CHARSET_DEFAULT</code>, <code>SC_CHARSET_EASTEUROPE</code>, <code>SC_CHARSET_GB2312</code>, <code>SC_CHARSET_GREEK</code>, <code>SC_CHARSET_HANGUL</code>, <code>SC_CHARSET_HEBREW</code>, <code>SC_CHARSET_JOHAB</code>, <code>SC_CHARSET_MAC</code>, <code>SC_CHARSET_OEM</code>, <code>SC_CHARSET_RUSSIAN</code> (code page 1251), <code>SC_CHARSET_SHIFTJIS</code>, <code>SC_CHARSET_SYMBOL</code>, <code>SC_CHARSET_THAI</code>, <code>SC_CHARSET_TURKISH</code>, and <code>SC_CHARSET_VIETNAMESE</code>.</p> <p>The character sets supported on GTK+ are:<br /> <code>SC_CHARSET_ANSI</code>, <code>SC_CHARSET_CYRILLIC</code> (code page 1251), <code>SC_CHARSET_EASTEUROPE</code>, <code>SC_CHARSET_GB2312</code>, <code>SC_CHARSET_HANGUL</code>, <code>SC_CHARSET_RUSSIAN</code> (KOI8-R), <code>SC_CHARSET_SHIFTJIS</code>, and <code>SC_CHARSET_8859_15</code>.</p> <p><b id="SCI_STYLESETCASE">SCI_STYLESETCASE(int styleNumber, int caseMode)</b><br /> <b id="SCI_STYLEGETCASE">SCI_STYLEGETCASE(int styleNumber)</b><br /> The value of caseMode determines how text is displayed. You can set upper case (<code>SC_CASE_UPPER</code>, 1) or lower case (<code>SC_CASE_LOWER</code>, 2) or display normally (<code>SC_CASE_MIXED</code>, 0). This does not change the stored text, only how it is displayed.</p> <p><b id="SCI_STYLESETVISIBLE">SCI_STYLESETVISIBLE(int styleNumber, bool visible)</b><br /> <b id="SCI_STYLEGETVISIBLE">SCI_STYLEGETVISIBLE(int styleNumber)</b><br /> Text is normally visible. However, you can completely hide it by giving it a style with the <code>visible</code> set to 0. This could be used to hide embedded formatting instructions or hypertext keywords in HTML or XML.</p> <p><b id="SCI_STYLESETCHANGEABLE">SCI_STYLESETCHANGEABLE(int styleNumber, bool changeable)</b><br /> <b id="SCI_STYLEGETCHANGEABLE">SCI_STYLEGETCHANGEABLE(int styleNumber)</b><br /> This is an experimental and incompletely implemented style attribute. The default setting is <code>changeable</code> set <code>true</code> but when set <code>false</code> it makes text read-only. Currently it only stops the caret from being within not-changeable text and does not yet stop deleting a range that contains not-changeable text.</p> <p><b id="SCI_STYLESETHOTSPOT">SCI_STYLESETHOTSPOT(int styleNumber, bool hotspot)</b><br /> <b id="SCI_STYLEGETHOTSPOT">SCI_STYLEGETHOTSPOT(int styleNumber)</b><br /> This style is used to mark ranges of text that can detect mouse clicks. The cursor changes to a hand over hotspots, and the foreground, and background colours may change and an underline appear to indicate that these areas are sensitive to clicking. This may be used to allow hyperlinks to other documents.</p> <h2 id="CaretAndSelectionStyles">Caret, selection, and hotspot styles</h2> <p>The selection is shown by changing the foreground and/or background colours. If one of these is not set then that attribute is not changed for the selection. The default is to show the selection by changing the background to light gray and leaving the foreground the same as when it was not selected. When there is no selection, the current insertion point is marked by the text caret. This is a vertical line that is normally blinking on and off to attract the users attention.</p> <code><a class="message" href="#SCI_SETSELFORE">SCI_SETSELFORE(bool useSelectionForeColour, int colour)</a><br /> <a class="message" href="#SCI_SETSELBACK">SCI_SETSELBACK(bool useSelectionBackColour, int colour)</a><br /> <a class="message" href="#SCI_SETSELALPHA">SCI_SETSELALPHA(int alpha)</a><br /> <a class="message" href="#SCI_GETSELALPHA">SCI_GETSELALPHA</a><br /> <a class="message" href="#SCI_SETSELEOLFILLED">SCI_SETSELEOLFILLED(bool filled)</a><br /> <a class="message" href="#SCI_GETSELEOLFILLED">SCI_GETSELEOLFILLED</a><br /> <a class="message" href="#SCI_SETCARETFORE">SCI_SETCARETFORE(int colour)</a><br /> <a class="message" href="#SCI_GETCARETFORE">SCI_GETCARETFORE</a><br /> <a class="message" href="#SCI_SETCARETLINEVISIBLE">SCI_SETCARETLINEVISIBLE(bool show)</a><br /> <a class="message" href="#SCI_GETCARETLINEVISIBLE">SCI_GETCARETLINEVISIBLE</a><br /> <a class="message" href="#SCI_SETCARETLINEBACK">SCI_SETCARETLINEBACK(int colour)</a><br /> <a class="message" href="#SCI_GETCARETLINEBACK">SCI_GETCARETLINEBACK</a><br /> <a class="message" href="#SCI_SETCARETLINEBACKALPHA">SCI_SETCARETLINEBACKALPHA(int alpha)</a><br /> <a class="message" href="#SCI_GETCARETLINEBACKALPHA">SCI_GETCARETLINEBACKALPHA</a><br /> <a class="message" href="#SCI_SETCARETLINEVISIBLEALWAYS">SCI_SETCARETLINEVISIBLEALWAYS(bool alwaysVisible)</a><br /> <a class="message" href="#SCI_GETCARETLINEVISIBLEALWAYS">SCI_GETCARETLINEVISIBLEALWAYS</a><br /> <a class="message" href="#SCI_SETCARETPERIOD">SCI_SETCARETPERIOD(int milliseconds)</a><br /> <a class="message" href="#SCI_GETCARETPERIOD">SCI_GETCARETPERIOD</a><br /> <a class="message" href="#SCI_SETCARETSTYLE">SCI_SETCARETSTYLE(int style)</a><br /> <a class="message" href="#SCI_GETCARETSTYLE">SCI_GETCARETSTYLE</a><br /> <a class="message" href="#SCI_SETCARETWIDTH">SCI_SETCARETWIDTH(int pixels)</a><br /> <a class="message" href="#SCI_GETCARETWIDTH">SCI_GETCARETWIDTH</a><br /> <a class="message" href="#SCI_SETHOTSPOTACTIVEFORE">SCI_SETHOTSPOTACTIVEFORE(bool useSetting, int colour)</a><br /> <a class="message" href="#SCI_GETHOTSPOTACTIVEFORE">SCI_GETHOTSPOTACTIVEFORE</a><br /> <a class="message" href="#SCI_SETHOTSPOTACTIVEBACK">SCI_SETHOTSPOTACTIVEBACK(bool useSetting, int colour)</a><br /> <a class="message" href="#SCI_GETHOTSPOTACTIVEBACK">SCI_GETHOTSPOTACTIVEBACK</a><br /> <a class="message" href="#SCI_SETHOTSPOTACTIVEUNDERLINE">SCI_SETHOTSPOTACTIVEUNDERLINE(bool underline)</a><br /> <a class="message" href="#SCI_GETHOTSPOTACTIVEUNDERLINE">SCI_GETHOTSPOTACTIVEUNDERLINE</a><br /> <a class="message" href="#SCI_SETHOTSPOTSINGLELINE">SCI_SETHOTSPOTSINGLELINE(bool singleLine)</a><br /> <a class="message" href="#SCI_GETHOTSPOTSINGLELINE">SCI_GETHOTSPOTSINGLELINE</a><br /> <a class="message" href="#SCI_SETCONTROLCHARSYMBOL">SCI_SETCONTROLCHARSYMBOL(int symbol)</a><br /> <a class="message" href="#SCI_GETCONTROLCHARSYMBOL">SCI_GETCONTROLCHARSYMBOL</a><br /> <a class="message" href="#SCI_SETCARETSTICKY">SCI_SETCARETSTICKY(int useCaretStickyBehaviour)</a><br /> <a class="message" href="#SCI_GETCARETSTICKY">SCI_GETCARETSTICKY</a><br /> <a class="message" href="#SCI_TOGGLECARETSTICKY">SCI_TOGGLECARETSTICKY</a><br /> </code> <p><b id="SCI_SETSELFORE">SCI_SETSELFORE(bool useSelectionForeColour, int <a class="jump" href="#colour">colour</a>)</b><br /> <b id="SCI_SETSELBACK">SCI_SETSELBACK(bool useSelectionBackColour, int <a class="jump" href="#colour">colour</a>)</b><br /> You can choose to override the default selection colouring with these two messages. The colour you provide is used if you set <code>useSelection*Colour</code> to <code>true</code>. If it is set to <code>false</code>, the default styled colouring is used and the <code>colour</code> argument has no effect.</p> <p><b id="SCI_SETSELALPHA">SCI_SETSELALPHA(int <a class="jump" href="#alpha">alpha</a>)</b><br /> <b id="SCI_GETSELALPHA">SCI_GETSELALPHA</b><br /> The selection can be drawn translucently in the selection background colour by setting an alpha value.</p> <p><b id="SCI_SETSELEOLFILLED">SCI_SETSELEOLFILLED(bool filled)</b><br /> <b id="SCI_GETSELEOLFILLED">SCI_GETSELEOLFILLED</b><br /> The selection can be drawn up to the right hand border by setting this property.</p> <p><b id="SCI_SETCARETFORE">SCI_SETCARETFORE(int <a class="jump" href="#colour">colour</a>)</b><br /> <b id="SCI_GETCARETFORE">SCI_GETCARETFORE</b><br /> The colour of the caret can be set with <code>SCI_SETCARETFORE</code> and retrieved with <code>SCI_GETCARETFORE</code>.</p> <p><b id="SCI_SETCARETLINEVISIBLE">SCI_SETCARETLINEVISIBLE(bool show)</b><br /> <b id="SCI_GETCARETLINEVISIBLE">SCI_GETCARETLINEVISIBLE</b><br /> <b id="SCI_SETCARETLINEBACK">SCI_SETCARETLINEBACK(int <a class="jump" href="#colour">colour</a>)</b><br /> <b id="SCI_GETCARETLINEBACK">SCI_GETCARETLINEBACK</b><br /> <b id="SCI_SETCARETLINEBACKALPHA">SCI_SETCARETLINEBACKALPHA(int <a class="jump" href="#alpha">alpha</a>)</b><br /> <b id="SCI_GETCARETLINEBACKALPHA">SCI_GETCARETLINEBACKALPHA</b><br /> You can choose to make the background colour of the line containing the caret different with these messages. To do this, set the desired background colour with <code>SCI_SETCARETLINEBACK</code>, then use <code>SCI_SETCARETLINEVISIBLE(true)</code> to enable the effect. You can cancel the effect with <code>SCI_SETCARETLINEVISIBLE(false)</code>. The two <code>SCI_GETCARET*</code> functions return the state and the colour. This form of background colouring has highest priority when a line has markers that would otherwise change the background colour. The caret line may also be drawn translucently which allows other background colours to show through. This is done by setting the alpha (translucency) value by calling SCI_SETCARETLINEBACKALPHA. When the alpha is not SC_ALPHA_NOALPHA, the caret line is drawn after all other features so will affect the colour of all other features. </p> <p><b id="SCI_SETCARETLINEVISIBLEALWAYS">SCI_SETCARETLINEVISIBLEALWAYS(bool alwaysVisible)</b><br /> <b id="SCI_GETCARETLINEVISIBLEALWAYS">SCI_GETCARETLINEVISIBLEALWAYS</b><br /> Choose to make the caret line always visible even when the window is not in focus. Default behaviour <code>SCI_SETCARETLINEVISIBLEALWAYS(false)</code> the caret line is only visible when the window is in focus. </p> <p><b id="SCI_SETCARETPERIOD">SCI_SETCARETPERIOD(int milliseconds)</b><br /> <b id="SCI_GETCARETPERIOD">SCI_GETCARETPERIOD</b><br /> The rate at which the caret blinks can be set with <code>SCI_SETCARETPERIOD</code> which determines the time in milliseconds that the caret is visible or invisible before changing state. Setting the period to 0 stops the caret blinking. The default value is 500 milliseconds. <code>SCI_GETCARETPERIOD</code> returns the current setting.</p> <p><b id="SCI_SETCARETSTYLE">SCI_SETCARETSTYLE(int style)</b><br /> <b id="SCI_GETCARETSTYLE">SCI_GETCARETSTYLE</b><br /> The style of the caret can be set with <code>SCI_SETCARETSTYLE</code> to be a line caret (CARETSTYLE_LINE=1), a block caret (CARETSTYLE_BLOCK=2) or to not draw at all (CARETSTYLE_INVISIBLE=0). The default value is the line caret (CARETSTYLE_LINE=1). You can determine the current caret style setting using <code>SCI_GETCARETSTYLE</code>.</p> <p>The block character draws most combining and multibyte character sequences successfully, though some fonts like Thai Fonts (and possibly others) can sometimes appear strange when the cursor is positioned at these characters, which may result in only drawing a part of the cursor character sequence. This is most notable on Windows platforms.</p> <p><b id="SCI_SETCARETWIDTH">SCI_SETCARETWIDTH(int pixels)</b><br /> <b id="SCI_GETCARETWIDTH">SCI_GETCARETWIDTH</b><br /> The width of the line caret can be set with <code>SCI_SETCARETWIDTH</code> to a value of 0, 1, 2 or 3 pixels. The default width is 1 pixel. You can read back the current width with <code>SCI_GETCARETWIDTH</code>. A width of 0 makes the caret invisible (added at version 1.50), similar to setting the caret style to CARETSTYLE_INVISIBLE (though not interchangable). This setting only affects the width of the cursor when the cursor style is set to line caret mode, it does not affect the width for a block caret.</p> <p><b id="SCI_SETHOTSPOTACTIVEFORE">SCI_SETHOTSPOTACTIVEFORE(bool useHotSpotForeColour, int <a class="jump" href="#colour">colour</a>)</b><br /> <b id="SCI_GETHOTSPOTACTIVEFORE">SCI_GETHOTSPOTACTIVEFORE</b><br /> <b id="SCI_SETHOTSPOTACTIVEBACK">SCI_SETHOTSPOTACTIVEBACK(bool useHotSpotBackColour, int <a class="jump" href="#colour">colour</a>)</b><br /> <b id="SCI_GETHOTSPOTACTIVEBACK">SCI_GETHOTSPOTACTIVEBACK</b><br /> <b id="SCI_SETHOTSPOTACTIVEUNDERLINE">SCI_SETHOTSPOTACTIVEUNDERLINE(bool underline)</b><br /> <b id="SCI_GETHOTSPOTACTIVEUNDERLINE">SCI_GETHOTSPOTACTIVEUNDERLINE</b><br /> <b id="SCI_SETHOTSPOTSINGLELINE">SCI_SETHOTSPOTSINGLELINE(bool singleLine)</b><br /> <b id="SCI_GETHOTSPOTSINGLELINE">SCI_GETHOTSPOTSINGLELINE</b><br /> While the cursor hovers over text in a style with the hotspot attribute set, the default colouring can be modified and an underline drawn with these settings. Single line mode stops a hotspot from wrapping onto next line.</p> <p><b id="SCI_SETCONTROLCHARSYMBOL">SCI_SETCONTROLCHARSYMBOL(int symbol)</b><br /> <b id="SCI_GETCONTROLCHARSYMBOL">SCI_GETCONTROLCHARSYMBOL</b><br /> By default, Scintilla displays control characters (characters with codes less than 32) in a rounded rectangle as ASCII mnemonics: "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US". These mnemonics come from the early days of signaling, though some are still used (LF = Line Feed, BS = Back Space, CR = Carriage Return, for example).</p> <p>You can choose to replace these mnemonics by a nominated symbol with an ASCII code in the range 32 to 255. If you set a symbol value less than 32, all control characters are displayed as mnemonics. The symbol you set is rendered in the font of the style set for the character. You can read back the current symbol with the <code>SCI_GETCONTROLCHARSYMBOL</code> message. The default symbol value is 0.</p> <p><b id="SCI_SETCARETSTICKY">SCI_SETCARETSTICKY(int useCaretStickyBehaviour)</b><br /> <b id="SCI_GETCARETSTICKY">SCI_GETCARETSTICKY</b><br /> <b id="SCI_TOGGLECARETSTICKY">SCI_TOGGLECARETSTICKY</b><br /> These messages set, get or toggle the caretSticky setting which controls when the last position of the caret on the line is saved.</p> <p>When set to <code>SC_CARETSTICKY_OFF</code> (0), the sticky flag is off; all text changes (and all caret position changes) will remember the caret's new horizontal position when moving to different lines. This is the default.</p> <p>When set to <code>SC_CARETSTICKY_ON</code> (1), the sticky flag is on, and the only thing which will cause the editor to remember the horizontal caret position is moving the caret with mouse or keyboard (left/right arrow keys, home/end keys, etc). </p> <p>When set to <code>SC_CARETSTICKY_WHITESPACE</code> (2), the caret acts like mode 0 (sticky off) except under one special case; when space or tab characters are inserted. (Including pasting <b>only space/tabs</b> -- undo, redo, etc. do not exhibit this behavior..).</p> <p><code>SCI_TOGGLECARETSTICKY</code> switches from <code>SC_CARETSTICKY_ON</code> and <code>SC_CARETSTICKY_WHITESPACE</code> to <code>SC_CARETSTICKY_OFF</code> and from <code>SC_CARETSTICKY_OFF</code> to <code>SC_CARETSTICKY_ON</code>.</p> <h2 id="Margins">Margins</h2> <p>There may be up to five margins, numbered 0 to <code>SC_MAX_MARGIN</code> (4) to the left of the text display, plus a gap either side of the text. Each margin can be set to display only symbols, line numbers, or text with <a class="message" href="#SCI_SETMARGINTYPEN"><code>SCI_SETMARGINTYPEN</code></a>. Textual margins may also display symbols. The markers that can be displayed in each margin are set with <a class="message" href="#SCI_SETMARGINMASKN"><code>SCI_SETMARGINMASKN</code></a>. Any markers not associated with a visible margin will be displayed as changes in background colour in the text. A width in pixels can be set for each margin. Margins with a zero width are ignored completely. You can choose if a mouse click in a margin sends a <a class="message" href="#SCN_MARGINCLICK"><code>SCN_MARGINCLICK</code></a> notification to the container or selects a line of text.</p> <p>The margins are numbered 0 to 4. Using a margin number outside the valid range has no effect. By default, margin 0 is set to display line numbers, but is given a width of 0, so it is hidden. Margin 1 is set to display non-folding symbols and is given a width of 16 pixels, so it is visible. Margin 2 is set to display the folding symbols, but is given a width of 0, so it is hidden. Of course, you can set the margins to be whatever you wish.</p> <p>Styled text margins used to show revision and blame information:</p> <p><img src="styledmargin.png" alt="Styled text margins used to show revision and blame information" /></p> <code><a class="message" href="#SCI_SETMARGINTYPEN">SCI_SETMARGINTYPEN(int margin, int type)</a><br /> <a class="message" href="#SCI_GETMARGINTYPEN">SCI_GETMARGINTYPEN(int margin)</a><br /> <a class="message" href="#SCI_SETMARGINWIDTHN">SCI_SETMARGINWIDTHN(int margin, int pixelWidth)</a><br /> <a class="message" href="#SCI_GETMARGINWIDTHN">SCI_GETMARGINWIDTHN(int margin)</a><br /> <a class="message" href="#SCI_SETMARGINMASKN">SCI_SETMARGINMASKN(int margin, int mask)</a><br /> <a class="message" href="#SCI_GETMARGINMASKN">SCI_GETMARGINMASKN(int margin)</a><br /> <a class="message" href="#SCI_SETMARGINSENSITIVEN">SCI_SETMARGINSENSITIVEN(int margin, bool sensitive)</a><br /> <a class="message" href="#SCI_GETMARGINSENSITIVEN">SCI_GETMARGINSENSITIVEN(int margin)</a><br /> <a class="message" href="#SCI_SETMARGINCURSORN">SCI_SETMARGINCURSORN(int margin, int cursor)</a><br /> <a class="message" href="#SCI_GETMARGINCURSORN">SCI_GETMARGINCURSORN(int margin)</a><br /> <a class="message" href="#SCI_SETMARGINLEFT">SCI_SETMARGINLEFT(<unused>, int pixels)</a><br /> <a class="message" href="#SCI_GETMARGINLEFT">SCI_GETMARGINLEFT</a><br /> <a class="message" href="#SCI_SETMARGINRIGHT">SCI_SETMARGINRIGHT(<unused>, int pixels)</a><br /> <a class="message" href="#SCI_GETMARGINRIGHT">SCI_GETMARGINRIGHT</a><br /> <a class="message" href="#SCI_SETFOLDMARGINCOLOUR">SCI_SETFOLDMARGINCOLOUR(bool useSetting, int colour)</a><br /> <a class="message" href="#SCI_SETFOLDMARGINHICOLOUR">SCI_SETFOLDMARGINHICOLOUR(bool useSetting, int colour)</a><br /> <a class="message" href="#SCI_MARGINSETTEXT">SCI_MARGINSETTEXT(int line, char *text)</a><br /> <a class="message" href="#SCI_MARGINGETTEXT">SCI_MARGINGETTEXT(int line, char *text)</a><br /> <a class="message" href="#SCI_MARGINSETSTYLE">SCI_MARGINSETSTYLE(int line, int style)</a><br /> <a class="message" href="#SCI_MARGINGETSTYLE">SCI_MARGINGETSTYLE(int line)</a><br /> <a class="message" href="#SCI_MARGINSETSTYLES">SCI_MARGINSETSTYLES(int line, char *styles)</a><br /> <a class="message" href="#SCI_MARGINGETSTYLES">SCI_MARGINGETSTYLES(int line, char *styles)</a><br /> <a class="message" href="#SCI_MARGINTEXTCLEARALL">SCI_MARGINTEXTCLEARALL</a><br /> <a class="message" href="#SCI_MARGINSETSTYLEOFFSET">SCI_MARGINSETSTYLEOFFSET(int style)</a><br /> <a class="message" href="#SCI_MARGINGETSTYLEOFFSET">SCI_MARGINGETSTYLEOFFSET</a><br /> <a class="message" href="#SCI_SETMARGINOPTIONS">SCI_SETMARGINOPTIONS(int marginOptions)</a><br /> <a class="message" href="#SCI_GETMARGINOPTIONS">SCI_GETMARGINOPTIONS</a><br /> </code> <p><b id="SCI_SETMARGINTYPEN">SCI_SETMARGINTYPEN(int margin, int iType)</b><br /> <b id="SCI_GETMARGINTYPEN">SCI_GETMARGINTYPEN(int margin)</b><br /> These two routines set and get the type of a margin. The margin argument should be 0, 1, 2, 3 or 4. You can use the predefined constants <code>SC_MARGIN_SYMBOL</code> (0) and <code>SC_MARGIN_NUMBER</code> (1) to set a margin as either a line number or a symbol margin. A margin with application defined text may use <code>SC_MARGIN_TEXT</code> (4) or <code>SC_MARGIN_RTEXT</code> (5) to right justify the text. By convention, margin 0 is used for line numbers and the next two are used for symbols. You can also use the constants <code>SC_MARGIN_BACK</code> (2) and <code>SC_MARGIN_FORE</code> (3) for symbol margins that set their background colour to match the STYLE_DEFAULT background and foreground colours.</p> <p><b id="SCI_SETMARGINWIDTHN">SCI_SETMARGINWIDTHN(int margin, int pixelWidth)</b><br /> <b id="SCI_GETMARGINWIDTHN">SCI_GETMARGINWIDTHN(int margin)</b><br /> These routines set and get the width of a margin in pixels. A margin with zero width is invisible. By default, Scintilla sets margin 1 for symbols with a width of 16 pixels, so this is a reasonable guess if you are not sure what would be appropriate. Line number margins widths should take into account the number of lines in the document and the line number style. You could use something like <a class="message" href="#SCI_TEXTWIDTH"><code>SCI_TEXTWIDTH(STYLE_LINENUMBER, "_99999")</code></a> to get a suitable width.</p> <p><b id="SCI_SETMARGINMASKN">SCI_SETMARGINMASKN(int margin, int mask)</b><br /> <b id="SCI_GETMARGINMASKN">SCI_GETMARGINMASKN(int margin)</b><br /> The mask is a 32-bit value. Each bit corresponds to one of 32 logical symbols that can be displayed in a margin that is enabled for symbols. There is a useful constant, <code>SC_MASK_FOLDERS</code> (0xFE000000 or -33554432), that is a mask for the 7 logical symbols used to denote folding. You can assign a wide range of symbols and colours to each of the 32 logical symbols, see <a href="#Markers">Markers</a> for more information. If <code>(mask & SC_MASK_FOLDERS)==0</code>, the margin background colour is controlled by style 33 (<a class="message" href="#StyleDefinition"><code>STYLE_LINENUMBER</code></a>).</p> <p>You add logical markers to a line with <a class="message" href="#SCI_MARKERADD"><code>SCI_MARKERADD</code></a>. If a line has an associated marker that does not appear in the mask of any margin with a non-zero width, the marker changes the background colour of the line. For example, suppose you decide to use logical marker 10 to mark lines with a syntax error and you want to show such lines by changing the background colour. The mask for this marker is 1 shifted left 10 times (1<<10) which is 0x400. If you make sure that no symbol margin includes 0x400 in its mask, any line with the marker gets the background colour changed.</p> <p>To set a non-folding margin 1 use <code>SCI_SETMARGINMASKN(1, ~SC_MASK_FOLDERS)</code> which is the default set by Scintilla. To set a folding margin 2 use <code>SCI_SETMARGINMASKN(2, SC_MASK_FOLDERS)</code>. <code>~SC_MASK_FOLDERS</code> is 0x1FFFFFF in hexadecimal or 33554431 decimal. Of course, you may need to display all 32 symbols in a margin, in which case use <code>SCI_SETMARGINMASKN(margin, -1)</code>.</p> <p><b id="SCI_SETMARGINSENSITIVEN">SCI_SETMARGINSENSITIVEN(int margin, bool sensitive)</b><br /> <b id="SCI_GETMARGINSENSITIVEN">SCI_GETMARGINSENSITIVEN(int margin)</b><br /> Each of the five margins can be set sensitive or insensitive to mouse clicks. A click in a sensitive margin sends a <a class="message" href="#SCN_MARGINCLICK"><code>SCN_MARGINCLICK</code></a> <a class="jump" href="#Notifications">notification</a> to the container. Margins that are not sensitive act as selection margins which make it easy to select ranges of lines. By default, all margins are insensitive.</p> <p><b id="SCI_SETMARGINCURSORN">SCI_SETMARGINCURSORN(int margin, int cursor)</b><br /> <b id="SCI_GETMARGINCURSORN">SCI_GETMARGINCURSORN(int margin)</b><br /> A reversed arrow cursor is normally shown over all margins. This may be changed to a normal arrow with <code>SCI_SETMARGINCURSORN(margin, SC_CURSORARROW)</code> or restored to a reversed arrow with <code>SCI_SETMARGINCURSORN(margin, SC_CURSORREVERSEARROW)</code>.</p> <p><b id="SCI_SETMARGINLEFT">SCI_SETMARGINLEFT(<unused>, int pixels)</b><br /> <b id="SCI_GETMARGINLEFT">SCI_GETMARGINLEFT</b><br /> <b id="SCI_SETMARGINRIGHT">SCI_SETMARGINRIGHT(<unused>, int pixels)</b><br /> <b id="SCI_GETMARGINRIGHT">SCI_GETMARGINRIGHT</b><br /> These messages set and get the width of the blank margin on both sides of the text in pixels. The default is to one pixel on each side.</p> <p><b id="SCI_SETFOLDMARGINCOLOUR">SCI_SETFOLDMARGINCOLOUR(bool useSetting, int colour)</b><br /> <b id="SCI_SETFOLDMARGINHICOLOUR">SCI_SETFOLDMARGINHICOLOUR(bool useSetting, int colour)</b><br /> These messages allow changing the colour of the fold margin and fold margin highlight. On Windows the fold margin colour defaults to ::GetSysColor(COLOR_3DFACE) and the fold margin highlight colour to ::GetSysColor(COLOR_3DHIGHLIGHT).</p> <p> <b id="SCI_MARGINSETTEXT">SCI_MARGINSETTEXT(int line, char *text)</b><br /> <b id="SCI_MARGINGETTEXT">SCI_MARGINGETTEXT(int line, char *text)</b><br /> <b id="SCI_MARGINSETSTYLE">SCI_MARGINSETSTYLE(int line, int style)</b><br /> <b id="SCI_MARGINGETSTYLE">SCI_MARGINGETSTYLE(int line)</b><br /> <b id="SCI_MARGINSETSTYLES">SCI_MARGINSETSTYLES(int line, char *styles)</b><br /> <b id="SCI_MARGINGETSTYLES">SCI_MARGINGETSTYLES(int line, char *styles)</b><br /> <b id="SCI_MARGINTEXTCLEARALL">SCI_MARGINTEXTCLEARALL</b><br /> Text margins are created with the type SC_MARGIN_TEXT or SC_MARGIN_RTEXT. A different string may be set for each line with <code>SCI_MARGINSETTEXT</code>. The whole of the text margin on a line may be displayed in a particular style with <code>SCI_MARGINSETSTYLE</code> or each character may be individually styled with <code>SCI_MARGINSETSTYLES</code> which uses an array of bytes with each byte setting the style of the corresponding text byte similar to <code>SCI_SETSTYLINGEX</code>. Setting a text margin will cause a <a class="message" href="#SC_MOD_CHANGEMARGIN"><code>SC_MOD_CHANGEMARGIN</code></a> notification to be sent. </p> <p> Only some style attributes are active in text margins: font, size/sizeFractional, bold/weight, italics, fore, back, and characterSet. </p> <p> <b id="SCI_MARGINSETSTYLEOFFSET">SCI_MARGINSETSTYLEOFFSET(int style)</b><br /> <b id="SCI_MARGINGETSTYLEOFFSET">SCI_MARGINGETSTYLEOFFSET</b><br /> Margin styles may be completely separated from standard text styles by setting a style offset. For example, <code>SCI_MARGINSETSTYLEOFFSET(256)</code> would allow the margin styles to be numbered from 256 upto 511 so they do not overlap styles set by lexers. Each style number set with <code>SCI_MARGINSETSTYLE</code> or <code>SCI_MARGINSETSTYLES</code> has the offset added before looking up the style. </p> <p> Always call <a class="message" href="#SCI_ALLOCATEEXTENDEDSTYLES">SCI_ALLOCATEEXTENDEDSTYLES</a> before <code>SCI_MARGINSETSTYLEOFFSET</code> and use the result as the argument to <code>SCI_MARGINSETSTYLEOFFSET</code>. </p> <p> <b id="SCI_SETMARGINOPTIONS">SCI_SETMARGINOPTIONS(int marginOptions)</b><br /> <b id="SCI_GETMARGINOPTIONS">SCI_GETMARGINOPTIONS</b><br /> Define margin options by enabling appropriate bit flags. At the moment, only one flag is available <code>SC_MARGINOPTION_SUBLINESELECT</code>=1, which controls how wrapped lines are selected when clicking on margin in front of them. If <code>SC_MARGINOPTION_SUBLINESELECT</code> is set only sub line of wrapped line is selected, otherwise whole wrapped line is selected. Margin options are set to <code>SC_MARGINOPTION_NONE</code>=0 by default. </p> <h2 id="Annotations">Annotations</h2> <p>Annotations are read-only lines of text underneath each line of editable text. An annotation may consist of multiple lines separated by '\n'. Annotations can be used to display an assembler version of code for debugging or to show diagnostic messages inline or to line up different versions of text in a merge tool.</p> <p>Annotations count as display lines for the methods <a class="message" href="#SCI_VISIBLEFROMDOCLINE"><code>SCI_VISIBLEFROMDOCLINE</code></a> and <a class="message" href="#SCI_DOCLINEFROMVISIBLE"><code>SCI_DOCLINEFROMVISIBLE</code></a></p> <p>Annotations used for inline diagnostics:</p> <p><img src="annotations.png" alt="Annotations used for inline diagnostics" /></p> <code> <a class="message" href="#SCI_ANNOTATIONSETTEXT">SCI_ANNOTATIONSETTEXT(int line, char *text)</a><br /> <a class="message" href="#SCI_ANNOTATIONGETTEXT">SCI_ANNOTATIONGETTEXT(int line, char *text)</a><br /> <a class="message" href="#SCI_ANNOTATIONSETSTYLE">SCI_ANNOTATIONSETSTYLE(int line, int style)</a><br /> <a class="message" href="#SCI_ANNOTATIONGETSTYLE">SCI_ANNOTATIONGETSTYLE(int line)</a><br /> <a class="message" href="#SCI_ANNOTATIONSETSTYLES">SCI_ANNOTATIONSETSTYLES(int line, char *styles)</a><br /> <a class="message" href="#SCI_ANNOTATIONGETSTYLES">SCI_ANNOTATIONGETSTYLES(int line, char *styles)</a><br /> <a class="message" href="#SCI_ANNOTATIONGETLINES">SCI_ANNOTATIONGETLINES(int line)</a><br /> <a class="message" href="#SCI_ANNOTATIONCLEARALL">SCI_ANNOTATIONCLEARALL</a><br /> <a class="message" href="#SCI_ANNOTATIONSETVISIBLE">SCI_ANNOTATIONSETVISIBLE(int visible)</a><br /> <a class="message" href="#SCI_ANNOTATIONGETVISIBLE">SCI_ANNOTATIONGETVISIBLE</a><br /> <a class="message" href="#SCI_ANNOTATIONSETSTYLEOFFSET">SCI_ANNOTATIONSETSTYLEOFFSET(int style)</a><br /> <a class="message" href="#SCI_ANNOTATIONGETSTYLEOFFSET">SCI_ANNOTATIONGETSTYLEOFFSET</a><br /> </code> <p> <b id="SCI_ANNOTATIONSETTEXT">SCI_ANNOTATIONSETTEXT(int line, char *text)</b><br /> <b id="SCI_ANNOTATIONGETTEXT">SCI_ANNOTATIONGETTEXT(int line, char *text)</b><br /> <b id="SCI_ANNOTATIONSETSTYLE">SCI_ANNOTATIONSETSTYLE(int line, int style)</b><br /> <b id="SCI_ANNOTATIONGETSTYLE">SCI_ANNOTATIONGETSTYLE(int line)</b><br /> <b id="SCI_ANNOTATIONSETSTYLES">SCI_ANNOTATIONSETSTYLES(int line, char *styles)</b><br /> <b id="SCI_ANNOTATIONGETSTYLES">SCI_ANNOTATIONGETSTYLES(int line, char *styles)</b><br /> <b id="SCI_ANNOTATIONGETLINES">SCI_ANNOTATIONGETLINES(int line)</b><br /> <b id="SCI_ANNOTATIONCLEARALL">SCI_ANNOTATIONCLEARALL</b><br /> A different string may be set for each line with <code>SCI_ANNOTATIONSETTEXT</code>. To clear annotations call <code>SCI_ANNOTATIONSETTEXT</code> with a NULL pointer. The whole of the text ANNOTATION on a line may be displayed in a particular style with <code>SCI_ANNOTATIONSETSTYLE</code> or each character may be individually styled with <code>SCI_ANNOTATIONSETSTYLES</code> which uses an array of bytes with each byte setting the style of the corresponding text byte similar to <code>SCI_SETSTYLINGEX</code>. The text must be set first as it specifies how long the annotation is so how many bytes of styling to read. Setting an annotation will cause a <a class="message" href="#SC_MOD_CHANGEANNOTATION"><code>SC_MOD_CHANGEANNOTATION</code></a> notification to be sent. </p> <p> The number of lines annotating a line can be retrieved with <code>SCI_ANNOTATIONGETLINES</code>. All the lines can be cleared of annotations with <code>SCI_ANNOTATIONCLEARALL</code> which is equivalent to clearing each line (setting to 0) and then deleting other memory used for this feature. </p> <p> Only some style attributes are active in annotations: font, size/sizeFractional, bold/weight, italics, fore, back, and characterSet. </p> <p> <b id="SCI_ANNOTATIONSETVISIBLE">SCI_ANNOTATIONSETVISIBLE(int visible)</b><br /> <b id="SCI_ANNOTATIONGETVISIBLE">SCI_ANNOTATIONGETVISIBLE</b><br /> Annotations can be made visible in a view and there is a choice of display style when visible. The two messages set and get the annotation display mode. The <code>visible</code> argument can be one of:</p> <table cellpadding="1" cellspacing="2" border="0" summary="Annotation visibility"> <tbody valign="top"> <tr> <th align="left"><code>ANNOTATION_HIDDEN</code></th> <td>0</td> <td>Annotations are not displayed.</td> </tr> <tr> <th align="left"><code>ANNOTATION_STANDARD</code></th> <td>1</td> <td>Annotations are drawn left justified with no adornment.</td> </tr> <tr> <th align="left"><code>ANNOTATION_BOXED</code></th> <td>2</td> <td>Annotations are indented to match the text and are surrounded by a box.</td> </tr> </tbody> </table> <p> <b id="SCI_ANNOTATIONSETSTYLEOFFSET">SCI_ANNOTATIONSETSTYLEOFFSET(int style)</b><br /> <b id="SCI_ANNOTATIONGETSTYLEOFFSET">SCI_ANNOTATIONGETSTYLEOFFSET</b><br /> Annotation styles may be completely separated from standard text styles by setting a style offset. For example, <code>SCI_ANNOTATIONSETSTYLEOFFSET(512)</code> would allow the annotation styles to be numbered from 512 upto 767 so they do not overlap styles set by lexers (or margins if margins offset is 256). Each style number set with <code>SCI_ANNOTATIONSETSTYLE</code> or <code>SCI_ANNOTATIONSETSTYLES</code> has the offset added before looking up the style. </p> <p> Always call <a class="message" href="#SCI_ALLOCATEEXTENDEDSTYLES">SCI_ALLOCATEEXTENDEDSTYLES</a> before <code>SCI_ANNOTATIONSETSTYLEOFFSET</code> and use the result as the argument to <code>SCI_ANNOTATIONSETSTYLEOFFSET</code>. </p> <h2 id="OtherSettings">Other settings</h2> <code><a class="message" href="#SCI_SETUSEPALETTE">SCI_SETUSEPALETTE(bool allowPaletteUse)</a><br /> <a class="message" href="#SCI_GETUSEPALETTE">SCI_GETUSEPALETTE</a><br /> <a class="message" href="#SCI_SETBUFFEREDDRAW">SCI_SETBUFFEREDDRAW(bool isBuffered)</a><br /> <a class="message" href="#SCI_GETBUFFEREDDRAW">SCI_GETBUFFEREDDRAW</a><br /> <a class="message" href="#SCI_SETTWOPHASEDRAW">SCI_SETTWOPHASEDRAW(bool twoPhase)</a><br /> <a class="message" href="#SCI_GETTWOPHASEDRAW">SCI_GETTWOPHASEDRAW</a><br /> <a class="message" href="#SCI_SETTECHNOLOGY">SCI_SETTECHNOLOGY(int technology)</a><br /> <a class="message" href="#SCI_GETTECHNOLOGY">SCI_GETTECHNOLOGY</a><br /> <a class="message" href="#SCI_SETFONTQUALITY">SCI_SETFONTQUALITY(int fontQuality)</a><br /> <a class="message" href="#SCI_GETFONTQUALITY">SCI_GETFONTQUALITY</a><br /> <a class="message" href="#SCI_SETCODEPAGE">SCI_SETCODEPAGE(int codePage)</a><br /> <a class="message" href="#SCI_GETCODEPAGE">SCI_GETCODEPAGE</a><br /> <a class="message" href="#SCI_SETKEYSUNICODE">SCI_SETKEYSUNICODE(bool keysUnicode)</a><br /> <a class="message" href="#SCI_GETKEYSUNICODE">SCI_GETKEYSUNICODE</a><br /> <a class="message" href="#SCI_SETWORDCHARS">SCI_SETWORDCHARS(<unused>, const char *characters)</a><br /> <a class="message" href="#SCI_GETWORDCHARS">SCI_GETWORDCHARS(<unused>, char *characters)</a><br /> <a class="message" href="#SCI_SETWHITESPACECHARS">SCI_SETWHITESPACECHARS(<unused>, const char *characters)</a><br /> <a class="message" href="#SCI_GETWHITESPACECHARS">SCI_GETWHITESPACECHARS(<unused>, char *characters)</a><br /> <a class="message" href="#SCI_SETPUNCTUATIONCHARS">SCI_SETPUNCTUATIONCHARS(<unused>, const char *characters)</a><br /> <a class="message" href="#SCI_GETPUNCTUATIONCHARS">SCI_GETPUNCTUATIONCHARS(<unused>, char *characters)</a><br /> <a class="message" href="#SCI_SETCHARSDEFAULT">SCI_SETCHARSDEFAULT</a><br /> <a class="message" href="#SCI_GRABFOCUS">SCI_GRABFOCUS</a><br /> <a class="message" href="#SCI_SETFOCUS">SCI_SETFOCUS(bool focus)</a><br /> <a class="message" href="#SCI_GETFOCUS">SCI_GETFOCUS</a><br /> </code> <p>To forward a message <code>(WM_XXXX, WPARAM, LPARAM)</code> to Scintilla, you can use <code>SendMessage(hScintilla, WM_XXXX, WPARAM, LPARAM)</code> where <code>hScintilla</code> is the handle to the Scintilla window you created as your editor.</p> <p>While we are on the subject of forwarding messages in Windows, the top level window should forward any <code>WM_SETTINGCHANGE</code> messages to Scintilla (this is currently used to collect changes to mouse settings, but could be used for other user interface items in the future).</p> <p><b id="SCI_SETBUFFEREDDRAW">SCI_SETBUFFEREDDRAW(bool isBuffered)</b><br /> <b id="SCI_GETBUFFEREDDRAW">SCI_GETBUFFEREDDRAW</b><br /> These messages turn buffered drawing on or off and report the buffered drawing state. Buffered drawing draws each line into a bitmap rather than directly to the screen and then copies the bitmap to the screen. This avoids flickering although it does take longer. The default is for drawing to be buffered.</p> <p><b id="SCI_SETTWOPHASEDRAW">SCI_SETTWOPHASEDRAW(bool twoPhase)</b><br /> <b id="SCI_GETTWOPHASEDRAW">SCI_GETTWOPHASEDRAW</b><br /> Two phase drawing is a better but slower way of drawing text. In single phase drawing each run of characters in one style is drawn along with its background. If a character overhangs the end of a run, such as in "<i>V</i>_" where the "<i>V</i>" is in a different style from the "_", then this can cause the right hand side of the "<i>V</i>" to be overdrawn by the background of the "_" which cuts it off. Two phase drawing fixes this by drawing all the backgrounds first and then drawing the text in transparent mode. Two phase drawing may flicker more than single phase unless buffered drawing is on. The default is for drawing to be two phase.</p> <p><b id="SCI_SETTECHNOLOGY">SCI_SETTECHNOLOGY(int technology)</b><br /> <b id="SCI_GETTECHNOLOGY">SCI_GETTECHNOLOGY</b><br /> The technology property allows choosing between different drawing APIs and options. On most platforms, the only choice is <code>SC_TECHNOLOGY_DEFAULT</code> (0). On Windows Vista or later, <code>SC_TECHNOLOGY_DIRECTWRITE</code> (1) can be chosen to use the Direct2D and DirectWrite APIs for higher quality antialiased drawing. Since Direct2D buffers drawing, Scintilla's buffering can be turned off with <code>SCI_SETBUFFEREDDRAW(0)</code>.</p> <p><b id="SCI_SETFONTQUALITY">SCI_SETFONTQUALITY(int fontQuality)</b><br /> <b id="SCI_GETFONTQUALITY">SCI_GETFONTQUALITY</b><br /> Manage font quality (antialiasing method). Currently, the following values are available on Windows: <code>SC_EFF_QUALITY_DEFAULT</code> (backward compatible), <code>SC_EFF_QUALITY_NON_ANTIALIASED</code>, <code>SC_EFF_QUALITY_ANTIALIASED</code>, <code>SC_EFF_QUALITY_LCD_OPTIMIZED</code>.</p> <p>In case it is necessary to squeeze more options into this property, only a limited number of bits defined by SC_EFF_QUALITY_MASK (0xf) will be used for quality.</p> <p><b id="SCI_SETCODEPAGE">SCI_SETCODEPAGE(int codePage)</b><br /> <b id="SCI_GETCODEPAGE">SCI_GETCODEPAGE</b><br /> Scintilla has some support for Japanese, Chinese and Korean DBCS. Use this message with <code>codePage</code> set to the code page number to set Scintilla to use code page information to ensure double byte characters are treated as one character rather than two. This also stops the caret from moving between the two bytes in a double byte character. Do not use this message to choose between different single byte character sets: it doesn't do that. Call with <code>codePage</code> set to zero to disable DBCS support. The default is <code>SCI_SETCODEPAGE(0)</code>.</p> <p>Code page <code>SC_CP_UTF8</code> (65001) sets Scintilla into Unicode mode with the document treated as a sequence of characters expressed in UTF-8. The text is converted to the platform's normal Unicode encoding before being drawn by the OS and thus can display Hebrew, Arabic, Cyrillic, and Han characters. Languages which can use two characters stacked vertically in one horizontal space, such as Thai, will mostly work but there are some issues where the characters are drawn separately leading to visual glitches. Bi-directional text is not supported. </p> <p>Code page can be set to 932 (Japanese Shift-JIS), 936 (Simplified Chinese GBK), 949 (Korean Unified Hangul Code), 950 (Traditional Chinese Big5), or 1361 (Korean Johab) although these may require installation of language specific support.</p> <p><b id="SCI_SETKEYSUNICODE">SCI_SETKEYSUNICODE(bool keysUnicode)</b><br /> <b id="SCI_GETKEYSUNICODE">SCI_GETKEYSUNICODE</b><br /> On Windows, character keys are normally handled differently depending on whether Scintilla is a wide or narrow character window with character messages treated as Unicode when wide and as 8 bit otherwise. Set this property to always treat as Unicode. This option is needed for Delphi.</p> <p><b id="SCI_SETWORDCHARS">SCI_SETWORDCHARS(<unused>, const char *characters)</b><br /> Scintilla has several functions that operate on words, which are defined to be contiguous sequences of characters from a particular set of characters. This message defines which characters are members of that set. The character sets are set to default values before processing this function. For example, if you don't allow '_' in your set of characters use:<br /> <code>SCI_SETWORDCHARS(0, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")</code>;</p> <p><b id="SCI_GETWORDCHARS">SCI_GETWORDCHARS(<unused>, char *characters)</b><br /> This fills the characters parameter with all the characters included in words. The characters parameter must be large enough to hold all of the characters. If the characters parameter is 0 then the length that should be allocated to store the entire set is returned.</p> <p><b id="SCI_SETWHITESPACECHARS">SCI_SETWHITESPACECHARS(<unused>, const char *characters)</b><br /> <b id="SCI_GETWHITESPACECHARS">SCI_GETWHITESPACECHARS(<unused>, char *characters)</b><br /> Similar to <code>SCI_SETWORDCHARS</code>, this message allows the user to define which chars Scintilla considers as whitespace. Setting the whitespace chars allows the user to fine-tune Scintilla's behaviour doing such things as moving the cursor to the start or end of a word; for example, by defining punctuation chars as whitespace, they will be skipped over when the user presses ctrl+left or ctrl+right. This function should be called after <code>SCI_SETWORDCHARS</code> as it will reset the whitespace characters to the default set. <code>SCI_GETWHITESPACECHARS</code> behaves similarly to <code>SCI_GETWORDCHARS</code>.</p> <p><b id="SCI_SETPUNCTUATIONCHARS">SCI_SETPUNCTUATIONCHARS(<unused>, const char *characters)</b><br /> <b id="SCI_GETPUNCTUATIONCHARS">SCI_GETPUNCTUATIONCHARS(<unused>, char *characters)</b><br /> Similar to <code>SCI_SETWORDCHARS</code> and <code>SCI_SETWHITESPACECHARS</code>, this message allows the user to define which chars Scintilla considers as punctuation. <code>SCI_GETPUNCTUATIONCHARS</code> behaves similarly to <code>SCI_GETWORDCHARS</code>.</p> <p><b id="SCI_SETCHARSDEFAULT">SCI_SETCHARSDEFAULT</b><br /> Use the default sets of word and whitespace characters. This sets whitespace to space, tab and other characters with codes less than 0x20, with word characters set to alphanumeric and '_'. </p> <p><b id="SCI_GRABFOCUS">SCI_GRABFOCUS</b><br /> <b id="SCI_SETFOCUS">SCI_SETFOCUS(bool focus)</b><br /> <b id="SCI_GETFOCUS">SCI_GETFOCUS</b><br /> Scintilla can be told to grab the focus with this message. This is needed more on GTK+ where focus handling is more complicated than on Windows.</p> <p>The internal focus flag can be set with <code>SCI_SETFOCUS</code>. This is used by clients that have complex focus requirements such as having their own window that gets the real focus but with the need to indicate that Scintilla has the logical focus.</p> <h2 id="BraceHighlighting">Brace highlighting</h2> <code><a class="message" href="#SCI_BRACEHIGHLIGHT">SCI_BRACEHIGHLIGHT(int pos1, int pos2)</a><br /> <a class="message" href="#SCI_BRACEBADLIGHT">SCI_BRACEBADLIGHT(int pos1)</a><br /> <a class="message" href="#SCI_BRACEHIGHLIGHTINDICATOR">SCI_BRACEHIGHLIGHTINDICATOR(bool useBraceHighlightIndicator, int indicatorNumber)</a><br /> <a class="message" href="#SCI_BRACEBADLIGHTINDICATOR">SCI_BRACEBADLIGHTINDICATOR(bool useBraceBadLightIndicator, int indicatorNumber)</a><br /> <a class="message" href="#SCI_BRACEMATCH">SCI_BRACEMATCH(int position, int maxReStyle)</a><br /> </code> <p><b id="SCI_BRACEHIGHLIGHT">SCI_BRACEHIGHLIGHT(int pos1, int pos2)</b><br /> Up to two characters can be highlighted in a 'brace highlighting style', which is defined as style number <a class="message" href="#StyleDefinition"><code>STYLE_BRACELIGHT</code></a> (34). If you have enabled indent guides, you may also wish to highlight the indent that corresponds with the brace. You can locate the column with <a class="message" href="#SCI_GETCOLUMN"><code>SCI_GETCOLUMN</code></a> and highlight the indent with <a class="message" href="#SCI_SETHIGHLIGHTGUIDE"><code>SCI_SETHIGHLIGHTGUIDE</code></a>.</p> <p><b id="SCI_BRACEBADLIGHT">SCI_BRACEBADLIGHT(int pos1)</b><br /> If there is no matching brace then the <a class="jump" href="#StyleDefinition">brace badlighting style</a>, style <code>STYLE_BRACEBAD</code> (35), can be used to show the brace that is unmatched. Using a position of <code>INVALID_POSITION</code> (-1) removes the highlight.</p> <p><b id="#SCI_BRACEHIGHLIGHTINDICATOR">SCI_BRACEHIGHLIGHTINDICATOR(bool useBraceHighlightIndicator, int indicatorNumber)</b><br /> Use specified indicator to highlight matching braces instead of changing their style.</p> <p><b id="#SCI_BRACEBADLIGHTINDICATOR">SCI_BRACEBADLIGHTINDICATOR(bool useBraceBadLightIndicator, int indicatorNumber)</b><br /> Use specified indicator to highlight non matching brace instead of changing its style.</p> <p><b id="SCI_BRACEMATCH">SCI_BRACEMATCH(int pos, int maxReStyle)</b><br /> The <code>SCI_BRACEMATCH</code> message finds a corresponding matching brace given <code>pos</code>, the position of one brace. The brace characters handled are '(', ')', '[', ']', '{', '}', '<', and '>'. The search is forwards from an opening brace and backwards from a closing brace. If the character at position is not a brace character, or a matching brace cannot be found, the return value is -1. Otherwise, the return value is the position of the matching brace.</p> <p>A match only occurs if the style of the matching brace is the same as the starting brace or the matching brace is beyond the end of styling. Nested braces are handled correctly. The <code>maxReStyle</code> parameter must currently be 0 - it may be used in the future to limit the length of brace searches.</p> <h2 id="TabsAndIndentationGuides">Tabs and Indentation Guides</h2> <p>Indentation (the white space at the start of a line) is often used by programmers to clarify program structure and in some languages, for example Python, it may be part of the language syntax. Tabs are normally used in editors to insert a tab character or to pad text with spaces up to the next tab.</p> <p>Scintilla can be set to treat tab and backspace in the white space at the start of a line in a special way: inserting a tab indents the line to the next indent position rather than just inserting a tab at the current character position and backspace unindents the line rather than deleting a character. Scintilla can also display indentation guides (vertical lines) to help you to generate code.</p> <code><a class="message" href="#SCI_SETTABWIDTH">SCI_SETTABWIDTH(int widthInChars)</a><br /> <a class="message" href="#SCI_GETTABWIDTH">SCI_GETTABWIDTH</a><br /> <a class="message" href="#SCI_SETUSETABS">SCI_SETUSETABS(bool useTabs)</a><br /> <a class="message" href="#SCI_GETUSETABS">SCI_GETUSETABS</a><br /> <a class="message" href="#SCI_SETINDENT">SCI_SETINDENT(int widthInChars)</a><br /> <a class="message" href="#SCI_GETINDENT">SCI_GETINDENT</a><br /> <a class="message" href="#SCI_SETTABINDENTS">SCI_SETTABINDENTS(bool tabIndents)</a><br /> <a class="message" href="#SCI_GETTABINDENTS">SCI_GETTABINDENTS</a><br /> <a class="message" href="#SCI_SETBACKSPACEUNINDENTS">SCI_SETBACKSPACEUNINDENTS(bool bsUnIndents)</a><br /> <a class="message" href="#SCI_GETBACKSPACEUNINDENTS">SCI_GETBACKSPACEUNINDENTS</a><br /> <a class="message" href="#SCI_SETLINEINDENTATION">SCI_SETLINEINDENTATION(int line, int indentation)</a><br /> <a class="message" href="#SCI_GETLINEINDENTATION">SCI_GETLINEINDENTATION(int line)</a><br /> <a class="message" href="#SCI_GETLINEINDENTPOSITION">SCI_GETLINEINDENTPOSITION(int line)</a><br /> <a class="message" href="#SCI_SETINDENTATIONGUIDES">SCI_SETINDENTATIONGUIDES(int indentView)</a><br /> <a class="message" href="#SCI_GETINDENTATIONGUIDES">SCI_GETINDENTATIONGUIDES</a><br /> <a class="message" href="#SCI_SETHIGHLIGHTGUIDE">SCI_SETHIGHLIGHTGUIDE(int column)</a><br /> <a class="message" href="#SCI_GETHIGHLIGHTGUIDE">SCI_GETHIGHLIGHTGUIDE</a><br /> </code> <p><b id="SCI_SETTABWIDTH">SCI_SETTABWIDTH(int widthInChars)</b><br /> <b id="SCI_GETTABWIDTH">SCI_GETTABWIDTH</b><br /> <code>SCI_SETTABWIDTH</code> sets the size of a tab as a multiple of the size of a space character in <code>STYLE_DEFAULT</code>. The default tab width is 8 characters. There are no limits on tab sizes, but values less than 1 or large values may have undesirable effects.</p> <p><b id="SCI_SETUSETABS">SCI_SETUSETABS(bool useTabs)</b><br /> <b id="SCI_GETUSETABS">SCI_GETUSETABS</b><br /> <code>SCI_SETUSETABS</code> determines whether indentation should be created out of a mixture of tabs and spaces or be based purely on spaces. Set <code>useTabs</code> to <code>false</code> (0) to create all tabs and indents out of spaces. The default is <code>true</code>. You can use <a class="message" href="#SCI_GETCOLUMN"><code>SCI_GETCOLUMN</code></a> to get the column of a position taking the width of a tab into account.</p> <p><b id="SCI_SETINDENT">SCI_SETINDENT(int widthInChars)</b><br /> <b id="SCI_GETINDENT">SCI_GETINDENT</b><br /> <code>SCI_SETINDENT</code> sets the size of indentation in terms of the width of a space in <a class="message" href="#StyleDefinition"><code>STYLE_DEFAULT</code></a>. If you set a width of 0, the indent size is the same as the tab size. There are no limits on indent sizes, but values less than 0 or large values may have undesirable effects. </p> <p><b id="SCI_SETTABINDENTS">SCI_SETTABINDENTS(bool tabIndents)</b><br /> <b id="SCI_GETTABINDENTS">SCI_GETTABINDENTS</b><br /> <b id="SCI_SETBACKSPACEUNINDENTS">SCI_SETBACKSPACEUNINDENTS(bool bsUnIndents)</b><br /> <b id="SCI_GETBACKSPACEUNINDENTS">SCI_GETBACKSPACEUNINDENTS</b><br /> </p> <p>Inside indentation white space, the tab and backspace keys can be made to indent and unindent rather than insert a tab character or delete a character with the <code>SCI_SETTABINDENTS</code> and <code>SCI_SETBACKSPACEUNINDENTS</code> functions.</p> <p><b id="SCI_SETLINEINDENTATION">SCI_SETLINEINDENTATION(int line, int indentation)</b><br /> <b id="SCI_GETLINEINDENTATION">SCI_GETLINEINDENTATION(int line)</b><br /> The amount of indentation on a line can be discovered and set with <code>SCI_GETLINEINDENTATION</code> and <code>SCI_SETLINEINDENTATION</code>. The indentation is measured in character columns, which correspond to the width of space characters.</p> <p><b id="SCI_GETLINEINDENTPOSITION">SCI_GETLINEINDENTPOSITION(int line)</b><br /> This returns the position at the end of indentation of a line.</p> <p><b id="SCI_SETINDENTATIONGUIDES">SCI_SETINDENTATIONGUIDES(int indentView)</b><br /> <b id="SCI_GETINDENTATIONGUIDES">SCI_GETINDENTATIONGUIDES</b><br /> Indentation guides are dotted vertical lines that appear within indentation white space every indent size columns. They make it easy to see which constructs line up especially when they extend over multiple pages. Style <a class="message" href="#StyleDefinition"><code>STYLE_INDENTGUIDE</code></a> (37) is used to specify the foreground and background colour of the indentation guides.</p> <p>There are 4 indentation guide views. SC_IV_NONE turns the feature off but the other 3 states determine how far the guides appear on empty lines. </p> <table border="0" summary="Search flags"> <tbody> <tr> <td><code>SC_IV_NONE</code></td> <td>No indentation guides are shown.</td> </tr> <tr> <td><code>SC_IV_REAL</code></td> <td>Indentation guides are shown inside real indentation white space.</td> </tr> <tr> <td><code>SC_IV_LOOKFORWARD</code></td> <td>Indentation guides are shown beyond the actual indentation up to the level of the next non-empty line. If the previous non-empty line was a fold header then indentation guides are shown for one more level of indent than that line. This setting is good for Python.</td> </tr> <tr> <td><code>SC_IV_LOOKBOTH</code></td> <td>Indentation guides are shown beyond the actual indentation up to the level of the next non-empty line or previous non-empty line whichever is the greater. This setting is good for most languages.</td> </tr> </tbody> </table> <p><b id="SCI_SETHIGHLIGHTGUIDE">SCI_SETHIGHLIGHTGUIDE(int column)</b><br /> <b id="SCI_GETHIGHLIGHTGUIDE">SCI_GETHIGHLIGHTGUIDE</b><br /> When brace highlighting occurs, the indentation guide corresponding to the braces may be highlighted with the brace highlighting style, <a class="message" href="#StyleDefinition"><code>STYLE_BRACELIGHT</code></a> (34). Set <code>column</code> to 0 to cancel this highlight.</p> <h2 id="Markers">Markers</h2> <p>There are 32 markers, numbered 0 to <code>MARKER_MAX</code> (31), and you can assign any combination of them to each line in the document. Markers appear in the <a class="jump" href="#Margins">selection margin</a> to the left of the text. If the selection margin is set to zero width, the background colour of the whole line is changed instead. Marker numbers 25 to 31 are used by Scintilla in folding margins, and have symbolic names of the form <code>SC_MARKNUM_</code>*, for example <code>SC_MARKNUM_FOLDEROPEN</code>.</p> <p>Marker numbers 0 to 24 have no pre-defined function; you can use them to mark syntax errors or the current point of execution, break points, or whatever you need marking. If you do not need folding, you can use all 32 for any purpose you wish.</p> <p>Each marker number has a symbol associated with it. You can also set the foreground and background colour for each marker number, so you can use the same symbol more than once with different colouring for different uses. Scintilla has a set of symbols you can assign (<code>SC_MARK_</code>*) or you can use characters. By default, all 32 markers are set to <code>SC_MARK_CIRCLE</code> with a black foreground and a white background.</p> <p>The markers are drawn in the order of their numbers, so higher numbered markers appear on top of lower numbered ones. Markers try to move with their text by tracking where the start of their line moves. When a line is deleted, its markers are combined, by an <code>OR</code> operation, with the markers of the previous line.</p> <code><a class="message" href="#SCI_MARKERDEFINE">SCI_MARKERDEFINE(int markerNumber, int markerSymbols)</a><br /> <a class="message" href="#SCI_MARKERDEFINEPIXMAP">SCI_MARKERDEFINEPIXMAP(int markerNumber, const char *xpm)</a><br /> <a class="message" href="#SCI_RGBAIMAGESETWIDTH">SCI_RGBAIMAGESETWIDTH(int width)</a><br /> <a class="message" href="#SCI_RGBAIMAGESETHEIGHT">SCI_RGBAIMAGESETHEIGHT(int height)</a><br /> <a class="message" href="#SCI_RGBAIMAGESETSCALE">SCI_RGBAIMAGESETSCALE(int scalePercent)</a><br /> <a class="message" href="#SCI_MARKERDEFINERGBAIMAGE">SCI_MARKERDEFINERGBAIMAGE(int markerNumber, const char *pixels)</a><br /> <a class="message" href="#SCI_MARKERSYMBOLDEFINED">SCI_MARKERSYMBOLDEFINED(int markerNumber) </a><br /> <a class="message" href="#SCI_MARKERSETFORE">SCI_MARKERSETFORE(int markerNumber, int colour)</a><br /> <a class="message" href="#SCI_MARKERSETBACK">SCI_MARKERSETBACK(int markerNumber, int colour)</a><br /> <a class="message" href="#SCI_MARKERSETBACKSELECTED">SCI_MARKERSETBACKSELECTED(int markerNumber, int colour)</a><br /> <a class="message" href="#SCI_MARKERENABLEHIGHLIGHT">SCI_MARKERENABLEHIGHLIGHT(int enabled)</a><br /> <a class="message" href="#SCI_MARKERSETALPHA">SCI_MARKERSETALPHA(int markerNumber, int alpha)</a><br /> <a class="message" href="#SCI_MARKERADD">SCI_MARKERADD(int line, int markerNumber)</a><br /> <a class="message" href="#SCI_MARKERADDSET">SCI_MARKERADDSET(int line, int markerMask)</a><br /> <a class="message" href="#SCI_MARKERDELETE">SCI_MARKERDELETE(int line, int markerNumber)</a><br /> <a class="message" href="#SCI_MARKERDELETEALL">SCI_MARKERDELETEALL(int markerNumber)</a><br /> <a class="message" href="#SCI_MARKERGET">SCI_MARKERGET(int line)</a><br /> <a class="message" href="#SCI_MARKERNEXT">SCI_MARKERNEXT(int lineStart, int markerMask)</a><br /> <a class="message" href="#SCI_MARKERPREVIOUS">SCI_MARKERPREVIOUS(int lineStart, int markerMask)</a><br /> <a class="message" href="#SCI_MARKERLINEFROMHANDLE">SCI_MARKERLINEFROMHANDLE(int handle)</a><br /> <a class="message" href="#SCI_MARKERDELETEHANDLE">SCI_MARKERDELETEHANDLE(int handle)</a><br /> </code> <p><b id="SCI_MARKERDEFINE">SCI_MARKERDEFINE(int markerNumber, int markerSymbols)</b><br /> This message associates a marker number in the range 0 to 31 with one of the marker symbols or an ASCII character. The general-purpose marker symbols currently available are:<br /> <code>SC_MARK_CIRCLE</code>, <code>SC_MARK_ROUNDRECT</code>, <code>SC_MARK_ARROW</code>, <code>SC_MARK_SMALLRECT</code>, <code>SC_MARK_SHORTARROW</code>, <code>SC_MARK_EMPTY</code>, <code>SC_MARK_ARROWDOWN</code>, <code>SC_MARK_MINUS</code>, <code>SC_MARK_PLUS</code>, <code>SC_MARK_ARROWS</code>, <code>SC_MARK_DOTDOTDOT</code>, <code>SC_MARK_BACKGROUND</code>, <code>SC_MARK_LEFTRECT</code>, <code>SC_MARK_FULLRECT</code>, and <code>SC_MARK_UNDERLINE</code>.</p> <p>The <code>SC_MARK_BACKGROUND</code> marker changes the background colour of the line only. The <code>SC_MARK_FULLRECT</code> symbol mirrors this, changing only the margin background colour. <code>SC_MARK_UNDERLINE</code> draws an underline across the text. The <code>SC_MARK_EMPTY</code> symbol is invisible, allowing client code to track the movement of lines. You would also use it if you changed the folding style and wanted one or more of the <code>SC_FOLDERNUM_</code>* markers to have no associated symbol.</p> <p>Applications may use the marker symbol <code>SC_MARK_AVAILABLE</code> to indicate that plugins may allocate that marker number. </p> <p>There are also marker symbols designed for use in the folding margin in a flattened tree style.<br /> <code>SC_MARK_BOXMINUS</code>, <code>SC_MARK_BOXMINUSCONNECTED</code>, <code>SC_MARK_BOXPLUS</code>, <code>SC_MARK_BOXPLUSCONNECTED</code>, <code>SC_MARK_CIRCLEMINUS</code>, <code>SC_MARK_CIRCLEMINUSCONNECTED</code>, <code>SC_MARK_CIRCLEPLUS</code>, <code>SC_MARK_CIRCLEPLUSCONNECTED</code>, <code>SC_MARK_LCORNER</code>, <code>SC_MARK_LCORNERCURVE</code>, <code>SC_MARK_TCORNER</code>, <code>SC_MARK_TCORNERCURVE</code>, and <code>SC_MARK_VLINE</code>.</p> Characters can be used as markers by adding the ASCII value of the character to <code>SC_MARK_CHARACTER</code> (10000). For example, to use 'A' (ASCII code 65) as marker number 1 use:<br /> <code>SCI_MARKERDEFINE(1, SC_MARK_CHARACTER+65)</code>. <br /> <p>The marker numbers <code>SC_MARKNUM_FOLDER</code> and <code>SC_MARKNUM_FOLDEROPEN</code> are used for showing that a fold is present and open or closed. Any symbols may be assigned for this purpose although the (<code>SC_MARK_PLUS</code>, <code>SC_MARK_MINUS</code>) pair or the (<code>SC_MARK_ARROW</code>, <code>SC_MARK_ARROWDOWN</code>) pair are good choices. As well as these two, more assignments are needed for the flattened tree style: <code>SC_MARKNUM_FOLDEREND</code>, <code>SC_MARKNUM_FOLDERMIDTAIL</code>, <code>SC_MARKNUM_FOLDEROPENMID</code>, <code>SC_MARKNUM_FOLDERSUB</code>, and <code>SC_MARKNUM_FOLDERTAIL</code>. The bits used for folding are specified by <code>SC_MASK_FOLDERS</code>, which is commonly used as an argument to <code>SCI_SETMARGINMASKN</code> when defining a margin to be used for folding.</p> <p>This table shows which <code>SC_MARK_</code>* symbols should be assigned to which <code>SC_MARKNUM_</code>* marker numbers to obtain four folding styles: Arrow (mimics Macintosh), plus/minus shows folded lines as '+' and opened folds as '-', Circle tree, Box tree.</p> <table cellpadding="1" cellspacing="2" border="0" summary="Markers used for folding"> <thead align="left"> <tr> <th><code>SC_MARKNUM_</code>*</th> <th>Arrow</th> <th>Plus/minus</th> <th>Circle tree</th> <th>Box tree</th> </tr> </thead> <tbody valign="top"> <tr> <th align="left"><code>FOLDEROPEN</code></th> <td><code>ARROWDOWN</code></td> <td><code>MINUS</code></td> <td><code>CIRCLEMINUS</code></td> <td><code>BOXMINUS</code></td> </tr> <tr> <th align="left"><code>FOLDER</code></th> <td><code>ARROW</code></td> <td><code>PLUS</code></td> <td><code>CIRCLEPLUS</code></td> <td><code>BOXPLUS</code></td> </tr> <tr> <th align="left"><code>FOLDERSUB</code></th> <td><code>EMPTY</code></td> <td><code>EMPTY</code></td> <td><code>VLINE</code></td> <td><code>VLINE</code></td> </tr> <tr> <th align="left"><code>FOLDERTAIL</code></th> <td><code>EMPTY</code></td> <td><code>EMPTY</code></td> <td><code>LCORNERCURVE</code></td> <td><code>LCORNER</code></td> </tr> <tr> <th align="left"><code>FOLDEREND</code></th> <td><code>EMPTY</code></td> <td><code>EMPTY</code></td> <td><code>CIRCLEPLUSCONNECTED</code></td> <td><code>BOXPLUSCONNECTED</code></td> </tr> <tr> <th align="left"><code>FOLDEROPENMID</code></th> <td><code>EMPTY</code></td> <td><code>EMPTY</code></td> <td><code>CIRCLEMINUSCONNECTED</code></td> <td><code>BOXMINUSCONNECTED</code></td> </tr> <tr> <th align="left"><code>FOLDERMIDTAIL</code></th> <td><code>EMPTY</code></td> <td><code>EMPTY</code></td> <td><code>TCORNERCURVE</code></td> <td><code>TCORNER</code></td> </tr> </tbody> </table> <p><b id="SCI_MARKERDEFINEPIXMAP">SCI_MARKERDEFINEPIXMAP(int markerNumber, const char *xpm)</b><br /> Markers can be set to pixmaps with this message. The <a class="jump" href="#XPM">XPM format</a> is used for the pixmap. Pixmaps use the <code>SC_MARK_PIXMAP</code> marker symbol. </p> <p> <b id="SCI_RGBAIMAGESETWIDTH">SCI_RGBAIMAGESETWIDTH(int width)</b><br /> <b id="SCI_RGBAIMAGESETHEIGHT">SCI_RGBAIMAGESETHEIGHT(int height)</b><br /> <b id="SCI_RGBAIMAGESETSCALE">SCI_RGBAIMAGESETSCALE(int scalePercent)</b><br /> <b id="SCI_MARKERDEFINERGBAIMAGE">SCI_MARKERDEFINERGBAIMAGE(int markerNumber, const char *pixels)</b><br /> Markers can be set to translucent pixmaps with this message. The <a class="jump" href="#RGBA">RGBA format</a> is used for the pixmap. The width and height must previously been set with the <code>SCI_RGBAIMAGESETWIDTH</code> and <code>SCI_RGBAIMAGESETHEIGHT</code> messages.</p> <p>A scale factor in percent may be set with <code>SCI_RGBAIMAGESETSCALE</code>. This is useful on OS X with a retina display where each display unit is 2 pixels: use a factor of 200 so that each image pixel is dsplayed using a screen pixel. The default scale, 100, will stretch each image pixel to cover 4 screen pixels on a retina display.</p> <p>Pixmaps use the <code>SC_MARK_RGBAIMAGE</code> marker symbol. </p> <p><b id="SCI_MARKERSYMBOLDEFINED">SCI_MARKERSYMBOLDEFINED(int markerNumber)</b><br /> Returns the symbol defined for a markerNumber with <code>SCI_MARKERDEFINE</code> or <code>SC_MARK_PIXMAP</code> if defined with <code>SCI_MARKERDEFINEPIXMAP</code> or <code>SC_MARK_RGBAIMAGE</code> if defined with <code>SCI_MARKERDEFINERGBAIMAGE</code>.</p> <p><b id="SCI_MARKERSETFORE">SCI_MARKERSETFORE(int markerNumber, int <a class="jump" href="#colour">colour</a>)</b><br /> <b id="SCI_MARKERSETBACK">SCI_MARKERSETBACK(int markerNumber, int <a class="jump" href="#colour">colour</a>)</b><br /> These two messages set the foreground and background colour of a marker number.<br /> <b id="SCI_MARKERSETBACKSELECTED">SCI_MARKERSETBACKSELECTED(int markerNumber, int <a class="jump" href="#colour">colour</a>)</b><br /> This message sets the highlight background colour of a marker number when its folding block is selected. The default colour is #FF0000.</p> <p><b id="SCI_MARKERENABLEHIGHLIGHT">SCI_MARKERENABLEHIGHLIGHT(bool enabled)</b><br /> This message allows to enable/disable the highlight folding block when it is selected. (i.e. block that contains the caret)</p> <p><b id="SCI_MARKERSETALPHA">SCI_MARKERSETALPHA(int markerNumber, int <a class="jump" href="#alpha">alpha</a>)</b><br /> When markers are drawn in the content area, either because there is no margin for them or they are of <code>SC_MARK_BACKGROUND</code> or <code>SC_MARK_UNDERLINE</code> types, they may be drawn translucently by setting an alpha value.</p> <p><b id="SCI_MARKERADD">SCI_MARKERADD(int line, int markerNumber)</b><br /> This message adds marker number <code>markerNumber</code> to a line. The message returns -1 if this fails (illegal line number, out of memory) or it returns a marker handle number that identifies the added marker. You can use this returned handle with <a class="message" href="#SCI_MARKERLINEFROMHANDLE"><code>SCI_MARKERLINEFROMHANDLE</code></a> to find where a marker is after moving or combining lines and with <a class="message" href="#SCI_MARKERDELETEHANDLE"><code>SCI_MARKERDELETEHANDLE</code></a> to delete the marker based on its handle. The message does not check the value of markerNumber, nor does it check if the line already contains the marker.</p> <p><b id="SCI_MARKERADDSET">SCI_MARKERADDSET(int line, int markerMask)</b><br /> This message can add one or more markers to a line with a single call, specified in the same "one-bit-per-marker" 32-bit integer format returned by <a class="message" href="#SCI_MARKERGET"><code>SCI_MARKERGET</code></a> (and used by the mask-based marker search functions <a class="message" href="#SCI_MARKERNEXT"><code>SCI_MARKERNEXT</code></a> and <a class="message" href="#SCI_MARKERPREVIOUS"><code>SCI_MARKERPREVIOUS</code></a>). As with <a class="message" href="#SCI_MARKERADD"><code>SCI_MARKERADD</code></a>, no check is made to see if any of the markers are already present on the targeted line.</p> <p><b id="SCI_MARKERDELETE">SCI_MARKERDELETE(int line, int markerNumber)</b><br /> This searches the given line number for the given marker number and deletes it if it is present. If you added the same marker more than once to the line, this will delete one copy each time it is used. If you pass in a marker number of -1, all markers are deleted from the line.</p> <p><b id="SCI_MARKERDELETEALL">SCI_MARKERDELETEALL(int markerNumber)</b><br /> This removes markers of the given number from all lines. If markerNumber is -1, it deletes all markers from all lines.</p> <p><b id="SCI_MARKERGET">SCI_MARKERGET(int line)</b><br /> This returns a 32-bit integer that indicates which markers were present on the line. Bit 0 is set if marker 0 is present, bit 1 for marker 1 and so on.</p> <p><b id="SCI_MARKERNEXT">SCI_MARKERNEXT(int lineStart, int markerMask)</b><br /> <b id="SCI_MARKERPREVIOUS">SCI_MARKERPREVIOUS(int lineStart, int markerMask)</b><br /> These messages search efficiently for lines that include a given set of markers. The search starts at line number <code>lineStart</code> and continues forwards to the end of the file (<code>SCI_MARKERNEXT</code>) or backwards to the start of the file (<code>SCI_MARKERPREVIOUS</code>). The <code>markerMask</code> argument should have one bit set for each marker you wish to find. Set bit 0 to find marker 0, bit 1 for marker 1 and so on. The message returns the line number of the first line that contains one of the markers in <code>markerMask</code> or -1 if no marker is found.</p> <p><b id="SCI_MARKERLINEFROMHANDLE">SCI_MARKERLINEFROMHANDLE(int markerHandle)</b><br /> The <code>markerHandle</code> argument is an identifier for a marker returned by <a class="message" href="#SCI_MARKERADD"><code>SCI_MARKERADD</code></a>. This function searches the document for the marker with this handle and returns the line number that contains it or -1 if it is not found.</p> <p><b id="SCI_MARKERDELETEHANDLE">SCI_MARKERDELETEHANDLE(int markerHandle)</b><br /> The <code>markerHandle</code> argument is an identifier for a marker returned by <a class="message" href="#SCI_MARKERADD"><code>SCI_MARKERADD</code></a>. This function searches the document for the marker with this handle and deletes the marker if it is found.</p> <h2 id="Indicators">Indicators</h2> <p>Indicators are used to display additional information over the top of styling. They can be used to show, for example, syntax errors, deprecated names and bad indentation by drawing underlines under text or boxes around text. Originally, Scintilla stored indicator information in the style bytes but this has proved limiting, so now up to 32 separately stored indicators may be used. While style byte indicators currently still work, they will soon be removed so all the bits in each style byte can be used for lexical states.</p> <p>Indicators may be displayed as simple underlines, squiggly underlines, a line of small 'T' shapes, a line of diagonal hatching, a strike-out or a rectangle around the text.</p> <p>The <code>SCI_INDIC*</code> messages allow you to get and set the visual appearance of the indicators. They all use an <code>indicatorNumber</code> argument in the range 0 to INDIC_MAX(31) to set the indicator to style. To prevent interference the set of indicators is divided up into a range for use by lexers (0..7) and a range for use by containers (8=<code>INDIC_CONTAINER</code> .. 31=<code>INDIC_MAX</code>).</p> <code><a class="message" href="#SCI_INDICSETSTYLE">SCI_INDICSETSTYLE(int indicatorNumber, int indicatorStyle)</a><br /> <a class="message" href="#SCI_INDICGETSTYLE">SCI_INDICGETSTYLE(int indicatorNumber)</a><br /> <a class="message" href="#SCI_INDICSETFORE">SCI_INDICSETFORE(int indicatorNumber, int colour)</a><br /> <a class="message" href="#SCI_INDICGETFORE">SCI_INDICGETFORE(int indicatorNumber)</a><br /> <a class="message" href="#SCI_INDICSETALPHA">SCI_INDICSETALPHA(int indicatorNumber, int alpha)</a><br /> <a class="message" href="#SCI_INDICGETALPHA">SCI_INDICGETALPHA(int indicatorNumber)</a><br /> <a class="message" href="#SCI_INDICSETOUTLINEALPHA">SCI_INDICSETOUTLINEALPHA(int indicatorNumber, int alpha)</a><br /> <a class="message" href="#SCI_INDICGETOUTLINEALPHA">SCI_INDICGETOUTLINEALPHA(int indicatorNumber)</a><br /> <a class="message" href="#SCI_INDICSETUNDER">SCI_INDICSETUNDER(int indicatorNumber, bool under)</a><br /> <a class="message" href="#SCI_INDICGETUNDER">SCI_INDICGETUNDER(int indicatorNumber)</a><br /> <a class="message" href="#SCI_SETINDICATORCURRENT">SCI_SETINDICATORCURRENT(int indicator)</a><br /> <a class="message" href="#SCI_GETINDICATORCURRENT">SCI_GETINDICATORCURRENT</a><br /> <a class="message" href="#SCI_SETINDICATORVALUE">SCI_SETINDICATORVALUE(int value)</a><br /> <a class="message" href="#SCI_GETINDICATORVALUE">SCI_GETINDICATORVALUE</a><br /> <a class="message" href="#SCI_INDICATORFILLRANGE">SCI_INDICATORFILLRANGE(int position, int fillLength)</a><br /> <a class="message" href="#SCI_INDICATORCLEARRANGE">SCI_INDICATORCLEARRANGE(int position, int clearLength)</a><br /> <a class="message" href="#SCI_INDICATORALLONFOR">SCI_INDICATORALLONFOR(int position)</a><br /> <a class="message" href="#SCI_INDICATORVALUEAT">SCI_INDICATORVALUEAT(int indicator, int position)</a><br /> <a class="message" href="#SCI_INDICATORSTART">SCI_INDICATORSTART(int indicator, int position)</a><br /> <a class="message" href="#SCI_INDICATOREND">SCI_INDICATOREND(int indicator, int position)</a><br /> <a class="message" href="#SCI_FINDINDICATORSHOW">SCI_FINDINDICATORSHOW(int start, int end)</a><br /> <a class="message" href="#SCI_FINDINDICATORFLASH">SCI_FINDINDICATORFLASH(int start, int end)</a><br /> <a class="message" href="#SCI_FINDINDICATORHIDE">SCI_FINDINDICATORHIDE</a><br /> </code> <p><b id="SCI_INDICSETSTYLE">SCI_INDICSETSTYLE(int indicatorNumber, int indicatorStyle)</b><br /> <b id="SCI_INDICGETSTYLE">SCI_INDICGETSTYLE(int indicatorNumber)</b><br /> These two messages set and get the style for a particular indicator. The indicator styles currently available are:</p> <table cellpadding="1" cellspacing="2" border="0" summary="Indicators"> <tbody> <tr> <th align="left">Symbol</th> <th>Value</th> <th align="left">Visual effect</th> </tr> </tbody> <tbody valign="top"> <tr> <td align="left"><code>INDIC_PLAIN</code></td> <td align="center">0</td> <td>Underlined with a single, straight line.</td> </tr> <tr> <td align="left"><code>INDIC_SQUIGGLE</code></td> <td align="center">1</td> <td>A squiggly underline. Requires 3 pixels of descender space.</td> </tr> <tr> <td align="left"><code>INDIC_TT</code></td> <td align="center">2</td> <td>A line of small T shapes.</td> </tr> <tr> <td align="left"><code>INDIC_DIAGONAL</code></td> <td align="center">3</td> <td>Diagonal hatching.</td> </tr> <tr> <td align="left"><code>INDIC_STRIKE</code></td> <td align="center">4</td> <td>Strike out.</td> </tr> <tr> <td align="left"><code>INDIC_HIDDEN</code></td> <td align="center">5</td> <td>An indicator with no visual effect.</td> </tr> <tr> <td align="left"><code>INDIC_BOX</code></td> <td align="center">6</td> <td>A rectangle around the text.</td> </tr> <tr> <td align="left"><code>INDIC_ROUNDBOX</code></td> <td align="center">7</td> <td>A rectangle with rounded corners around the text using translucent drawing with the interior usually more transparent than the border. You can use <a class="message" href="#SCI_INDICSETALPHA">SCI_INDICSETALPHA</a> and <a class="message" href="#SCI_INDICSETOUTLINEALPHA">SCI_INDICSETOUTLINEALPHA</a> to control the alpha transparency values. The default alpha values are 30 for fill colour and 50 for outline colour.</td> </tr> <tr> <td align="left"><code>INDIC_STRAIGHTBOX</code></td> <td align="center">8</td> <td>A rectangle around the text using translucent drawing with the interior usually more transparent than the border. You can use <a class="message" href="#SCI_INDICSETALPHA">SCI_INDICSETALPHA</a> and <a class="message" href="#SCI_INDICSETOUTLINEALPHA">SCI_INDICSETOUTLINEALPHA</a> to control the alpha transparency values. The default alpha values are 30 for fill colour and 50 for outline colour.</td> </tr> <tr> <td align="left"><code>INDIC_DASH</code></td> <td align="center">9</td> <td>A dashed underline.</td> </tr> <tr> <td align="left"><code>INDIC_DOTS</code></td> <td align="center">10</td> <td>A dotted underline.</td> </tr> <tr> <td align="left"><code>INDIC_SQUIGGLELOW</code></td> <td align="center">11</td> <td>Similar to <code>INDIC_SQUIGGLE</code> but only using 2 vertical pixels so will fit under small fonts.</td> </tr> <tr> <td align="left"><code>INDIC_DOTBOX</code></td> <td align="center">12</td> <td>A dotted rectangle around the text using translucent drawing. Translucency alternates between the alpha and outline alpha settings with the top-left pixel using the alpha setting. <a class="message" href="#SCI_INDICSETALPHA">SCI_INDICSETALPHA</a> and <a class="message" href="#SCI_INDICSETOUTLINEALPHA">SCI_INDICSETOUTLINEALPHA</a> control the alpha transparency values. The default values are 30 for alpha and 50 for outline alpha. To avoid excessive memory allocation the maximum width of a dotted box is 4000 pixels. Not available for OS X Carbon.</td> </tr> <tr> <td align="left"><code>INDIC_SQUIGGLEPIXMAP</code></td> <td align="center">13</td> <td>A version of <code>INDIC_SQUIGGLE</code> that draws using a pixmap instead of as a series of line segments for performance. Measured to be between 3 and 6 times faster than <code>INDIC_SQUIGGLE</code> on GTK+. Apperance will not be as good as <code>INDIC_SQUIGGLE</code> on OS X in HiDPI mode.</td> </tr> </tbody> </table> <p>The default indicator styles are equivalent to:<br /> <code>SCI_INDICSETSTYLE(0, INDIC_SQUIGGLE);</code><br /> <code>SCI_INDICSETSTYLE(1, INDIC_TT);</code><br /> <code>SCI_INDICSETSTYLE(2, INDIC_PLAIN);</code></p> <p><b id="SCI_INDICSETFORE">SCI_INDICSETFORE(int indicatorNumber, int <a class="jump" href="#colour">colour</a>)</b><br /> <b id="SCI_INDICGETFORE">SCI_INDICGETFORE(int indicatorNumber)</b><br /> These two messages set and get the colour used to draw an indicator. The default indicator colours are equivalent to:<br /> <code>SCI_INDICSETFORE(0, 0x007f00);</code> (dark green)<br /> <code>SCI_INDICSETFORE(1, 0xff0000);</code> (light blue)<br /> <code>SCI_INDICSETFORE(2, 0x0000ff);</code> (light red)</p> <p><b id="SCI_INDICSETALPHA">SCI_INDICSETALPHA(int indicatorNumber, int alpha)</b><br /> <b id="SCI_INDICGETALPHA">SCI_INDICGETALPHA(int indicatorNumber)</b><br /> These two messages set and get the alpha transparency used for drawing the fill colour of the INDIC_ROUNDBOX and INDIC_STRAIGHTBOX rectangle. The alpha value can range from 0 (completely transparent) to 255 (no transparency). </p> <p><b id="SCI_INDICSETOUTLINEALPHA">SCI_INDICSETOUTLINEALPHA(int indicatorNumber, int alpha)</b><br /> <b id="SCI_INDICGETOUTLINEALPHA">SCI_INDICGETOUTLINEALPHA(int indicatorNumber)</b><br /> These two messages set and get the alpha transparency used for drawing the outline colour of the INDIC_ROUNDBOX and INDIC_STRAIGHTBOX rectangle. The alpha value can range from 0 (completely transparent) to 255 (no transparency). </p> <p><b id="SCI_INDICSETUNDER">SCI_INDICSETUNDER(int indicatorNumber, bool under)</b><br /> <b id="SCI_INDICGETUNDER">SCI_INDICGETUNDER(int indicatorNumber)</b><br /> These two messages set and get whether an indicator is drawn under text or over(default). Drawing under text works only for modern indicators when <a class="message" href="#SCI_SETTWOPHASEDRAW">two phase drawing</a> is enabled.</p> <h3 id="ModernIndicators">Modern Indicators</h3> <p>Modern indicators are stored in a format similar to run length encoding which is efficient in both speed and storage for sparse information.</p> <p>An indicator may store different values for each range but currently all values are drawn the same. In the future, it may be possible to draw different values in different styles.</p> <p> <b id="SCI_SETINDICATORCURRENT">SCI_SETINDICATORCURRENT(int indicator)</b><br /> <b id="SCI_GETINDICATORCURRENT">SCI_GETINDICATORCURRENT</b><br /> These two messages set and get the indicator that will be affected by calls to <a class="message" href="#SCI_INDICATORFILLRANGE">SCI_INDICATORFILLRANGE(int position, int fillLength)</a> and <a class="message" href="#SCI_INDICATORCLEARRANGE">SCI_INDICATORCLEARRANGE(int position, int clearLength)</a>. </p> <p> <b id="SCI_SETINDICATORVALUE">SCI_SETINDICATORVALUE(int value)</b><br /> <b id="SCI_GETINDICATORVALUE">SCI_GETINDICATORVALUE</b><br /> These two messages set and get the value that will be set by calls to <a class="message" href="#SCI_INDICATORFILLRANGE">SCI_INDICATORFILLRANGE</a>. </p> <p> <b id="SCI_INDICATORFILLRANGE">SCI_INDICATORFILLRANGE(int position, int fillLength)</b><br /> <b id="SCI_INDICATORCLEARRANGE">SCI_INDICATORCLEARRANGE(int position, int clearLength)</b><br /> These two messages fill or clear a range for the current indicator. <code>SCI_INDICATORFILLRANGE</code> fills with the the current value. </p> <p> <b id="SCI_INDICATORALLONFOR">SCI_INDICATORALLONFOR(int position)</b><br /> Retrieve a bitmap value representing which indicators are non-zero at a position. </p> <p> <b id="SCI_INDICATORVALUEAT">SCI_INDICATORVALUEAT(int indicator, int position)</b><br /> Retrieve the value of a particular indicator at a position. </p> <p> <b id="SCI_INDICATORSTART">SCI_INDICATORSTART(int indicator, int position)</b><br /> <b id="SCI_INDICATOREND">SCI_INDICATOREND(int indicator, int position)</b><br /> Find the start or end of a range with one value from a position within the range. Can be used to iterate through the document to discover all the indicator positions. </p> <h3 id="FindIndicators">OS X Find Indicator</h3> <p>On OS X search matches are highlighted with an animated gold rounded rectangle. The indicator shows, then briefly grows 25% and shrinks to the original size to draw the user's attention. While this feature is currently only implemented on OS X, it may be implemented on other platforms in the future.</p> <p><b id="SCI_FINDINDICATORSHOW">SCI_FINDINDICATORSHOW(int start, int end)</b><br /> <b id="SCI_FINDINDICATORFLASH">SCI_FINDINDICATORFLASH(int start, int end)</b><br /> These two messages show and animate the find indicator. The indicator remains visible with <code>SCI_FINDINDICATORSHOW</code> and fades out after showing for half a second with <code>SCI_FINDINDICATORFLASH</code>. <code>SCI_FINDINDICATORSHOW</code> behaves similarly to the OS X TextEdit and Safari applications and is best suited to editing documentation where the search target is often a word. <code>SCI_FINDINDICATORFLASH</code> is similar to Xcode and is suited to editing source code where the match will often be located next to operators which would otherwise be hidden under the indicator's padding. </p> <p><b id="SCI_FINDINDICATORHIDE">SCI_FINDINDICATORHIDE</b><br /> This message hides the find indicator. </p> <h3 id="StyleByteIndicators">Style Byte Indicators (deprecated)</h3> <p>By default, Scintilla organizes the style byte associated with each text byte as 5 bits of style information (for 32 styles) and 3 bits of indicator information for 3 independent indicators so that, for example, syntax errors, deprecated names and bad indentation could all be displayed at once.</p> <p>The indicators are set using <a class="message" href="#SCI_STARTSTYLING"><code>SCI_STARTSTYLING</code></a> with a <code>INDICS_MASK</code> mask and <a class="message" href="#SCI_SETSTYLING"><code>SCI_SETSTYLING</code></a> with the values <code>INDIC0_MASK</code>, <code>INDIC1_MASK</code> and <code>INDIC2_MASK</code>.</p> <p>If you are using indicators in a buffer that has a lexer active (see <a class="message" href="#SCI_SETLEXER"><code>SCI_SETLEXER</code></a>), you must save lexing state information before setting any indicators and restore it afterwards. Use <a class="message" href="#SCI_GETENDSTYLED"><code>SCI_GETENDSTYLED</code></a> to retrieve the current "styled to" position and <a class="message" href="#SCI_STARTSTYLING"><code>SCI_STARTSTYLING</code></a> to reset the styling position and mask (<code>0x1f </code> in the default layout of 5 style bits and 3 indicator bits) when you are done.</p> <p>The number of bits used for styles can be altered with <a class="message" href="#SCI_SETSTYLEBITS"><code>SCI_SETSTYLEBITS</code></a> from 0 to 8 bits. The remaining bits can be used for indicators, so there can be from 1 to 8 indicators. However, the <code>INDIC*_MASK</code> constants defined in <code>Scintilla.h</code> all assume 5 bits of styling information and 3 indicators. If you use a different arrangement, you must define your own constants.</p> <h2 id="Autocompletion">Autocompletion</h2> <p>Autocompletion displays a list box showing likely identifiers based upon the user's typing. The user chooses the currently selected item by pressing the tab character or another character that is a member of the fillup character set defined with <code>SCI_AUTOCSETFILLUPS</code>. Autocompletion is triggered by your application. For example, in C if you detect that the user has just typed <code>fred.</code> you could look up <code>fred</code>, and if it has a known list of members, you could offer them in an autocompletion list. Alternatively, you could monitor the user's typing and offer a list of likely items once their typing has narrowed down the choice to a reasonable list. As yet another alternative, you could define a key code to activate the list.</p> <p>When the user makes a selection from the list the container is sent a <code><a class="message" href="#SCN_AUTOCSELECTION">SCN_AUTOCSELECTION</a></code> <a class="jump" href="#Notifications">notification message</a>. On return from the notification Scintilla will insert the selected text unless the autocompletion list has been cancelled, for example by the container sending <code><a class="message" href="#SCI_AUTOCCANCEL">SCI_AUTOCCANCEL</a></code>.</p> <p>To make use of autocompletion you must monitor each character added to the document. See <code>SciTEBase::CharAdded()</code> in SciTEBase.cxx for an example of autocompletion.</p> <code><a class="message" href="#SCI_AUTOCSHOW">SCI_AUTOCSHOW(int lenEntered, const char *list)</a><br /> <a class="message" href="#SCI_AUTOCCANCEL">SCI_AUTOCCANCEL</a><br /> <a class="message" href="#SCI_AUTOCACTIVE">SCI_AUTOCACTIVE</a><br /> <a class="message" href="#SCI_AUTOCPOSSTART">SCI_AUTOCPOSSTART</a><br /> <a class="message" href="#SCI_AUTOCCOMPLETE">SCI_AUTOCCOMPLETE</a><br /> <a class="message" href="#SCI_AUTOCSTOPS">SCI_AUTOCSTOPS(<unused>, const char *chars)</a><br /> <a class="message" href="#SCI_AUTOCSETSEPARATOR">SCI_AUTOCSETSEPARATOR(char separator)</a><br /> <a class="message" href="#SCI_AUTOCGETSEPARATOR">SCI_AUTOCGETSEPARATOR</a><br /> <a class="message" href="#SCI_AUTOCSELECT">SCI_AUTOCSELECT(<unused>, const char *select)</a><br /> <a class="message" href="#SCI_AUTOCGETCURRENT">SCI_AUTOCGETCURRENT</a><br /> <a class="message" href="#SCI_AUTOCGETCURRENTTEXT">SCI_AUTOCGETCURRENTTEXT(<unused>, char *text)</a><br /> <a class="message" href="#SCI_AUTOCSETCANCELATSTART">SCI_AUTOCSETCANCELATSTART(bool cancel)</a><br /> <a class="message" href="#SCI_AUTOCGETCANCELATSTART">SCI_AUTOCGETCANCELATSTART</a><br /> <a class="message" href="#SCI_AUTOCSETFILLUPS">SCI_AUTOCSETFILLUPS(<unused>, const char *chars)</a><br /> <a class="message" href="#SCI_AUTOCSETCHOOSESINGLE">SCI_AUTOCSETCHOOSESINGLE(bool chooseSingle)</a><br /> <a class="message" href="#SCI_AUTOCGETCHOOSESINGLE">SCI_AUTOCGETCHOOSESINGLE</a><br /> <a class="message" href="#SCI_AUTOCSETIGNORECASE">SCI_AUTOCSETIGNORECASE(bool ignoreCase)</a><br /> <a class="message" href="#SCI_AUTOCGETIGNORECASE">SCI_AUTOCGETIGNORECASE</a><br /> <a class="message" href="#SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR">SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR(int behaviour)</a><br> <a class="message" href="#SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR">SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR</a><br> <a class="message" href="#SCI_AUTOCSETAUTOHIDE">SCI_AUTOCSETAUTOHIDE(bool autoHide)</a><br /> <a class="message" href="#SCI_AUTOCGETAUTOHIDE">SCI_AUTOCGETAUTOHIDE</a><br /> <a class="message" href="#SCI_AUTOCSETDROPRESTOFWORD">SCI_AUTOCSETDROPRESTOFWORD(bool dropRestOfWord)</a><br /> <a class="message" href="#SCI_AUTOCGETDROPRESTOFWORD">SCI_AUTOCGETDROPRESTOFWORD</a><br /> <a class="message" href="#SCI_REGISTERIMAGE">SCI_REGISTERIMAGE(int type, const char *xpmData)</a><br /> <a class="message" href="#SCI_REGISTERRGBAIMAGE">SCI_REGISTERRGBAIMAGE(int type, const char *pixels)</a><br /> <a class="message" href="#SCI_CLEARREGISTEREDIMAGES">SCI_CLEARREGISTEREDIMAGES</a><br /> <a class="message" href="#SCI_AUTOCSETTYPESEPARATOR">SCI_AUTOCSETTYPESEPARATOR(char separatorCharacter)</a><br /> <a class="message" href="#SCI_AUTOCGETTYPESEPARATOR">SCI_AUTOCGETTYPESEPARATOR</a><br /> <a class="message" href="#SCI_AUTOCSETMAXHEIGHT">SCI_AUTOCSETMAXHEIGHT(int rowCount)</a><br /> <a class="message" href="#SCI_AUTOCGETMAXHEIGHT">SCI_AUTOCGETMAXHEIGHT</a><br /> <a class="message" href="#SCI_AUTOCSETMAXWIDTH">SCI_AUTOCSETMAXWIDTH(int characterCount)</a><br /> <a class="message" href="#SCI_AUTOCGETMAXWIDTH">SCI_AUTOCGETMAXWIDTH</a><br /> </code> <p><b id="SCI_AUTOCSHOW">SCI_AUTOCSHOW(int lenEntered, const char *list)</b><br /> This message causes a list to be displayed. <code>lenEntered</code> is the number of characters of the word already entered and <code>list</code> is the list of words separated by separator characters. The initial separator character is a space but this can be set or got with <a class="message" href="#SCI_AUTOCSETSEPARATOR"><code>SCI_AUTOCSETSEPARATOR</code></a> and <a class="message" href="#SCI_AUTOCGETSEPARATOR"><code>SCI_AUTOCGETSEPARATOR</code></a>.</p> <p>The list of words should be in sorted order. If set to ignore case mode with <a class="message" href="#SCI_AUTOCSETIGNORECASE"><code>SCI_AUTOCSETIGNORECASE</code></a>, then strings are matched after being converted to upper case. One result of this is that the list should be sorted with the punctuation characters '[', '\', ']', '^', '_', and '`' sorted after letters.</p> <p><b id="SCI_AUTOCCANCEL">SCI_AUTOCCANCEL</b><br /> This message cancels any displayed autocompletion list. When in autocompletion mode, the list should disappear when the user types a character that can not be part of the autocompletion, such as '.', '(' or '[' when typing an identifier. A set of characters that will cancel autocompletion can be specified with <a class="message" href="#SCI_AUTOCSTOPS"><code>SCI_AUTOCSTOPS</code></a>.</p> <p><b id="SCI_AUTOCACTIVE">SCI_AUTOCACTIVE</b><br /> This message returns non-zero if there is an active autocompletion list and zero if there is not.</p> <p><b id="SCI_AUTOCPOSSTART">SCI_AUTOCPOSSTART</b><br /> This returns the value of the current position when <code>SCI_AUTOCSHOW</code> started display of the list.</p> <p><b id="SCI_AUTOCCOMPLETE">SCI_AUTOCCOMPLETE</b><br /> This message triggers autocompletion. This has the same effect as the tab key.</p> <p><b id="SCI_AUTOCSTOPS">SCI_AUTOCSTOPS(<unused>, const char *chars)</b><br /> The <code>chars</code> argument is a string containing a list of characters that will automatically cancel the autocompletion list. When you start the editor, this list is empty.</p> <p><b id="SCI_AUTOCSETSEPARATOR">SCI_AUTOCSETSEPARATOR(char separator)</b><br /> <b id="SCI_AUTOCGETSEPARATOR">SCI_AUTOCGETSEPARATOR</b><br /> These two messages set and get the separator character used to separate words in the <code>SCI_AUTOCSHOW</code> list. The default is the space character.</p> <p><b id="SCI_AUTOCSELECT">SCI_AUTOCSELECT(<unused>, const char *select)</b><br /> <b id="SCI_AUTOCGETCURRENT">SCI_AUTOCGETCURRENT</b><br /> This message selects an item in the autocompletion list. It searches the list of words for the first that matches <code>select</code>. By default, comparisons are case sensitive, but you can change this with <a class="message" href="#SCI_AUTOCSETIGNORECASE"><code>SCI_AUTOCSETIGNORECASE</code></a>. The match is character by character for the length of the <code>select</code> string. That is, if select is "Fred" it will match "Frederick" if this is the first item in the list that begins with "Fred". If an item is found, it is selected. If the item is not found, the autocompletion list closes if auto-hide is true (see <a class="message" href="#SCI_AUTOCSETAUTOHIDE"><code>SCI_AUTOCSETAUTOHIDE</code></a>).<br /> The current selection index can be retrieved with <code>SCI_AUTOCGETCURRENT</code>.</p> <p><b id="SCI_AUTOCGETCURRENTTEXT">SCI_AUTOCGETCURRENTTEXT(<unused>, char *text)</b><br /> This message retrieves the current selected text in the autocompletion list. Normally the <a class="message" href="#SCN_AUTOCSELECTION"><code>SCN_AUTOCSELECTION</code></a> notification is used instead.</p> <p>The value is copied to the <code>text</code> buffer, returning the length (not including the terminating 0). If not found, an empty string is copied to the buffer and 0 is returned.</p> <p>If the value argument is 0 then the length that should be allocated to store the value is returned; again, the terminating 0 is not included.</p> <p><b id="SCI_AUTOCSETCANCELATSTART">SCI_AUTOCSETCANCELATSTART(bool cancel)</b><br /> <b id="SCI_AUTOCGETCANCELATSTART">SCI_AUTOCGETCANCELATSTART</b><br /> The default behavior is for the list to be cancelled if the caret moves to the location it was at when the list was displayed. By calling this message with a <code>false</code> argument, the list is not cancelled until the caret moves at least one character before the word being completed.</p> <p><b id="SCI_AUTOCSETFILLUPS">SCI_AUTOCSETFILLUPS(<unused>, const char *chars)</b><br /> If a fillup character is typed with an autocompletion list active, the currently selected item in the list is added into the document, then the fillup character is added. Common fillup characters are '(', '[' and '.' but others are possible depending on the language. By default, no fillup characters are set.</p> <p><b id="SCI_AUTOCSETCHOOSESINGLE">SCI_AUTOCSETCHOOSESINGLE(bool chooseSingle)</b><br /> <b id="SCI_AUTOCGETCHOOSESINGLE">SCI_AUTOCGETCHOOSESINGLE</b><br /> If you use <code>SCI_AUTOCSETCHOOSESINGLE(1)</code> and a list has only one item, it is automatically added and no list is displayed. The default is to display the list even if there is only a single item.</p> <p><b id="SCI_AUTOCSETIGNORECASE">SCI_AUTOCSETIGNORECASE(bool ignoreCase)</b><br /> <b id="SCI_AUTOCGETIGNORECASE">SCI_AUTOCGETIGNORECASE</b><br /> By default, matching of characters to list members is case sensitive. These messages let you set and get case sensitivity.</p> <p><b id="SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR">SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR(int behaviour)</b><br> <b id="SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR">SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR</b><br> When autocompletion is set to ignore case (<code>SCI_AUTOCSETIGNORECASE</code>), by default it will nonetheless select the first list member that matches in a case sensitive way to entered characters. This corresponds to a behaviour property of <code>SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE</code> (0). If you want autocompletion to ignore case at all, choose <code>SC_CASEINSENSITIVEBEHAVIOUR_IGNORECASE</code> (1).</p> <p><b id="SCI_AUTOCSETAUTOHIDE">SCI_AUTOCSETAUTOHIDE(bool autoHide)</b><br /> <b id="SCI_AUTOCGETAUTOHIDE">SCI_AUTOCGETAUTOHIDE</b><br /> By default, the list is cancelled if there are no viable matches (the user has typed characters that no longer match a list entry). If you want to keep displaying the original list, set <code>autoHide</code> to <code>false</code>. This also effects <a class="message" href="#SCI_AUTOCSELECT"><code>SCI_AUTOCSELECT</code></a>.</p> <p><b id="SCI_AUTOCSETDROPRESTOFWORD">SCI_AUTOCSETDROPRESTOFWORD(bool dropRestOfWord)</b><br /> <b id="SCI_AUTOCGETDROPRESTOFWORD">SCI_AUTOCGETDROPRESTOFWORD</b><br /> When an item is selected, any word characters following the caret are first erased if <code>dropRestOfWord</code> is set <code>true</code>. The default is <code>false</code>.</p> <p> <b id="SCI_REGISTERIMAGE">SCI_REGISTERIMAGE(int type, const char *xpmData)</b><br /> <b id="SCI_REGISTERRGBAIMAGE">SCI_REGISTERRGBAIMAGE(int type, const char *pixels)</b><br /> <b id="SCI_CLEARREGISTEREDIMAGES">SCI_CLEARREGISTEREDIMAGES</b><br /> <b id="SCI_AUTOCSETTYPESEPARATOR">SCI_AUTOCSETTYPESEPARATOR(char separatorCharacter)</b><br /> <b id="SCI_AUTOCGETTYPESEPARATOR">SCI_AUTOCGETTYPESEPARATOR</b><br /> Autocompletion list items may display an image as well as text. Each image is first registered with an integer type. Then this integer is included in the text of the list separated by a '?' from the text. For example, "fclose?2 fopen" displays image 2 before the string "fclose" and no image before "fopen". The images are in either the <a class="jump" href="#XPM">XPM format</a> (<code>SCI_REGISTERIMAGE</code>) or <a class="jump" href="#RGBA">RGBA format</a> (<code>SCI_REGISTERRGBAIMAGE</code>). For <code>SCI_REGISTERRGBAIMAGE</code> the width and height must previously been set with the <a class="message" href="#SCI_RGBAIMAGESETWIDTH"><code>SCI_RGBAIMAGESETWIDTH</code></a> and <a class="message" href="#SCI_RGBAIMAGESETHEIGHT"><code>SCI_RGBAIMAGESETHEIGHT</code></a> messages. The set of registered images can be cleared with <code>SCI_CLEARREGISTEREDIMAGES</code> and the '?' separator changed with <code>SCI_AUTOCSETTYPESEPARATOR</code>. </p> <p> <b id="SCI_AUTOCSETMAXHEIGHT">SCI_AUTOCSETMAXHEIGHT(int rowCount)</b><br /> <b id="SCI_AUTOCGETMAXHEIGHT">SCI_AUTOCGETMAXHEIGHT</b><br /> Get or set the maximum number of rows that will be visible in an autocompletion list. If there are more rows in the list, then a vertical scrollbar is shown. The default is 5. </p> <p> <b id="SCI_AUTOCSETMAXWIDTH">SCI_AUTOCSETMAXWIDTH(int characterCount)</b><br /> <b id="SCI_AUTOCGETMAXWIDTH">SCI_AUTOCGETMAXWIDTH</b><br /> Get or set the maximum width of an autocompletion list expressed as the number of characters in the longest item that will be totally visible. If zero (the default) then the list's width is calculated to fit the item with the most characters. Any items that cannot be fully displayed within the available width are indicated by the presence of ellipsis. </p> <h2 id="UserLists">User lists</h2> <p>User lists use the same internal mechanisms as autocompletion lists, and all the calls listed for autocompletion work on them; you cannot display a user list at the same time as an autocompletion list is active. They differ in the following respects:</p> <p>o The <code><a class="message" href="#SCI_AUTOCSETCHOOSESINGLE">SCI_AUTOCSETCHOOSESINGLE</a></code> message has no effect.<br /> o When the user makes a selection you are sent a <code><a class="message" href="#SCN_USERLISTSELECTION">SCN_USERLISTSELECTION</a></code> <a class="jump" href="#Notifications">notification message</a> rather than <code><a class="message" href="#SCN_AUTOCSELECTION">SCN_AUTOCSELECTION</a></code>.</p> <p>BEWARE: if you have set fillup characters or stop characters, these will still be active with the user list, and may result in items being selected or the user list cancelled due to the user typing into the editor.</p> <p><b id="SCI_USERLISTSHOW">SCI_USERLISTSHOW(int listType, const char *list)</b><br /> The <code>listType</code> parameter is returned to the container as the <code>wParam</code> field of the <a class="message" href="#SCNotification"><code>SCNotification</code></a> structure. It must be greater than 0 as this is how Scintilla tells the difference between an autocompletion list and a user list. If you have different types of list, for example a list of buffers and a list of macros, you can use <code>listType</code> to tell which one has returned a selection. </p> <h2 id="CallTips">Call tips</h2> <p>Call tips are small windows displaying the arguments to a function and are displayed after the user has typed the name of the function. They normally display characters using the font facename, size and character set defined by <code><a class="message" href="#StyleDefinition">STYLE_DEFAULT</a></code>. You can choose to use <code><a class="message" href="#StyleDefinition">STYLE_CALLTIP</a></code> to define the facename, size, foreground and background colours and character set with <code><a class="message" href="#SCI_CALLTIPUSESTYLE">SCI_CALLTIPUSESTYLE</a></code>. This also enables support for Tab characters. There is some interaction between call tips and autocompletion lists in that showing a call tip cancels any active autocompletion list, and vice versa.</p> <p>Call tips can highlight part of the text within them. You could use this to highlight the current argument to a function by counting the number of commas (or whatever separator your language uses). See <code>SciTEBase::CharAdded()</code> in <code>SciTEBase.cxx</code> for an example of call tip use.</p> <p>The mouse may be clicked on call tips and this causes a <code><a class="message" href="#SCN_CALLTIPCLICK">SCN_CALLTIPCLICK</a></code> notification to be sent to the container. Small up and down arrows may be displayed within a call tip by, respectively, including the characters '\001', or '\002'. This is useful for showing that there are overloaded variants of one function name and that the user can click on the arrows to cycle through the overloads.</p> <p>Alternatively, call tips can be displayed when you leave the mouse pointer for a while over a word in response to the <code><a class="message" href="#SCN_DWELLSTART">SCN_DWELLSTART</a></code> <a class="jump" href="#Notifications">notification</a> and cancelled in response to <code><a class="message" href="#SCN_DWELLEND">SCN_DWELLEND</a></code>. This method could be used in a debugger to give the value of a variable, or during editing to give information about the word under the pointer.</p> <code><a class="message" href="#SCI_CALLTIPSHOW">SCI_CALLTIPSHOW(int posStart, const char *definition)</a><br /> <a class="message" href="#SCI_CALLTIPCANCEL">SCI_CALLTIPCANCEL</a><br /> <a class="message" href="#SCI_CALLTIPACTIVE">SCI_CALLTIPACTIVE</a><br /> <a class="message" href="#SCI_CALLTIPPOSSTART">SCI_CALLTIPPOSSTART</a><br /> <a class="message" href="#SCI_CALLTIPSETHLT">SCI_CALLTIPSETHLT(int highlightStart, int highlightEnd)</a><br /> <a class="message" href="#SCI_CALLTIPSETBACK">SCI_CALLTIPSETBACK(int colour)</a><br /> <a class="message" href="#SCI_CALLTIPSETFORE">SCI_CALLTIPSETFORE(int colour)</a><br /> <a class="message" href="#SCI_CALLTIPSETFOREHLT">SCI_CALLTIPSETFOREHLT(int colour)</a><br /> <a class="message" href="#SCI_CALLTIPUSESTYLE">SCI_CALLTIPUSESTYLE(int tabsize)</a><br /> <a class="message" href="#SCI_CALLTIPSETPOSITION">SCI_CALLTIPSETPOSITION(bool above)</a><br /> </code> <p><b id="SCI_CALLTIPSHOW">SCI_CALLTIPSHOW(int posStart, const char *definition)</b><br /> This message starts the process by displaying the call tip window. If a call tip is already active, this has no effect.<br /> <code>posStart</code> is the position in the document at which to align the call tip. The call tip text is aligned to start 1 line below this character unless you have included up and/or down arrows in the call tip text in which case the tip is aligned to the right-hand edge of the rightmost arrow. The assumption is that you will start the text with something like "\001 1 of 3 \002".<br /> <code>definition</code> is the call tip text. This can contain multiple lines separated by '\n' (Line Feed, ASCII code 10) characters. Do not include '\r' (Carriage Return, ASCII code 13), as this will most likely print as an empty box. '\t' (Tab, ASCII code 9) is supported if you set a tabsize with <code><a class="message" href="#SCI_CALLTIPUSESTYLE">SCI_CALLTIPUSESTYLE</a></code>.<br /></p> <p><b id="SCI_CALLTIPCANCEL">SCI_CALLTIPCANCEL</b><br /> This message cancels any displayed call tip. Scintilla will also cancel call tips for you if you use any keyboard commands that are not compatible with editing the argument list of a function.</p> <p><b id="SCI_CALLTIPACTIVE">SCI_CALLTIPACTIVE</b><br /> This returns 1 if a call tip is active and 0 if it is not active.</p> <p><b id="SCI_CALLTIPPOSSTART">SCI_CALLTIPPOSSTART</b><br /> This message returns the value of the current position when <code>SCI_CALLTIPSHOW</code> started to display the tip.</p> <p><b id="SCI_CALLTIPSETHLT">SCI_CALLTIPSETHLT(int hlStart, int hlEnd)</b><br /> This sets the region of the call tips text to display in a highlighted style. <code>hlStart</code> is the zero-based index into the string of the first character to highlight and <code>hlEnd</code> is the index of the first character after the highlight. <code>hlEnd</code> must be greater than <code>hlStart</code>; <code>hlEnd-hlStart</code> is the number of characters to highlight. Highlights can extend over line ends if this is required.</p> <p>Unhighlighted text is drawn in a mid gray. Selected text is drawn in a dark blue. The background is white. These can be changed with <code>SCI_CALLTIPSETBACK</code>, <code>SCI_CALLTIPSETFORE</code>, and <code>SCI_CALLTIPSETFOREHLT</code>. </p> <p><b id="SCI_CALLTIPSETBACK">SCI_CALLTIPSETBACK(int colour)</b><br /> The background colour of call tips can be set with this message; the default colour is white. It is not a good idea to set a dark colour as the background as the default colour for normal calltip text is mid gray and the defaultcolour for highlighted text is dark blue. This also sets the background colour of <code>STYLE_CALLTIP</code>.</p> <p><b id="SCI_CALLTIPSETFORE">SCI_CALLTIPSETFORE(int colour)</b><br /> The colour of call tip text can be set with this message; the default colour is mid gray. This also sets the foreground colour of <code>STYLE_CALLTIP</code>.</p> <p><b id="SCI_CALLTIPSETFOREHLT">SCI_CALLTIPSETFOREHLT(int colour)</b><br /> The colour of highlighted call tip text can be set with this message; the default colour is dark blue.</p> <p><b id="SCI_CALLTIPUSESTYLE">SCI_CALLTIPUSESTYLE(int tabsize)</b><br /> This message changes the style used for call tips from <code>STYLE_DEFAULT</code> to <code>STYLE_CALLTIP</code> and sets a tab size in screen pixels. If <code>tabsize</code> is less than 1, Tab characters are not treated specially. Once this call has been used, the call tip foreground and background colours are also taken from the style.</p> <p><b id="SCI_CALLTIPSETPOSITION">SCI_CALLTIPSETPOSITION(bool above)</b><br /> By default the calltip is displayed below the text, setting above to <code>true</code> (1) will display it above the text.</p> <h2 id="KeyboardCommands">Keyboard commands</h2> <p>To allow the container application to perform any of the actions available to the user with keyboard, all the keyboard actions are messages. They do not take any parameters. These commands are also used when redefining the key bindings with the <a class="message" href="#SCI_ASSIGNCMDKEY"><code>SCI_ASSIGNCMDKEY</code></a> message.</p> <table border="0" summary="Keyboard commands"> <tbody> <tr> <td><code>SCI_LINEDOWN</code></td> <td><code>SCI_LINEDOWNEXTEND</code></td> <td><code>SCI_LINEDOWNRECTEXTEND</code></td> <td><code>SCI_LINESCROLLDOWN</code></td> </tr> <tr> <td><code>SCI_LINEUP</code></td> <td><code>SCI_LINEUPEXTEND</code></td> <td><code>SCI_LINEUPRECTEXTEND</code></td> <td><code>SCI_LINESCROLLUP</code></td> </tr> <tr> <td><code>SCI_PARADOWN</code></td> <td><code>SCI_PARADOWNEXTEND</code></td> <td><code>SCI_PARAUP</code></td> <td><code>SCI_PARAUPEXTEND</code></td> </tr> <tr> <td><code>SCI_CHARLEFT</code></td> <td><code>SCI_CHARLEFTEXTEND</code></td> <td><code>SCI_CHARLEFTRECTEXTEND</code></td> </tr> <tr> <td><code>SCI_CHARRIGHT</code></td> <td><code>SCI_CHARRIGHTEXTEND</code></td> <td><code>SCI_CHARRIGHTRECTEXTEND</code></td> </tr> <tr> <td><code>SCI_WORDLEFT</code></td> <td><code>SCI_WORDLEFTEXTEND</code></td> <td><code>SCI_WORDRIGHT</code></td> <td><code>SCI_WORDRIGHTEXTEND</code></td> </tr> <tr> <td><code>SCI_WORDLEFTEND</code></td> <td><code>SCI_WORDLEFTENDEXTEND</code></td> <td><code>SCI_WORDRIGHTEND</code></td> <td><code>SCI_WORDRIGHTENDEXTEND</code></td> </tr> <tr> <td><code>SCI_WORDPARTLEFT</code></td> <td><code>SCI_WORDPARTLEFTEXTEND</code></td> <td><code>SCI_WORDPARTRIGHT</code></td> <td><code>SCI_WORDPARTRIGHTEXTEND</code></td> </tr> <tr> <td><code>SCI_HOME</code></td> <td><code>SCI_HOMEEXTEND</code></td> <td><code>SCI_HOMERECTEXTEND</code></td> </tr> <tr> <td><code>SCI_HOMEDISPLAY</code></td> <td><code>SCI_HOMEDISPLAYEXTEND</code></td> <td><code>SCI_HOMEWRAP</code></td> <td><code>SCI_HOMEWRAPEXTEND</code></td> </tr> <tr> <td><code>SCI_VCHOME</code></td> <td><code>SCI_VCHOMEEXTEND</code></td> <td><code>SCI_VCHOMERECTEXTEND</code></td> </tr> <tr> <td><code>SCI_VCHOMEWRAP</code></td> <td><code>SCI_VCHOMEWRAPEXTEND</code></td> <td><code>SCI_VCHOMEDISPLAY</code></td> <td><code>SCI_VCHOMEDISPLAYEXTEND</code></td> </tr> <tr> <td><code>SCI_LINEEND</code></td> <td><code>SCI_LINEENDEXTEND</code></td> <td><code>SCI_LINEENDRECTEXTEND</code></td> </tr> <tr> <td><code>SCI_LINEENDDISPLAY</code></td> <td><code>SCI_LINEENDDISPLAYEXTEND</code></td> <td><code>SCI_LINEENDWRAP</code></td> <td><code>SCI_LINEENDWRAPEXTEND</code></td> </tr> <tr> <td><code>SCI_DOCUMENTSTART</code></td> <td><code>SCI_DOCUMENTSTARTEXTEND</code></td> <td><code>SCI_DOCUMENTEND</code></td> <td><code>SCI_DOCUMENTENDEXTEND</code></td> </tr> <tr> <td><code>SCI_PAGEUP</code></td> <td><code>SCI_PAGEUPEXTEND</code></td> <td><code>SCI_PAGEUPRECTEXTEND</code></td> </tr> <tr> <td><code>SCI_PAGEDOWN</code></td> <td><code>SCI_PAGEDOWNEXTEND</code></td> <td><code>SCI_PAGEDOWNRECTEXTEND</code></td> </tr> <tr> <td><code>SCI_STUTTEREDPAGEUP</code></td> <td><code>SCI_STUTTEREDPAGEUPEXTEND</code></td> </tr> <tr> <td><code>SCI_STUTTEREDPAGEDOWN</code></td> <td><code>SCI_STUTTEREDPAGEDOWNEXTEND</code></td> </tr> <tr> <td><code>SCI_DELETEBACK</code></td> <td><code>SCI_DELETEBACKNOTLINE</code></td> </tr> <tr> <td><code>SCI_DELWORDLEFT</code></td> <td><code>SCI_DELWORDRIGHT</code></td> <td><code>SCI_DELWORDRIGHTEND</code></td> </tr> <tr> <td><code>SCI_DELLINELEFT</code></td> <td><code>SCI_DELLINERIGHT</code></td> <td><code>SCI_LINEDELETE</code></td> </tr> <tr> <td><code>SCI_LINECUT</code></td> <td><code>SCI_LINECOPY</code></td> <td><code>SCI_LINETRANSPOSE</code></td> <td><code>SCI_LINEDUPLICATE</code></td> </tr> <tr> <td><code>SCI_LOWERCASE</code></td> <td><code>SCI_UPPERCASE</code></td> <td><code>SCI_CANCEL</code></td> <td><code>SCI_EDITTOGGLEOVERTYPE</code></td> </tr> <tr> <td><code>SCI_NEWLINE</code></td> <td><code>SCI_FORMFEED</code></td> <td><code>SCI_TAB</code></td> <td><code>SCI_BACKTAB</code></td> </tr> <tr> <td><code>SCI_SELECTIONDUPLICATE</code></td> <td><code>SCI_VERTICALCENTRECARET</code></td> </tr> <tr> <td><code>SCI_MOVESELECTEDLINESUP</code></td> <td><code>SCI_MOVESELECTEDLINESDOWN</code></td> </tr> <tr> <td><code>SCI_SCROLLTOSTART</code></td> <td><code>SCI_SCROLLTOEND</code></td> </tr> </tbody> </table> <p>The <code>SCI_*EXTEND</code> messages extend the selection.</p> <p>The <code>SCI_*RECTEXTEND</code> messages extend the rectangular selection (and convert regular selection to rectangular one, if any).</p> <p>The <code>SCI_WORDPART*</code> commands are used to move between word segments marked by capitalisation (aCamelCaseIdentifier) or underscores (an_under_bar_ident).</p> <p>The <code>SCI_HOME*</code> commands move the caret to the start of the line, while the <code>SCI_VCHOME*</code> commands move the caret to the first non-blank character of the line (ie. just after the indentation) unless it is already there; in this case, it acts as SCI_HOME*.</p> <p>The <code>SCI_[HOME|LINEEND]DISPLAY*</code> commands are used when in line wrap mode to allow movement to the start or end of display lines as opposed to the normal <code>SCI_[HOME|LINEEND]</code> commands which move to the start or end of document lines.</p> <p>The <code>SCI_[[VC]HOME|LINEEND]WRAP*</code> commands are like their namesakes <code>SCI_[[VC]HOME|LINEEND]*</code> except they behave differently when word-wrap is enabled: They go first to the start / end of the display line, like <code>SCI_[HOME|LINEEND]DISPLAY*</code>, but if the cursor is already at the point, it goes on to the start or end of the document line, as appropriate for <code>SCI_[[VC]HOME|LINEEND]*</code>. </p> <p>The <code>SCI_SCROLLTO[START|END]</code> commands scroll the document to the start or end without changing the selection. These commands match OS X platform conventions for the behaviour of the <code>home</code> and <code>end</code> keys. Scintilla can be made to match OS X applications by binding the <code>home</code> and <code>end</code> keys to these commands. </p> <h2 id="KeyBindings">Key bindings</h2> <p>There is a default binding of keys to commands that is defined in the Scintilla source in the file <code>KeyMap.cxx</code> by the constant <code>KeyMap::MapDefault[]</code>. This table maps key definitions to <code>SCI_*</code> messages with no parameters (mostly the <a class="jump" href="#KeyboardCommands">keyboard commands</a> discussed above, but any Scintilla command that has no arguments can be mapped). You can change the mapping to suit your own requirements.</p> <code><a class="message" href="#SCI_ASSIGNCMDKEY">SCI_ASSIGNCMDKEY(int keyDefinition, int sciCommand)</a><br /> <a class="message" href="#SCI_CLEARCMDKEY">SCI_CLEARCMDKEY(int keyDefinition)</a><br /> <a class="message" href="#SCI_CLEARALLCMDKEYS">SCI_CLEARALLCMDKEYS</a><br /> <a class="message" href="#SCI_NULL">SCI_NULL</a><br /> </code> <p><b id="keyDefinition">keyDefinition</b><br /> A key definition contains the key code in the low 16-bits and the key modifiers in the high 16-bits. To combine <code>keyCode</code> and <code>keyMod</code> set:<br /> <br /> <code>keyDefinition = keyCode + (keyMod << 16)</code></p> <p>The key code is a visible or control character or a key from the <code>SCK_*</code> enumeration, which contains:<br /> <code>SCK_ADD</code>, <code>SCK_BACK</code>, <code>SCK_DELETE</code>, <code>SCK_DIVIDE</code>, <code>SCK_DOWN</code>, <code>SCK_END</code>, <code>SCK_ESCAPE</code>, <code>SCK_HOME</code>, <code>SCK_INSERT</code>, <code>SCK_LEFT</code>, <code>SCK_MENU</code>, <code>SCK_NEXT</code> (Page Down), <code>SCK_PRIOR</code> (Page Up), <code>SCK_RETURN</code>, <code>SCK_RIGHT</code>, <code>SCK_RWIN</code>, <code>SCK_SUBTRACT</code>, <code>SCK_TAB</code>, <code>SCK_UP</code>, and <code>SCK_WIN</code>.</p> <p>The modifiers are a combination of zero or more of <code>SCMOD_ALT</code>, <code>SCMOD_CTRL</code>, <code>SCMOD_SHIFT</code>, and <code>SCMOD_META</code>. On OS X, the Command key is mapped to <code>SCMOD_CTRL</code> and the Control key to <code>SCMOD_META</code>. If you are building a table, you might want to use <code>SCMOD_NORM</code>, which has the value 0, to mean no modifiers.</p> <p><b id="SCI_ASSIGNCMDKEY">SCI_ASSIGNCMDKEY(int <a class="jump" href="#keyDefinition">keyDefinition</a>, int sciCommand)</b><br /> This assigns the given key definition to a Scintilla command identified by <code>sciCommand</code>. <code>sciCommand</code> can be any <code>SCI_*</code> command that has no arguments.</p> <p><b id="SCI_CLEARCMDKEY">SCI_CLEARCMDKEY(int <a class="jump" href="#keyDefinition">keyDefinition</a>)</b><br /> This makes the given key definition do nothing by assigning the action <code>SCI_NULL</code> to it.</p> <p><b id="SCI_CLEARALLCMDKEYS">SCI_CLEARALLCMDKEYS</b><br /> This command removes all keyboard command mapping by setting an empty mapping table.</p> <p><b id="SCI_NULL">SCI_NULL</b><br /> The <code>SCI_NULL</code> does nothing and is the value assigned to keys that perform no action. SCI_NULL ensures that keys do not propagate to the parent window as that may cause focus to move. If you want the standard platform behaviour use the constant 0 instead.</p> <h2 id="PopupEditMenu">Popup edit menu</h2> <p><b id="SCI_USEPOPUP">SCI_USEPOPUP(bool bEnablePopup)</b><br /> Clicking the wrong button on the mouse pops up a short default editing menu. This may be turned off with <code>SCI_USEPOPUP(0)</code>. If you turn it off, context menu commands (in Windows, <code>WM_CONTEXTMENU</code>) will not be handled by Scintilla, so the parent of the Scintilla window will have the opportunity to handle the message.</p> <h2 id="MacroRecording">Macro recording</h2> <p>Start and stop macro recording mode. In macro recording mode, actions are reported to the container through <code><a class="message" href="#SCN_MACRORECORD">SCN_MACRORECORD</a></code> <a class="jump" href="#Notifications">notifications</a>. It is then up to the container to record these actions for future replay.</p> <p><b id="SCI_STARTRECORD">SCI_STARTRECORD</b><br /> <b id="SCI_STOPRECORD">SCI_STOPRECORD</b><br /> These two messages turn macro recording on and off.</p> <h2 id="Printing">Printing</h2> <p><code>SCI_FORMATRANGE</code> can be used to draw the text onto a display surface which can include a printer display surface. Printed output shows text styling as on the screen, but it hides all margins except a line number margin. All special marker effects are removed and the selection and caret are hidden.</p> <p>Different platforms use different display surface ID types to print on. On Windows, these are <code>HDC</code>s., on GTK+ 3.x <code>cairo_t *</code>, and on Cocoa <code>CGContextRef</code> is used.</p> <code><a class="message" href="#SCI_FORMATRANGE">SCI_FORMATRANGE(bool bDraw, Sci_RangeToFormat *pfr)</a><br /> <a class="message" href="#SCI_SETPRINTMAGNIFICATION">SCI_SETPRINTMAGNIFICATION(int magnification)</a><br /> <a class="message" href="#SCI_GETPRINTMAGNIFICATION">SCI_GETPRINTMAGNIFICATION</a><br /> <a class="message" href="#SCI_SETPRINTCOLOURMODE">SCI_SETPRINTCOLOURMODE(int mode)</a><br /> <a class="message" href="#SCI_GETPRINTCOLOURMODE">SCI_GETPRINTCOLOURMODE</a><br /> <a class="message" href="#SCI_SETPRINTWRAPMODE">SCI_SETPRINTWRAPMODE</a><br /> <a class="message" href="#SCI_GETPRINTWRAPMODE">SCI_GETPRINTWRAPMODE</a><br /> </code> <p><b id="SCI_FORMATRANGE">SCI_FORMATRANGE(bool bDraw, Sci_RangeToFormat *pfr)</b><br /> This call renders a range of text into a device context. If you use this for printing, you will probably want to arrange a page header and footer; Scintilla does not do this for you. See <code>SciTEWin::Print()</code> in <code>SciTEWinDlg.cxx</code> for an example. Each use of this message renders a range of text into a rectangular area and returns the position in the document of the next character to print.</p> <p><code>bDraw</code> controls if any output is done. Set this to false if you are paginating (for example, if you use this with MFC you will need to paginate in <code>OnBeginPrinting()</code> before you output each page.</p> <pre> struct Sci_Rectangle { int left; int top; int right; int bottom; }; struct Sci_RangeToFormat { Sci_SurfaceID hdc; // The Surface ID we print to Sci_SurfaceID hdcTarget; // The Surface ID we use for measuring (may be same as hdc) Sci_Rectangle rc; // Rectangle in which to print Sci_Rectangle rcPage; // Physically printable page size Sci_CharacterRange chrg; // Range of characters to print }; </pre> <p>On Windows, <code>hdc</code> and <code>hdcTarget</code> should both be set to the device context handle of the output device (usually a printer). If you print to a metafile these will not be the same as Windows metafiles (unlike extended metafiles) do not implement the full API for returning information. In this case, set <code>hdcTarget</code> to the screen DC.<br /> <code>rcPage</code> is the rectangle <code>{0, 0, maxX, maxY}</code> where <code>maxX+1</code> and <code>maxY+1</code> are the number of physically printable pixels in x and y.<br /> <code>rc</code> is the rectangle to render the text in (which will, of course, fit within the rectangle defined by rcPage).<br /> <code>chrg.cpMin</code> and <code>chrg.cpMax</code> define the start position and maximum position of characters to output. All of each line within this character range is drawn.</p> <p>On Cocoa, the surface IDs for printing (<code>bDraw=1</code>) should be the graphics port of the current context (<code>(CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]</code>) when the view's drawRect method is called. The Surface IDs are not really used for measurement (<code>bDraw=0</code>) but can be set to a bitmap context (created with <code>CGBitmapContextCreate</code>) to avoid runtime warnings.</p> <p>On GTK+, the surface IDs to use can be found from the printing context with <code>gtk_print_context_get_cairo_context(context)</code>.</p> <code>chrg.cpMin</code> and <code>chrg.cpMax</code> define the start position and maximum position of characters to output. All of each line within this character range is drawn.</p> <p>When printing, the most tedious part is always working out what the margins should be to allow for the non-printable area of the paper and printing a header and footer. If you look at the printing code in SciTE, you will find that most of it is taken up with this. The loop that causes Scintilla to render text is quite simple if you strip out all the margin, non-printable area, header and footer code.</p> <p><b id="SCI_SETPRINTMAGNIFICATION">SCI_SETPRINTMAGNIFICATION(int magnification)</b><br /> <b id="SCI_GETPRINTMAGNIFICATION">SCI_GETPRINTMAGNIFICATION</b><br /> <code>SCI_GETPRINTMAGNIFICATION</code> lets you to print at a different size than the screen font. <code>magnification</code> is the number of points to add to the size of each screen font. A value of -3 or -4 gives reasonably small print. You can get this value with <code>SCI_GETPRINTMAGNIFICATION</code>.</p> <p><b id="SCI_SETPRINTCOLOURMODE">SCI_SETPRINTCOLOURMODE(int mode)</b><br /> <b id="SCI_GETPRINTCOLOURMODE">SCI_GETPRINTCOLOURMODE</b><br /> These two messages set and get the method used to render coloured text on a printer that is probably using white paper. It is especially important to consider the treatment of colour if you use a dark or black screen background. Printing white on black uses up toner and ink very many times faster than the other way around. You can set the mode to one of:</p> <table cellpadding="1" cellspacing="2" border="0" summary="Colour printing modes"> <tbody> <tr> <th align="left">Symbol</th> <th>Value</th> <th align="left">Purpose</th> </tr> </tbody> <tbody valign="top"> <tr> <td align="left"><code>SC_PRINT_NORMAL</code></td> <td align="center">0</td> <td>Print using the current screen colours. This is the default.</td> </tr> <tr> <td align="left"><code>SC_PRINT_INVERTLIGHT</code></td> <td align="center">1</td> <td>If you use a dark screen background this saves ink by inverting the light value of all colours and printing on a white background.</td> </tr> <tr> <td align="left"><code>SC_PRINT_BLACKONWHITE</code></td> <td align="center">2</td> <td>Print all text as black on a white background.</td> </tr> <tr> <td align="left"><code>SC_PRINT_COLOURONWHITE</code></td> <td align="center">3</td> <td>Everything prints in its own colour on a white background.</td> </tr> <tr> <td align="left"><code>SC_PRINT_COLOURONWHITEDEFAULTBG</code></td> <td align="center">4</td> <td>Everything prints in its own colour on a white background except that line numbers use their own background colour.</td> </tr> </tbody> </table> <p><b id="SCI_SETPRINTWRAPMODE">SCI_SETPRINTWRAPMODE(int wrapMode)</b><br /> <b id="SCI_GETPRINTWRAPMODE">SCI_GETPRINTWRAPMODE</b><br /> These two functions get and set the printer wrap mode. <code>wrapMode</code> can be set to <code>SC_WRAP_NONE</code> (0), <code>SC_WRAP_WORD</code> (1) or <code>SC_WRAP_CHAR</code> (2). The default is <code>SC_WRAP_WORD</code>, which wraps printed output so that all characters fit into the print rectangle. If you set <code>SC_WRAP_NONE</code>, each line of text generates one line of output and the line is truncated if it is too long to fit into the print area.<br /> <code>SC_WRAP_WORD</code> tries to wrap only between words as indicated by white space or style changes although if a word is longer than a line, it will be wrapped before the line end. <code>SC_WRAP_CHAR</code> is preferred to <code>SC_WRAP_WORD</code> for Asian languages where there is no white space between words.</p> <h2 id="DirectAccess">Direct access</h2> <code><a class="message" href="#SCI_GETDIRECTFUNCTION">SCI_GETDIRECTFUNCTION</a><br /> <a class="message" href="#SCI_GETDIRECTPOINTER">SCI_GETDIRECTPOINTER</a><br /> <a class="message" href="#SCI_GETCHARACTERPOINTER">SCI_GETCHARACTERPOINTER</a><br /> <a class="message" href="#SCI_GETRANGEPOINTER">SCI_GETRANGEPOINTER(int position, int rangeLength)</a><br /> <a class="message" href="#SCI_GETGAPPOSITION">SCI_GETGAPPOSITION</a><br /> </code> <p>On Windows, the message-passing scheme used to communicate between the container and Scintilla is mediated by the operating system <code>SendMessage</code> function and can lead to bad performance when calling intensively. To avoid this overhead, Scintilla provides messages that allow you to call the Scintilla message function directly. The code to do this in C/C++ is of the form:</p> <pre> #include "Scintilla.h" SciFnDirect pSciMsg = (SciFnDirect)SendMessage(hSciWnd, SCI_GETDIRECTFUNCTION, 0, 0); sptr_t pSciWndData = (sptr_t)SendMessage(hSciWnd, SCI_GETDIRECTPOINTER, 0, 0); // now a wrapper to call Scintilla directly sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){ return pSciMsg(pSciWndData, iMessage, wParam, lParam); } </pre> <p><code>SciFnDirect</code>, <code>sptr_t</code> and <code>uptr_t</code> are declared in <code>Scintilla.h</code>. <code>hSciWnd</code> is the window handle returned when you created the Scintilla window.</p> <p>While faster, this direct calling will cause problems if performed from a different thread to the native thread of the Scintilla window in which case <code>SendMessage(hSciWnd, SCI_*, wParam, lParam)</code> should be used to synchronize with the window's thread.</p> <p>This feature also works on GTK+ but has no significant impact on speed.</p> <p>From version 1.47 on Windows, Scintilla exports a function called <code>Scintilla_DirectFunction</code> that can be used the same as the function returned by <code>SCI_GETDIRECTFUNCTION</code>. This saves you the call to <code>SCI_GETDIRECTFUNCTION</code> and the need to call Scintilla indirectly via the function pointer.</p> <p><b id="SCI_GETDIRECTFUNCTION">SCI_GETDIRECTFUNCTION</b><br /> This message returns the address of the function to call to handle Scintilla messages without the overhead of passing through the Windows messaging system. You need only call this once, regardless of the number of Scintilla windows you create.</p> <p><b id="SCI_GETDIRECTPOINTER">SCI_GETDIRECTPOINTER</b><br /> This returns a pointer to data that identifies which Scintilla window is in use. You must call this once for each Scintilla window you create. When you call the direct function, you must pass in the direct pointer associated with the target window.</p> <p><b id="SCI_GETCHARACTERPOINTER">SCI_GETCHARACTERPOINTER</b><br /> <b id="SCI_GETRANGEPOINTER">SCI_GETRANGEPOINTER(int position, int rangeLength)</b><br /> <b id="SCI_GETGAPPOSITION">SCI_GETGAPPOSITION</b><br /> Grant temporary direct read-only access to the memory used by Scintilla to store the document.</p> <p><code>SCI_GETCHARACTERPOINTER</code> moves the gap within Scintilla so that the text of the document is stored consecutively and ensure there is a NUL character after the text, then returns a pointer to the first character. Applications may then pass this to a function that accepts a character pointer such as a regular expression search or a parser. The pointer should <em>not</em> be written to as that may desynchronize the internal state of Scintilla.</p> <p>Since any action in Scintilla may change its internal state this pointer becomes invalid after any call or by allowing user interface activity. The application should reacquire the pointer after making any call to Scintilla or performing any user-interface calls such as modifying a progress indicator.</p> <p>This call takes similar time to inserting a character at the end of the document and this may include moving the document contents. Specifically, all the characters after the document gap are moved to before the gap. This compacted state should persist over calls and user interface actions that do not change the document contents so reacquiring the pointer afterwards is very quick. If this call is used to implement a global replace operation, then each replacement will move the gap so if <code>SCI_GETCHARACTERPOINTER</code> is called after each replacement then the operation will become O(n^2) rather than O(n). Instead, all matches should be found and remembered, then all the replacements performed.</p> <p><code>SCI_GETRANGEPOINTER</code> provides direct access to just the range requested. The gap is not moved unless it is within the requested range so this call can be faster than <code>SCI_GETCHARACTERPOINTER</code>. This can be used by application code that is able to act on blocks of text or ranges of lines.</p> <p><code>SCI_GETGAPPOSITION</code> returns the current gap position. This is a hint that applications can use to avoid calling <code>SCI_GETRANGEPOINTER</code> with a range that contains the gap and consequent costs of moving the gap.</p> <h2 id="MultipleViews">Multiple views</h2> <p>A Scintilla window and the document that it displays are separate entities. When you create a new window, you also create a new, empty document. Each document has a reference count that is initially set to 1. The document also has a list of the Scintilla windows that are linked to it so when any window changes the document, all other windows in which it appears are notified to cause them to update. The system is arranged in this way so that you can work with many documents in a single Scintilla window and so you can display a single document in multiple windows (for use with splitter windows).</p> <p>Although these messages use <code>document *pDoc</code>, to ensure compatibility with future releases of Scintilla you should treat <code>pDoc</code> as an opaque <code>void*</code>. That is, you can use and store the pointer as described in this section but you should not dereference it.</p> <code><a class="message" href="#SCI_GETDOCPOINTER">SCI_GETDOCPOINTER</a><br /> <a class="message" href="#SCI_SETDOCPOINTER">SCI_SETDOCPOINTER(<unused>, document *pDoc)</a><br /> <a class="message" href="#SCI_CREATEDOCUMENT">SCI_CREATEDOCUMENT</a><br /> <a class="message" href="#SCI_ADDREFDOCUMENT">SCI_ADDREFDOCUMENT(<unused>, document *pDoc)</a><br /> <a class="message" href="#SCI_RELEASEDOCUMENT">SCI_RELEASEDOCUMENT(<unused>, document *pDoc)</a><br /> </code> <p><b id="SCI_GETDOCPOINTER">SCI_GETDOCPOINTER</b><br /> This returns a pointer to the document currently in use by the window. It has no other effect.</p> <p><b id="SCI_SETDOCPOINTER">SCI_SETDOCPOINTER(<unused>, document *pDoc)</b><br /> This message does the following:<br /> 1. It removes the current window from the list held by the current document.<br /> 2. It reduces the reference count of the current document by 1.<br /> 3. If the reference count reaches 0, the document is deleted.<br /> 4. <code>pDoc</code> is set as the new document for the window.<br /> 5. If <code>pDoc</code> was 0, a new, empty document is created and attached to the window.<br /> 6. If <code>pDoc</code> was not 0, its reference count is increased by 1.</p> <p><b id="SCI_CREATEDOCUMENT">SCI_CREATEDOCUMENT</b><br /> This message creates a new, empty document and returns a pointer to it. This document is not selected into the editor and starts with a reference count of 1. This means that you have ownership of it and must either reduce its reference count by 1 after using <code>SCI_SETDOCPOINTER</code> so that the Scintilla window owns it or you must make sure that you reduce the reference count by 1 with <code>SCI_RELEASEDOCUMENT</code> before you close the application to avoid memory leaks.</p> <p><b id="SCI_ADDREFDOCUMENT">SCI_ADDREFDOCUMENT(<unused>, document *pDoc)</b><br /> This increases the reference count of a document by 1. If you want to replace the current document in the Scintilla window and take ownership of the current document, for example if you are editing many documents in one window, do the following:<br /> 1. Use <code>SCI_GETDOCPOINTER</code> to get a pointer to the document, <code>pDoc</code>.<br /> 2. Use <code>SCI_ADDREFDOCUMENT(0, pDoc)</code> to increment the reference count.<br /> 3. Use <code>SCI_SETDOCPOINTER(0, pNewDoc)</code> to set a different document or <code>SCI_SETDOCPOINTER(0, 0)</code> to set a new, empty document.</p> <p><b id="SCI_RELEASEDOCUMENT">SCI_RELEASEDOCUMENT(<unused>, document *pDoc)</b><br /> This message reduces the reference count of the document identified by <code>pDoc</code>. pDoc must be the result of <code>SCI_GETDOCPOINTER</code> or <code>SCI_CREATEDOCUMENT</code> and must point at a document that still exists. If you call this on a document with a reference count of 1 that is still attached to a Scintilla window, bad things will happen. To keep the world spinning in its orbit you must balance each call to <code>SCI_CREATEDOCUMENT</code> or <code>SCI_ADDREFDOCUMENT</code> with a call to <code>SCI_RELEASEDOCUMENT</code>.</p> <h2 id="BackgroundLoadSave">Background loading and saving</h2> <p>To ensure a responsive user interface, applications may decide to load and save documents using a separate thread from the user interface.</p> <h3 id="BackgroundLoad">Loading in the background</h2> <p>An application can load all of a file into a buffer it allocates on a background thread and then add the data in that buffer into a Scintilla document on the user interface thread. That technique uses extra memory to store a complete copy of the file and also means that the time that Scintilla takes to perform initial line end discovery blocks the user interface.</p> <p>To avoid these issues, a loader object may be created and used to load the file. The loader object supports the ILoader interface.</p> <p><b id="SCI_CREATELOADER">SCI_CREATELOADER(int bytes)</b><br /> Create an object that supports the <code>ILoader</code> interface which can be used to load data and then be turned into a Scintilla document object for attachment to a view object. The <code>bytes</code> argument determines the initial memory allocation for the document as it is more efficient to allocate once rather than rely on the buffer growing as data is added. If <code>SCI_CREATELOADER</code> fails then 0 is returned.</p> <h4>ILoader</h4> <div class="highlighted"> <span class="S5">class</span><span class="S0"> </span>ILoader<span class="S0"> </span><span class="S10">{</span><br /> <span class="S5">public</span><span class="S10">:</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD<span class="S0"> </span>Release<span class="S10">()</span><span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S2">// Returns a status code from SC_STATUS_*</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD<span class="S0"> </span>AddData<span class="S10">(</span><span class="S5">char</span><span class="S0"> </span><span class="S10">*</span>data<span class="S10">,</span><span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>length<span class="S10">)</span><span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span><span class="S5">void</span><span class="S0"> </span><span class="S10">*</span><span class="S0"> </span>SCI_METHOD<span class="S0"> </span>ConvertToDocument<span class="S10">()</span><span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S10">};</span><br /> </div> <p>The application should call the <code>AddData</code> method with each block of data read from the file. <code>AddData</code> will return SC_STATUS_OK unless a failure, such as memory exhaustion occurs. If a failure occurs in <code>AddData</code> or in a file reading call then loading can be abandoned and the loader released with the <code>Release</code> call. When the whole file has been read, the <code>ConvertToDocument</code> method should be called to produce a Scintilla document pointer which can be used in the same way as a document pointer returned from <a class="message" href="#SCI_CREATEDOCUMENT">SCI_CREATEDOCUMENT</a>. There is no need to call <code>Release</code> after <code>ConvertToDocument</code>.</p> <h3 id="BackgroundSave">Saving in the background</h2> <p>An application that wants to save in the background should lock the document with <code>SCI_SETREADONLY(1)</code> to prevent modifications and retrieve a pointer to the unified document contents with <a class="message" href="#SCI_GETCHARACTERPOINTER">SCI_GETCHARACTERPOINTER</a></code>. The buffer of a locked document will not move so the pointer is valid until the application calls <code>SCI_SETREADONLY(0)</code>.</p> <p>If the user tries to performs a modification while the document is locked then a <code><a class="message" href="#SCN_MODIFYATTEMPTRO">SCN_MODIFYATTEMPTRO</a></code> notification is sent to the application. The application may then decide to ignore the modification or to terminate the background saving thread and reenable modification before returning from the notification.</p> <h2 id="Folding">Folding</h2> <p>The fundamental operation in folding is making lines invisible or visible. Line visibility is a property of the view rather than the document so each view may be displaying a different set of lines. From the point of view of the user, lines are hidden and displayed using fold points. Generally, the fold points of a document are based on the hierarchical structure of the document contents. In Python, the hierarchy is determined by indentation and in C++ by brace characters. This hierarchy can be represented within a Scintilla document object by attaching a numeric "fold level" to each line. The fold level is most easily set by a lexer, but you can also set it with messages.</p> <p>It is up to your code to set the connection between user actions and folding and unfolding. The best way to see how this is done is to search the SciTE source code for the messages used in this section of the documentation and see how they are used. You will also need to use markers and a folding margin to complete your folding implementation. The <code>"fold"</code> property should be set to <code>"1"</code> with <code>SCI_SETPROPERTY("fold", "1")</code> to enable folding. </p> <code><a class="message" href="#SCI_VISIBLEFROMDOCLINE">SCI_VISIBLEFROMDOCLINE(int docLine)</a><br /> <a class="message" href="#SCI_DOCLINEFROMVISIBLE">SCI_DOCLINEFROMVISIBLE(int displayLine)</a><br /> <a class="message" href="#SCI_SHOWLINES">SCI_SHOWLINES(int lineStart, int lineEnd)</a><br /> <a class="message" href="#SCI_HIDELINES">SCI_HIDELINES(int lineStart, int lineEnd)</a><br /> <a class="message" href="#SCI_GETLINEVISIBLE">SCI_GETLINEVISIBLE(int line)</a><br /> <a class="message" href="#SCI_GETALLLINESVISIBLE">SCI_GETALLLINESVISIBLE</a><br /> <a class="message" href="#SCI_SETFOLDLEVEL">SCI_SETFOLDLEVEL(int line, int level)</a><br /> <a class="message" href="#SCI_GETFOLDLEVEL">SCI_GETFOLDLEVEL(int line)</a><br /> <a class="message" href="#SCI_SETFOLDFLAGS">SCI_SETFOLDFLAGS(int flags)</a><br /> <a class="message" href="#SCI_GETLASTCHILD">SCI_GETLASTCHILD(int line, int level)</a><br /> <a class="message" href="#SCI_GETFOLDPARENT">SCI_GETFOLDPARENT(int line)</a><br /> <a class="message" href="#SCI_SETFOLDEXPANDED">SCI_SETFOLDEXPANDED(int line, bool expanded)</a><br /> <a class="message" href="#SCI_GETFOLDEXPANDED">SCI_GETFOLDEXPANDED(int line)</a><br /> <a class="message" href="#SCI_CONTRACTEDFOLDNEXT">SCI_CONTRACTEDFOLDNEXT(int lineStart)</a><br /> <a class="message" href="#SCI_TOGGLEFOLD">SCI_TOGGLEFOLD(int line)</a><br /> <a class="message" href="#SCI_ENSUREVISIBLE">SCI_ENSUREVISIBLE(int line)</a><br /> <a class="message" href="#SCI_ENSUREVISIBLEENFORCEPOLICY">SCI_ENSUREVISIBLEENFORCEPOLICY(int line)</a><br /> </code> <p><b id="SCI_VISIBLEFROMDOCLINE">SCI_VISIBLEFROMDOCLINE(int docLine)</b><br /> When some lines are hidden and/or annotations are displayed, then a particular line in the document may be displayed at a different position to its document position. If no lines are hidden and there are no annotations, this message returns <code>docLine</code>. Otherwise, this returns the display line (counting the very first visible line as 0). The display line of an invisible line is the same as the previous visible line. The display line number of the first line in the document is 0. If lines are hidden and <code>docLine</code> is outside the range of lines in the document, the return value is -1. Lines can occupy more than one display line if they wrap.</p> <p><b id="SCI_DOCLINEFROMVISIBLE">SCI_DOCLINEFROMVISIBLE(int displayLine)</b><br /> When some lines are hidden and/or annotations are displayed, then a particular line in the document may be displayed at a different position to its document position. This message returns the document line number that corresponds to a display line (counting the display line of the first line in the document as 0). If <code>displayLine</code> is less than or equal to 0, the result is 0. If <code>displayLine</code> is greater than or equal to the number of displayed lines, the result is the number of lines in the document.</p> <p><b id="SCI_SHOWLINES">SCI_SHOWLINES(int lineStart, int lineEnd)</b><br /> <b id="SCI_HIDELINES">SCI_HIDELINES(int lineStart, int lineEnd)</b><br /> <b id="SCI_GETLINEVISIBLE">SCI_GETLINEVISIBLE(int line)</b><br /> <b id="SCI_GETALLLINESVISIBLE">SCI_GETALLLINESVISIBLE</b><br /> The first two messages mark a range of lines as visible or invisible and then redraw the display. <code>SCI_GETLINEVISIBLE</code> reports on the visible state of a line and returns 1 if it is visible and 0 if it is not visible. <code>SCI_GETALLLINESVISIBLE</code> returns 1 if all lines are visible and 0 if some lines are hidden. These messages have no effect on fold levels or fold flags. The first line can not be hidden.</p> <p><b id="SCI_SETFOLDLEVEL">SCI_SETFOLDLEVEL(int line, int level)</b><br /> <b id="SCI_GETFOLDLEVEL">SCI_GETFOLDLEVEL(int line)</b><br /> These two messages set and get a 32-bit value that contains the fold level of a line and some flags associated with folding. The fold level is a number in the range 0 to <code>SC_FOLDLEVELNUMBERMASK</code> (4095). However, the initial fold level is set to <code>SC_FOLDLEVELBASE</code> (1024) to allow unsigned arithmetic on folding levels. There are two addition flag bits. <code>SC_FOLDLEVELWHITEFLAG</code> indicates that the line is blank and allows it to be treated slightly different then its level may indicate. For example, blank lines should generally not be fold points and will be considered part of the preceding section even though they may have a lesser fold level. <code>SC_FOLDLEVELHEADERFLAG</code> indicates that the line is a header (fold point).</p> <p>Use <code>SCI_GETFOLDLEVEL(line) & SC_FOLDLEVELNUMBERMASK</code> to get the fold level of a line. Likewise, use <code>SCI_GETFOLDLEVEL(line) & SC_FOLDLEVEL*FLAG</code> to get the state of the flags. To set the fold level you must or in the associated flags. For instance, to set the level to <code>thisLevel</code> and mark a line as being a fold point use: <code>SCI_SETFOLDLEVEL(line, thisLevel | SC_FOLDLEVELHEADERFLAG)</code>.</p> If you use a lexer, you should not need to use <code>SCI_SETFOLDLEVEL</code> as this is far better handled by the lexer. You will need to use <code>SCI_GETFOLDLEVEL</code> to decide how to handle user folding requests. If you do change the fold levels, the folding margin will update to match your changes. <p><b id="SCI_SETFOLDFLAGS">SCI_SETFOLDFLAGS(int flags)</b><br /> In addition to showing markers in the folding margin, you can indicate folds to the user by drawing lines in the text area. The lines are drawn in the foreground colour set for <a class="message" href="#StyleDefinition"><code>STYLE_DEFAULT</code></a>. Bits set in <code>flags</code> determine where folding lines are drawn:<br /> </p> <table cellpadding="1" cellspacing="2" border="0" summary="Fold flags"> <tbody> <tr> <th align="left">Symbol</th> <th align="left">Value</th> <th align="left">Effect</th> </tr> </tbody> <tbody valign="top"> <tr> <td align="left"></td> <td align="left">1</td> <td align="left">Experimental feature that has been removed.</td> </tr> <tr> <td align="left">SC_FOLDFLAG_LINEBEFORE_EXPANDED</td> <td align="left">2</td> <td align="left">Draw above if expanded</td> </tr> <tr> <td align="left">SC_FOLDFLAG_LINEBEFORE_CONTRACTED</td> <td align="left">4</td> <td align="left">Draw above if not expanded</td> </tr> <tr> <td align="left">SC_FOLDFLAG_LINEAFTER_EXPANDED</td> <td align="left">8</td> <td align="left">Draw below if expanded</td> </tr> <tr> <td align="left">SC_FOLDFLAG_LINEAFTER_CONTRACTED</td> <td align="left">16</td> <td align="left">Draw below if not expanded</td> </tr> <tr> <td align="left">SC_FOLDFLAG_LEVELNUMBERS</td> <td align="left">64</td> <td align="left">display hexadecimal fold levels in line margin to aid debugging of folding. The appearance of this feature may change in the future.</td> </tr> </tbody> </table> <p>This message causes the display to redraw.</p> <p><b id="SCI_GETLASTCHILD">SCI_GETLASTCHILD(int startLine, int level)</b><br /> This message searches for the next line after <code>startLine</code>, that has a folding level that is less than or equal to <code>level</code> and then returns the previous line number. If you set <code>level</code> to -1, <code>level</code> is set to the folding level of line <code>startLine</code>. If <code>from</code> is a fold point, <code>SCI_GETLASTCHILD(from, -1)</code> returns the last line that would be in made visible or hidden by toggling the fold state.</p> <p><b id="SCI_GETFOLDPARENT">SCI_GETFOLDPARENT(int startLine)</b><br /> This message returns the line number of the first line before <code>startLine</code> that is marked as a fold point with <code>SC_FOLDLEVELHEADERFLAG</code> and has a fold level less than the <code>startLine</code>. If no line is found, or if the header flags and fold levels are inconsistent, the return value is -1.</p> <p><b id="SCI_TOGGLEFOLD">SCI_TOGGLEFOLD(int line)</b><br /> Each fold point may be either expanded, displaying all its child lines, or contracted, hiding all the child lines. This message toggles the folding state of the given line as long as it has the <code>SC_FOLDLEVELHEADERFLAG</code> set. This message takes care of folding or expanding all the lines that depend on the line. The display updates after this message.</p> <p><b id="SCI_SETFOLDEXPANDED">SCI_SETFOLDEXPANDED(int line, bool expanded)</b><br /> <b id="SCI_GETFOLDEXPANDED">SCI_GETFOLDEXPANDED(int line)</b><br /> These messages set and get the expanded state of a single line. The set message has no effect on the visible state of the line or any lines that depend on it. It does change the markers in the folding margin. If you ask for the expansion state of a line that is outside the document, the result is <code>false</code> (0).</p> <p>If you just want to toggle the fold state of one line and handle all the lines that are dependent on it, it is much easier to use <code>SCI_TOGGLEFOLD</code>. You would use the <code>SCI_SETFOLDEXPANDED</code> message to process many folds without updating the display until you had finished. See <code>SciTEBase::FoldAll()</code> and <code>SciTEBase::Expand()</code> for examples of the use of these messages.</p> <p><b id="SCI_CONTRACTEDFOLDNEXT">SCI_CONTRACTEDFOLDNEXT(int lineStart)</b><br /> Search efficiently for lines that are contracted fold headers. This is useful when saving the user's folding when switching documents or saving folding with a file. The search starts at line number <code>lineStart</code> and continues forwards to the end of the file. <code>lineStart</code> is returned if it is a contracted fold header otherwise the next contracted fold header is returned. If there are no more contracted fold headers then -1 is returned.</p> <p><b id="SCI_ENSUREVISIBLE">SCI_ENSUREVISIBLE(int line)</b><br /> <b id="SCI_ENSUREVISIBLEENFORCEPOLICY">SCI_ENSUREVISIBLEENFORCEPOLICY(int line)</b><br /> A line may be hidden because more than one of its parent lines is contracted. Both these message travels up the fold hierarchy, expanding any contracted folds until they reach the top level. The line will then be visible. If you use <code>SCI_ENSUREVISIBLEENFORCEPOLICY</code>, the vertical caret policy set by <a class="message" href="#SCI_SETVISIBLEPOLICY"><code>SCI_SETVISIBLEPOLICY</code></a> is then applied.</p> <h2 id="LineWrapping">Line wrapping</h2> <code><a class="message" href="#SCI_SETWRAPMODE">SCI_SETWRAPMODE(int wrapMode)</a><br /> <a class="message" href="#SCI_GETWRAPMODE">SCI_GETWRAPMODE</a><br /> <a class="message" href="#SCI_SETWRAPVISUALFLAGS">SCI_SETWRAPVISUALFLAGS(int wrapVisualFlags)</a><br /> <a class="message" href="#SCI_GETWRAPVISUALFLAGS">SCI_GETWRAPVISUALFLAGS</a><br /> <a class="message" href="#SCI_SETWRAPVISUALFLAGSLOCATION">SCI_SETWRAPVISUALFLAGSLOCATION(int wrapVisualFlagsLocation)</a><br /> <a class="message" href="#SCI_GETWRAPVISUALFLAGSLOCATION">SCI_GETWRAPVISUALFLAGSLOCATION</a><br /> <a class="message" href="#SCI_SETWRAPINDENTMODE">SCI_SETWRAPINDENTMODE(int indentMode)</a><br /> <a class="message" href="#SCI_GETWRAPINDENTMODE">SCI_GETWRAPINDENTMODE</a><br /> <a class="message" href="#SCI_SETWRAPSTARTINDENT">SCI_SETWRAPSTARTINDENT(int indent)</a><br /> <a class="message" href="#SCI_GETWRAPSTARTINDENT">SCI_GETWRAPSTARTINDENT</a><br /> <a class="message" href="#SCI_SETLAYOUTCACHE">SCI_SETLAYOUTCACHE(int cacheMode)</a><br /> <a class="message" href="#SCI_GETLAYOUTCACHE">SCI_GETLAYOUTCACHE</a><br /> <a class="message" href="#SCI_SETPOSITIONCACHE">SCI_SETPOSITIONCACHE(int size)</a><br /> <a class="message" href="#SCI_GETPOSITIONCACHE">SCI_GETPOSITIONCACHE</a><br /> <a class="message" href="#SCI_LINESSPLIT">SCI_LINESSPLIT(int pixelWidth)</a><br /> <a class="message" href="#SCI_LINESJOIN">SCI_LINESJOIN</a><br /> <a class="message" href="#SCI_WRAPCOUNT">SCI_WRAPCOUNT(int docLine)</a><br /> </code> <p>By default, Scintilla does not wrap lines of text. If you enable line wrapping, lines wider than the window width are continued on the following lines. Lines are broken after space or tab characters or between runs of different styles. If this is not possible because a word in one style is wider than the window then the break occurs after the last character that completely fits on the line. The horizontal scroll bar does not appear when wrap mode is on.</p> <p>For wrapped lines Scintilla can draw visual flags (little arrows) at end of a a subline of a wrapped line and at begin of the next subline. These can be enabled individually, but if Scintilla draws the visual flag at the beginning of the next subline this subline will be indented by one char. Independent from drawing a visual flag at the begin the subline can have an indention.</p> <p>Much of the time used by Scintilla is spent on laying out and drawing text. The same text layout calculations may be performed many times even when the data used in these calculations does not change. To avoid these unnecessary calculations in some circumstances, the line layout cache can store the results of the calculations. The cache is invalidated whenever the underlying data, such as the contents or styling of the document changes. Caching the layout of the whole document has the most effect, making dynamic line wrap as much as 20 times faster but this requires 7 times the memory required by the document contents plus around 80 bytes per line.</p> <p>Wrapping is not performed immediately there is a change but is delayed until the display is redrawn. This delay improves peformance by allowing a set of changes to be performed and then wrapped and displayed once. Because of this, some operations may not occur as expected. If a file is read and the scroll position moved to a particular line in the text, such as occurs when a container tries to restore a previous editing session, then the scroll position will have been determined before wrapping so an unexpected range of text will be displayed. To scroll to the position correctly, delay the scroll until the wrapping has been performed by waiting for an initial <a class="message" href="#SCN_PAINTED">SCN_PAINTED</a> notification.</p> <p><b id="SCI_SETWRAPMODE">SCI_SETWRAPMODE(int wrapMode)</b><br /> <b id="SCI_GETWRAPMODE">SCI_GETWRAPMODE</b><br /> Set wrapMode to <code>SC_WRAP_WORD</code> (1) to enable wrapping on word boundaries, <code>SC_WRAP_CHAR</code> (2) to enable wrapping between any characters, and to <code>SC_WRAP_NONE</code> (0) to disable line wrapping. <code>SC_WRAP_CHAR</code> is preferred to <code>SC_WRAP_WORD</code> for Asian languages where there is no white space between words.</p> <p><b id="SCI_SETWRAPVISUALFLAGS">SCI_SETWRAPVISUALFLAGS(int wrapVisualFlags)</b><br /> <b id="SCI_GETWRAPVISUALFLAGS">SCI_GETWRAPVISUALFLAGS</b><br /> You can enable the drawing of visual flags to indicate a line is wrapped. Bits set in wrapVisualFlags determine which visual flags are drawn. </p> <table cellpadding="1" cellspacing="2" border="0" summary="Wrap visual flags"> <tbody> <tr> <th align="left">Symbol</th> <th>Value</th> <th align="left">Effect</th> </tr> </tbody> <tbody valign="top"> <tr> <td align="left"><code>SC_WRAPVISUALFLAG_NONE</code></td> <td align="center">0</td> <td>No visual flags</td> </tr> <tr> <td align="left"><code>SC_WRAPVISUALFLAG_END</code></td> <td align="center">1</td> <td>Visual flag at end of subline of a wrapped line.</td> </tr> <tr> <td align="left"><code>SC_WRAPVISUALFLAG_START</code></td> <td align="center">2</td> <td>Visual flag at begin of subline of a wrapped line.<br /> Subline is indented by at least 1 to make room for the flag.<br /> </td> </tr> <tr> <td align="left"><code>SC_WRAPVISUALFLAG_MARGIN</code></td> <td align="center">4</td> <td>Visual flag in line number margin.</td> </tr> </tbody> </table> <p><b id="SCI_SETWRAPVISUALFLAGSLOCATION">SCI_SETWRAPVISUALFLAGSLOCATION(int wrapVisualFlagsLocation)</b><br /> <b id="SCI_GETWRAPVISUALFLAGSLOCATION">SCI_GETWRAPVISUALFLAGSLOCATION</b><br /> You can set whether the visual flags to indicate a line is wrapped are drawn near the border or near the text. Bits set in wrapVisualFlagsLocation set the location to near the text for the corresponding visual flag. </p> <table cellpadding="1" cellspacing="2" border="0" summary="Wrap visual flags locations"> <tbody> <tr> <th align="left">Symbol</th> <th>Value</th> <th align="left">Effect</th> </tr> </tbody> <tbody valign="top"> <tr> <td align="left"><code>SC_WRAPVISUALFLAGLOC_DEFAULT</code></td> <td align="center">0</td> <td>Visual flags drawn near border</td> </tr> <tr> <td align="left"><code>SC_WRAPVISUALFLAGLOC_END_BY_TEXT</code></td> <td align="center">1</td> <td>Visual flag at end of subline drawn near text</td> </tr> <tr> <td align="left"><code>SC_WRAPVISUALFLAGLOC_START_BY_TEXT</code></td> <td align="center">2</td> <td>Visual flag at beginning of subline drawn near text</td> </tr> </tbody> </table> <p><b id="SCI_SETWRAPINDENTMODE">SCI_SETWRAPINDENTMODE(int indentMode)</b><br /> <b id="SCI_GETWRAPINDENTMODE">SCI_GETWRAPINDENTMODE</b><br /> Wrapped sublines can be indented to the position of their first subline or one more indent level. The default is <code>SC_WRAPINDENT_FIXED</code>. The modes are: </p> <table cellpadding="1" cellspacing="2" border="0" summary="Wrap visual flags locations"> <tbody> <tr> <th align="left">Symbol</th> <th>Value</th> <th align="left">Effect</th> </tr> </tbody> <tbody valign="top"> <tr> <td align="left"><code>SC_WRAPINDENT_FIXED</code></td> <td align="center">0</td> <td>Wrapped sublines aligned to left of window plus amount set by <a class="message" href="#SCI_SETWRAPSTARTINDENT">SCI_SETWRAPSTARTINDENT</a></td> </tr> <tr> <td align="left"><code>SC_WRAPINDENT_SAME</code></td> <td align="center">1</td> <td>Wrapped sublines are aligned to first subline indent</td> </tr> <tr> <td align="left"><code>SC_WRAPINDENT_INDENT</code></td> <td align="center">2</td> <td>Wrapped sublines are aligned to first subline indent plus one more level of indentation</td> </tr> </tbody> </table> <p><b id="SCI_SETWRAPSTARTINDENT">SCI_SETWRAPSTARTINDENT(int indent)</b><br /> <b id="SCI_GETWRAPSTARTINDENT">SCI_GETWRAPSTARTINDENT</b><br /> <code>SCI_SETWRAPSTARTINDENT</code> sets the size of indentation of sublines for wrapped lines in terms of the average character width in <a class="message" href="#StyleDefinition"><code>STYLE_DEFAULT</code></a>. There are no limits on indent sizes, but values less than 0 or large values may have undesirable effects.<br /> The indention of sublines is independent of visual flags, but if <code>SC_WRAPVISUALFLAG_START</code> is set an indent of at least 1 is used. </p> <p><b id="SCI_SETLAYOUTCACHE">SCI_SETLAYOUTCACHE(int cacheMode)</b><br /> <b id="SCI_GETLAYOUTCACHE">SCI_GETLAYOUTCACHE</b><br /> You can set <code>cacheMode</code> to one of the symbols in the table:</p> <table cellpadding="1" cellspacing="2" border="0" summary="Line caching styles"> <tbody> <tr> <th align="left">Symbol</th> <th>Value</th> <th align="left">Layout cached for these lines</th> </tr> </tbody> <tbody valign="top"> <tr> <td align="left"><code>SC_CACHE_NONE</code></td> <td align="center">0</td> <td>No lines are cached.</td> </tr> <tr> <td align="left"><code>SC_CACHE_CARET</code></td> <td align="center">1</td> <td>The line containing the text caret. This is the default.</td> </tr> <tr> <td align="left"><code>SC_CACHE_PAGE</code></td> <td align="center">2</td> <td>Visible lines plus the line containing the caret.</td> </tr> <tr> <td align="left"><code>SC_CACHE_DOCUMENT</code></td> <td align="center">3</td> <td>All lines in the document.</td> </tr> </tbody> </table> <p><b id="SCI_SETPOSITIONCACHE">SCI_SETPOSITIONCACHE(int size)</b><br /> <b id="SCI_GETPOSITIONCACHE">SCI_GETPOSITIONCACHE</b><br /> The position cache stores position information for short runs of text so that their layout can be determined more quickly if the run recurs. The size in entries of this cache can be set with <code>SCI_SETPOSITIONCACHE</code>.</p> <p><b id="SCI_LINESSPLIT">SCI_LINESSPLIT(int pixelWidth)</b><br /> Split a range of lines indicated by the target into lines that are at most pixelWidth wide. Splitting occurs on word boundaries wherever possible in a similar manner to line wrapping. When <code>pixelWidth</code> is 0 then the width of the window is used. </p> <p><b id="SCI_LINESJOIN">SCI_LINESJOIN</b><br /> Join a range of lines indicated by the target into one line by removing line end characters. Where this would lead to no space between words, an extra space is inserted. </p> <p><b id="SCI_WRAPCOUNT">SCI_WRAPCOUNT(int docLine)</b><br /> Document lines can occupy more than one display line if they wrap and this returns the number of display lines needed to wrap a document line.</p> <h2 id="Zooming">Zooming</h2> <p>Scintilla incorporates a "zoom factor" that lets you make all the text in the document larger or smaller in steps of one point. The displayed point size never goes below 2, whatever zoom factor you set. You can set zoom factors in the range -10 to +20 points.</p> <code><a class="message" href="#SCI_ZOOMIN">SCI_ZOOMIN</a><br /> <a class="message" href="#SCI_ZOOMOUT">SCI_ZOOMOUT</a><br /> <a class="message" href="#SCI_SETZOOM">SCI_SETZOOM(int zoomInPoints)</a><br /> <a class="message" href="#SCI_GETZOOM">SCI_GETZOOM</a><br /> </code> <p><b id="SCI_ZOOMIN">SCI_ZOOMIN</b><br /> <b id="SCI_ZOOMOUT">SCI_ZOOMOUT</b><br /> <code>SCI_ZOOMIN</code> increases the zoom factor by one point if the current zoom factor is less than 20 points. <code>SCI_ZOOMOUT</code> decreases the zoom factor by one point if the current zoom factor is greater than -10 points.</p> <p><b id="SCI_SETZOOM">SCI_SETZOOM(int zoomInPoints)</b><br /> <b id="SCI_GETZOOM">SCI_GETZOOM</b><br /> These messages let you set and get the zoom factor directly. There is no limit set on the factors you can set, so limiting yourself to -10 to +20 to match the incremental zoom functions is a good idea.</p> <h2 id="LongLines">Long lines</h2> <p>You can choose to mark lines that exceed a given length by drawing a vertical line or by colouring the background of characters that exceed the set length.</p> <code><a class="message" href="#SCI_SETEDGEMODE">SCI_SETEDGEMODE(int mode)</a><br /> <a class="message" href="#SCI_GETEDGEMODE">SCI_GETEDGEMODE</a><br /> <a class="message" href="#SCI_SETEDGECOLUMN">SCI_SETEDGECOLUMN(int column)</a><br /> <a class="message" href="#SCI_GETEDGECOLUMN">SCI_GETEDGECOLUMN</a><br /> <a class="message" href="#SCI_SETEDGECOLOUR">SCI_SETEDGECOLOUR(int colour)</a><br /> <a class="message" href="#SCI_GETEDGECOLOUR">SCI_GETEDGECOLOUR</a><br /> </code> <p><b id="SCI_SETEDGEMODE">SCI_SETEDGEMODE(int edgeMode)</b><br /> <b id="SCI_GETEDGEMODE">SCI_GETEDGEMODE</b><br /> These two messages set and get the mode used to display long lines. You can set one of the values in the table:</p> <table cellpadding="1" cellspacing="2" border="0" summary="Long line styles"> <tbody> <tr> <th align="left">Symbol</th> <th>Value</th> <th align="left">Long line display mode</th> </tr> </tbody> <tbody valign="top"> <tr> <td align="left"><code>EDGE_NONE</code></td> <td align="center">0</td> <td>Long lines are not marked. This is the default state.</td> </tr> <tr> <td align="left"><code>EDGE_LINE</code></td> <td align="center">1</td> <td>A vertical line is drawn at the column number set by <code>SCI_SETEDGECOLUMN</code>. This works well for monospaced fonts. The line is drawn at a position based on the width of a space character in <a class="message" href="#StyleDefinition"><code>STYLE_DEFAULT</code></a>, so it may not work very well if your styles use proportional fonts or if your style have varied font sizes or you use a mixture of bold, italic and normal text.</td> </tr> <tr> <td align="left"><code>EDGE_BACKGROUND</code></td> <td align="center">2</td> <td>The background colour of characters after the column limit is changed to the colour set by <code>SCI_SETEDGECOLOUR</code>. This is recommended for proportional fonts.</td> </tr> </tbody> </table> <p><b id="SCI_SETEDGECOLUMN">SCI_SETEDGECOLUMN(int column)</b><br /> <b id="SCI_GETEDGECOLUMN">SCI_GETEDGECOLUMN</b><br /> These messages set and get the column number at which to display the long line marker. When drawing lines, the column sets a position in units of the width of a space character in <code>STYLE_DEFAULT</code>. When setting the background colour, the column is a character count (allowing for tabs) into the line.</p> <p><b id="SCI_SETEDGECOLOUR">SCI_SETEDGECOLOUR(int <a class="jump" href="#colour">colour</a>)</b><br /> <b id="SCI_GETEDGECOLOUR">SCI_GETEDGECOLOUR</b><br /> These messages set and get the colour of the marker used to show that a line has exceeded the length set by <code>SCI_SETEDGECOLUMN</code>.</p> <h2 id="Lexer">Lexer</h2> <p>If you define the symbol <code>SCI_LEXER</code> when building Scintilla, (this is sometimes called the SciLexer version of Scintilla), lexing support for a wide range of programming languages is included and the messages in this section are supported. If you want to set styling and fold points for an unsupported language you can either do this in the container or better still, write your own lexer following the pattern of one of the existing ones.</p> <p>Scintilla also supports external lexers. These are DLLs (on Windows) or .so modules (on GTK+/Linux) that export three functions: <code>GetLexerCount</code>, <code>GetLexerName</code>, and <code>GetLexerFactory</code>. See <code>externalLexer.cxx</code> for more.</p> <code><a class="message" href="#SCI_SETLEXER">SCI_SETLEXER(int lexer)</a><br /> <a class="message" href="#SCI_GETLEXER">SCI_GETLEXER</a><br /> <a class="message" href="#SCI_SETLEXERLANGUAGE">SCI_SETLEXERLANGUAGE(<unused>, const char *name)</a><br /> <a class="message" href="#SCI_GETLEXERLANGUAGE">SCI_GETLEXERLANGUAGE(<unused>, char *name)</a><br /> <a class="message" href="#SCI_LOADLEXERLIBRARY">SCI_LOADLEXERLIBRARY(<unused>, const char *path)</a><br /> <a class="message" href="#SCI_COLOURISE">SCI_COLOURISE(int start, int end)</a><br /> <a class="message" href="#SCI_CHANGELEXERSTATE">SCI_CHANGELEXERSTATE(int start, int end)</a><br /> <a class="message" href="#SCI_PROPERTYNAMES">SCI_PROPERTYNAMES(<unused>, char *names)</a><br /> <a class="message" href="#SCI_PROPERTYTYPE">SCI_PROPERTYTYPE(const char *name)</a><br /> <a class="message" href="#SCI_DESCRIBEPROPERTY">SCI_DESCRIBEPROPERTY(const char *name, char *description)</a><br /> <a class="message" href="#SCI_SETPROPERTY">SCI_SETPROPERTY(const char *key, const char *value)</a><br /> <a class="message" href="#SCI_GETPROPERTY">SCI_GETPROPERTY(const char *key, char *value)</a><br /> <a class="message" href="#SCI_GETPROPERTYEXPANDED">SCI_GETPROPERTYEXPANDED(const char *key, char *value)</a><br /> <a class="message" href="#SCI_GETPROPERTYINT">SCI_GETPROPERTYINT(const char *key, int default)</a><br /> <a class="message" href="#SCI_DESCRIBEKEYWORDSETS">SCI_DESCRIBEKEYWORDSETS(<unused>, char *descriptions)</a><br /> <a class="message" href="#SCI_SETKEYWORDS">SCI_SETKEYWORDS(int keyWordSet, const char *keyWordList)</a><br /> <a class="message" href="#SCI_GETSTYLEBITSNEEDED">SCI_GETSTYLEBITSNEEDED</a><br /> <div class="provisional"> <a class="message" href="#SCI_GETSUBSTYLEBASES">SCI_GETSUBSTYLEBASES(<unused>, char *styles)</a><br /> <a class="message" href="#SCI_DISTANCETOSECONDARYSTYLES">SCI_DISTANCETOSECONDARYSTYLES</a><br /> <a class="message" href="#SCI_ALLOCATESUBSTYLES">SCI_ALLOCATESUBSTYLES(int styleBase, int numberStyles)</a><br /> <a class="message" href="#SCI_FREESUBSTYLES">SCI_FREESUBSTYLES</a><br /> <a class="message" href="#SCI_GETSUBSTYLESSTART">SCI_GETSUBSTYLESSTART(int styleBase)</a><br /> <a class="message" href="#SCI_GETSUBSTYLESLENGTH">SCI_GETSUBSTYLESLENGTH(int styleBase)</a><br /> <a class="message" href="#SCI_SETIDENTIFIERS">SCI_SETIDENTIFIERS(int style, const char *identifiers)</a><br /> </div> </code> <p><b id="SCI_SETLEXER">SCI_SETLEXER(int lexer)</b><br /> <b id="SCI_GETLEXER">SCI_GETLEXER</b><br /> You can select the lexer to use with an integer code from the <code>SCLEX_*</code> enumeration in <code>Scintilla.h</code>. There are two codes in this sequence that do not use lexers: <code>SCLEX_NULL</code> to select no lexing action and <code>SCLEX_CONTAINER</code> which sends the <code><a class="message" href="#SCN_STYLENEEDED">SCN_STYLENEEDED</a></code> notification to the container whenever a range of text needs to be styled. You cannot use the <code>SCLEX_AUTOMATIC</code> value; this identifies additional external lexers that Scintilla assigns unused lexer numbers to.</p> <p><b id="SCI_SETLEXERLANGUAGE">SCI_SETLEXERLANGUAGE(<unused>, const char *name)</b><br /> <b id="SCI_GETLEXERLANGUAGE">SCI_GETLEXERLANGUAGE(<unused>, char *name)</b><br /> <code>SCI_SETLEXERLANGUAGE</code> lets you select a lexer by name, and is the only method if you are using an external lexer or if you have written a lexer module for a language of your own and do not wish to assign it an explicit lexer number. To select an existing lexer, set <code>name</code> to match the (case sensitive) name given to the module, for example "ada" or "python", not "Ada" or "Python". To locate the name for the built-in lexers, open the relevant <code>Lex*.cxx</code> file and search for <code>LexerModule</code>. The third argument in the <code>LexerModule</code> constructor is the name to use.</p> <p>To test if your lexer assignment worked, use <a class="message" href="#SCI_GETLEXER"><code>SCI_GETLEXER</code></a> before and after setting the new lexer to see if the lexer number changed.</p> <p><code>SCI_GETLEXERLANGUAGE</code> retrieves the name of the lexer.</p> <p><b id="SCI_LOADLEXERLIBRARY">SCI_LOADLEXERLIBRARY(<unused>, const char *path)</b><br /> Load a lexer implemented in a shared library. This is a .so file on GTK+/Linux or a .DLL file on Windows. </p> <p><b id="SCI_COLOURISE">SCI_COLOURISE(int startPos, int endPos)</b><br /> This requests the current lexer or the container (if the lexer is set to <code>SCLEX_CONTAINER</code>) to style the document between <code>startPos</code> and <code>endPos</code>. If <code>endPos</code> is -1, the document is styled from <code>startPos</code> to the end. If the <code>"fold"</code> property is set to <code>"1"</code> and your lexer or container supports folding, fold levels are also set. This message causes a redraw.</p> <p><b id="SCI_CHANGELEXERSTATE">SCI_CHANGELEXERSTATE(int startPos, int endPos)</b><br /> Indicate that the internal state of a lexer has changed over a range and therefore there may be a need to redraw.</p> <p><b id="SCI_PROPERTYNAMES">SCI_PROPERTYNAMES(<unused>, char *names)</b><br /> <b id="SCI_PROPERTYTYPE">SCI_PROPERTYTYPE(const char *name)</b><br /> <b id="SCI_DESCRIBEPROPERTY">SCI_DESCRIBEPROPERTY(const char *name, char *description)</b><br /> Information may be retrieved about the properties that can be set for the current lexer. This information is only available for newer lexers. <code>SCI_PROPERTYNAMES</code> returns a string with all of the valid properties separated by "\n". If the lexer does not support this call then an empty string is returned. Properties may be boolean (<code>SC_TYPE_BOOLEAN</code>), integer (<code>SC_TYPE_INTEGER</code>), or string (<code>SC_TYPE_STRING</code>) and this is found with <code>SCI_PROPERTYTYPE</code>. A description of a property in English is returned by <code>SCI_DESCRIBEPROPERTY</code>.</p> <p><b id="SCI_SETPROPERTY">SCI_SETPROPERTY(const char *key, const char *value)</b><br /> You can communicate settings to lexers with keyword:value string pairs. There is no limit to the number of keyword pairs you can set, other than available memory. <code>key</code> is a case sensitive keyword, <code>value</code> is a string that is associated with the keyword. If there is already a value string associated with the keyword, it is replaced. If you pass a zero length string, the message does nothing. Both <code>key</code> and <code>value</code> are used without modification; extra spaces at the beginning or end of <code>key</code> are significant.</p> <p>The <code>value</code> string can refer to other keywords. For example, <code>SCI_SETPROPERTY("foldTimes10", "$(fold)0")</code> stores the string <code>"$(fold)0"</code>, but when this is accessed, the <code>$(fold)</code> is replaced by the value of the <code>"fold"</code> keyword (or by nothing if this keyword does not exist).</p> <p>Currently the "fold" property is defined for most of the lexers to set the fold structure if set to "1". <code>SCLEX_PYTHON</code> understands <code>"tab.timmy.whinge.level"</code> as a setting that determines how to indicate bad indentation. Most keywords have values that are interpreted as integers. Search the lexer sources for <code>GetPropertyInt</code> to see how properties are used.</p> <p>There is a convention for naming properties used by lexers so that the set of properties can be found by scripts. Property names should start with "lexer.<lexer>." or "fold.<lexer>." when they apply to one lexer or start with "lexer." or "fold." if they apply to multiple lexers.</p> <p>Applications may discover the set of properties used by searching the source code of lexers for lines that contain <code>GetProperty</code> and a double quoted string and extract the value of the double quoted string as the property name. The <code>scintilla/src/LexGen.py</code> script does this and can be used as an example. Documentation for the property may be located above the call as a multi-line comment starting with <br/><code>// property <property-name></code></p> <p><b id="SCI_GETPROPERTY">SCI_GETPROPERTY(const char *key, char *value)</b><br /> Lookup a keyword:value pair using the specified key; if found, copy the value to the user-supplied buffer and return the length (not including the terminating 0). If not found, copy an empty string to the buffer and return 0.</p> <p>Note that "keyword replacement" as described in <a class="message" href="#SCI_SETPROPERTY"> <code>SCI_SETPROPERTY</code></a> will not be performed.</p> <p>If the value argument is 0 then the length that should be allocated to store the value is returned; again, the terminating 0 is not included.</p> <p><b id="SCI_GETPROPERTYEXPANDED">SCI_GETPROPERTYEXPANDED(const char *key, char *value)</b><br /> Lookup a keyword:value pair using the specified key; if found, copy the value to the user-supplied buffer and return the length (not including the terminating 0). If not found, copy an empty string to the buffer and return 0.</p> <p>Note that "keyword replacement" as described in <a class="message" href="#SCI_SETPROPERTY"> <code>SCI_SETPROPERTY</code></a> will be performed.</p> <p>If the value argument is 0 then the length that should be allocated to store the value (including any indicated keyword replacement) is returned; again, the terminating 0 is not included.</p> <p><b id="SCI_GETPROPERTYINT">SCI_GETPROPERTYINT(const char *key, int default)</b><br /> Lookup a keyword:value pair using the specified key; if found, interpret the value as an integer and return it. If not found (or the value is an empty string) then return the supplied default. If the keyword:value pair is found but is not a number, then return 0.</p> <p>Note that "keyword replacement" as described in <a class="message" href="#SCI_SETPROPERTY"> <code>SCI_SETPROPERTY</code></a> will be performed before any numeric interpretation.</p> <p><b id="SCI_SETKEYWORDS">SCI_SETKEYWORDS(int keyWordSet, const char *keyWordList)</b><br /> You can set up to 9 lists of keywords for use by the current lexer. This was increased from 6 at revision 1.50. <code>keyWordSet</code> can be 0 to 8 (actually 0 to <code>KEYWORDSET_MAX</code>) and selects which keyword list to replace. <code>keyWordList</code> is a list of keywords separated by spaces, tabs, <code>"\n"</code> or <code>"\r"</code> or any combination of these. It is expected that the keywords will be composed of standard ASCII printing characters, but there is nothing to stop you using any non-separator character codes from 1 to 255 (except common sense).</p> <p>How these keywords are used is entirely up to the lexer. Some languages, such as HTML may contain embedded languages, VBScript and JavaScript are common for HTML. For HTML, key word set 0 is for HTML, 1 is for JavaScript and 2 is for VBScript, 3 is for Python, 4 is for PHP and 5 is for SGML and DTD keywords. Review the lexer code to see examples of keyword list. A fully conforming lexer sets the fourth argument of the <code>LexerModule</code> constructor to be a list of strings that describe the uses of the keyword lists.</p> <p>Alternatively, you might use set 0 for general keywords, set 1 for keywords that cause indentation and set 2 for keywords that cause unindentation. Yet again, you might have a simple lexer that colours keywords and you could change languages by changing the keywords in set 0. There is nothing to stop you building your own keyword lists into the lexer, but this means that the lexer must be rebuilt if more keywords are added.</p> <p><b id="SCI_DESCRIBEKEYWORDSETS">SCI_DESCRIBEKEYWORDSETS(<unused>, char *descriptions)</b><br /> A description of all of the keyword sets separated by "\n" is returned by <code>SCI_DESCRIBEKEYWORDSETS</code>.</p> <p><b id="SCI_GETSTYLEBITSNEEDED">SCI_GETSTYLEBITSNEEDED</b><br /> Retrieve the number of bits the current lexer needs for styling. This should normally be the argument to <a class="message" href="#SCI_SETSTYLEBITS">SCI_SETSTYLEBITS</a>. </p> <div class="provisional"> <h3 id="Substyles">Substyles</h3> <a href="#ProvisionalMessages">These features are provisional</a><br /> <p>Lexers may support several different sublanguages and each sublanguage may want to style some number of sets of identifiers (or similar lexemes such as documentation keywords) uniquely. Preallocating a large number for each purpose would exhaust the number of allowed styles quickly. This is alleviated by substyles which allow the application to determine how many sets of identifiers to allocate for each purpose. Lexers have to explicitly support this feature by implementing the methods in <code>ILexerWithSubStyles</code>.</p> <p><b id="SCI_GETSUBSTYLEBASES">SCI_GETSUBSTYLEBASES(<unused>, char *styles)</b><br /> Fill <code>styles</code> with a byte for each style that can be split into substyles.</p> <p><b id="SCI_DISTANCETOSECONDARYSTYLES">SCI_DISTANCETOSECONDARYSTYLES</b><br /> Returns the distance between a primary style and its corresponding secondary style.</p> <p><b id="SCI_ALLOCATESUBSTYLES">SCI_ALLOCATESUBSTYLES(int styleBase, int numberStyles)</b><br /> Allocate some number of substyles for a particular base style returning the first substyle number allocated. Substyles are allocated contiguously.</p> <p><b id="SCI_FREESUBSTYLES">SCI_FREESUBSTYLES</b><br /> Free all allocated substyles.</p> <p><b id="SCI_GETSUBSTYLESSTART">SCI_GETSUBSTYLESSTART(int styleBase)</b><br /> <b id="SCI_GETSUBSTYLESLENGTH">SCI_GETSUBSTYLESLENGTH(int styleBase)</b><br /> Return the start and length of the substyles allocated for a base style.</p> <p><b id="SCI_SETIDENTIFIERS">SCI_SETIDENTIFIERS(int style, const char *identifiers)</b><br /> Similar to <code>SCI_SETKEYWORDS</code> but for substyles.</p> </div> <h2 id="LexerObjects">Lexer Objects</h2> <p>Lexers are programmed as objects that implement the ILexer interface and that interact with the document they are lexing through the IDocument interface. Previously lexers were defined by providing lexing and folding functions but creating an object to handle the interaction of a lexer with a document allows the lexer to store state information that can be used during lexing. For example a C++ lexer may store a set of preprocessor definitions or variable declarations and style these depending on their role.</p> <p>A set of helper classes allows older lexers defined by functions to be used in Scintilla.</p> <h4>ILexer</h4> <div class="highlighted"> <span class="S5">class</span><span class="S0"> </span>ILexer<span class="S0"> </span><span class="S10">{</span><br /> <span class="S5">public</span><span class="S10">:</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>Version<span class="S10">()</span><span class="S0"> </span> <span class="S5">const</span><span class="S0"> </span><span class="S10">=</span> <span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">void</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>Release<span class="S10">()</span><span class="S0"> </span> <span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span> <span class="S5">const</span><span class="S0"> </span> <span class="S5">char</span><span class="S0"> </span> <span class="S10">*</span><span class="S0"> </span> SCI_METHOD<span class="S0"> </span>PropertyNames<span class="S10">()</span> <span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD<span class="S0"> </span>PropertyType<span class="S10">(</span><span class="S5">const</span><span class="S0"> </span><span class="S5">char</span><span class="S0"> </span><span class="S10">*</span>name<span class="S10">)</span><span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">const</span><span class="S0"> </span><span class="S5">char</span><span class="S0"> </span><span class="S10">*</span><span class="S0"> </span>SCI_METHOD<span class="S0"> </span>DescribeProperty<span class="S10">(</span><span class="S5">const</span><span class="S0"> </span><span class="S5">char</span><span class="S0"> </span><span class="S10">*</span>name<span class="S10">)</span><span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>PropertySet<span class="S10">(</span><span class="S5">const</span> <span class="S0"> </span><span class="S5">char</span> <span class="S0"> </span><span class="S10">*</span>key<span class="S10">,</span> <span class="S0"> </span><span class="S5">const</span><span class="S0"> </span> <span class="S5">char</span><span class="S0"> </span><span class="S10">*</span>val<span class="S10">)</span> <span class="S0"> </span><span class="S10">=</span> <span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span> <span class="S5">const</span><span class="S0"> </span><span class="S5">char</span><span class="S0"> </span> <span class="S10">*</span><span class="S0"> </span>SCI_METHOD<span class="S0"> </span>DescribeWordListSets<span class="S10">()</span> <span class="S0"> </span><span class="S10">=</span><span class="S0"> </span> <span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>WordListSet<span class="S10">(</span><span class="S5">int</span> <span class="S0"> </span>n<span class="S10">,</span> <span class="S0"> </span><span class="S5">const</span><span class="S0"> </span> <span class="S5">char</span><span class="S0"> </span><span class="S10">*</span>wl<span class="S10">)</span> <span class="S0"> </span><span class="S10">=</span> <span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">void</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>Lex<span class="S10">(</span><span class="S5">unsigned</span> <span class="S0"> </span><span class="S5">int</span> <span class="S0"> </span>startPos<span class="S10">,</span> <span class="S0"> </span><span class="S5">int</span> <span class="S0"> </span>lengthDoc<span class="S10">,</span><span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>initStyle<span class="S10">,</span> <span class="S0"> </span>IDocument<span class="S0"> </span><span class="S10">*</span>pAccess<span class="S10">)</span> <span class="S0"> </span><span class="S10">=</span><span class="S0"> </span> <span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">void</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>Fold<span class="S10">(</span><span class="S5">unsigned</span> <span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>startPos<span class="S10">,</span> <span class="S0"> </span><span class="S5">int</span> <span class="S0"> </span>lengthDoc<span class="S10">,</span><span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>initStyle<span class="S10">,</span> <span class="S0"> </span>IDocument<span class="S0"> </span><span class="S10">*</span>pAccess<span class="S10">)</span> <span class="S0"> </span><span class="S10">=</span><span class="S0"> </span> <span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">void</span><span class="S0"> </span> <span class="S10">*</span><span class="S0"> </span>SCI_METHOD<span class="S0"> </span>PrivateCall<span class="S10">(</span><span class="S5">int</span> <span class="S0"> </span>operation<span class="S10">,</span><span class="S0"> </span><span class="S5">void</span><span class="S0"> </span> <span class="S10">*</span>pointer<span class="S10">)</span><span class="S0"> </span> <span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S10">};</span><br /> </div> <p> The return values from PropertySet and WordListSet are used to indicate whether the change requires performing lexing or folding over any of the document. It is the position at which to restart lexing and folding or -1 if the change does not require any extra work on the document. A simple approach is to return 0 if there is any possibility that a change requires lexing the document again while an optimisation could be to remember where a setting first affects the document and return that position. </p> <p><code>Release</code> is called to destroy the lexer object.</p> <p><code>PrivateCall</code> allows for direct communication between the application and a lexer. An example would be where an application maintains a single large data structure containing symbolic information about system headers (like Windows.h) and provides this to the lexer where it can be applied to each document. This avoids the costs of constructing the system header information for each document. This is invoked with the <code>SCI_PRIVATELEXERCALL</code> API.</p> <p><code>Fold</code> is called with the exact range that needs folding. Previously, lexers were called with a range that started one line before the range that needs to be folded as this allowed fixing up the last line from the previous folding. The new approach allows the lexer to decide whether to backtrack or to handle this more efficiently.</p> <h4 class="provisional">ILexerWithSubStyles</h4> <p class="provisional"> To allow lexers to report which line ends they support, and to support substyles, <code>Ilexer</code> is extended to <code>ILexerWithSubStyles</code>. </p> <div class="highlighted"> <span class="S5">class</span><span class="S0"> </span>ILexerWithSubStyles<span class="S0"> </span><span class="S10">:</span><span class="S0"> </span><span class="S5">public</span><span class="S0"> </span>ILexer<span class="S0"> </span><span class="S10">{</span><br /> <span class="S5">public</span><span class="S10">:</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD<span class="S0"> </span>LineEndTypesSupported<span class="S10">()</span><span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD<span class="S0"> </span>AllocateSubStyles<span class="S10">(</span><span class="S5">int</span><span class="S0"> </span>styleBase<span class="S10">,</span><span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>numberStyles<span class="S10">)</span><span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD<span class="S0"> </span>SubStylesStart<span class="S10">(</span><span class="S5">int</span><span class="S0"> </span>styleBase<span class="S10">)</span><span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD<span class="S0"> </span>SubStylesLength<span class="S10">(</span><span class="S5">int</span><span class="S0"> </span>styleBase<span class="S10">)</span><span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span><span class="S5">void</span><span class="S0"> </span>SCI_METHOD<span class="S0"> </span>FreeSubStyles<span class="S10">()</span><span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span><span class="S5">void</span><span class="S0"> </span>SCI_METHOD<span class="S0"> </span>SetIdentifiers<span class="S10">(</span><span class="S5">int</span><span class="S0"> </span>style<span class="S10">,</span><span class="S0"> </span><span class="S5">const</span><span class="S0"> </span><span class="S5">char</span><span class="S0"> </span><span class="S10">*</span>identifiers<span class="S10">)</span><span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD<span class="S0"> </span>DistanceToSecondaryStyles<span class="S10">()</span><span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span><span class="S5">const</span><span class="S0"> </span><span class="S5">char</span><span class="S0"> </span><span class="S10">*</span><span class="S0"> </span>SCI_METHOD<span class="S0"> </span>GetSubStyleBases<span class="S10">()</span><span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S10">};</span><br /> </div> <h4>IDocument</h4> <div class="highlighted"> <span class="S5">class</span><span class="S0"> </span>IDocument <span class="S0"> </span><span class="S10">{</span><br /> <span class="S5">public</span><span class="S10">:</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>Version<span class="S10">()</span><span class="S0"> </span> <span class="S5">const</span><span class="S0"> </span><span class="S10">=</span> <span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">void</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>SetErrorStatus<span class="S10">(</span><span class="S5">int</span> <span class="S0"> </span>status<span class="S10">)</span> <span class="S0"> </span><span class="S10">=</span><span class="S0"> </span> <span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>Length<span class="S10">()</span><span class="S0"> </span> <span class="S5">const</span><span class="S0"> </span><span class="S10">=</span> <span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">void</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>GetCharRange<span class="S10">(</span><span class="S5">char</span> <span class="S0"> </span><span class="S10">*</span>buffer<span class="S10">,</span> <span class="S0"> </span><span class="S5">int</span><span class="S0"> </span> position<span class="S10">,</span><span class="S0"> </span> <span class="S5">int</span><span class="S0"> </span>lengthRetrieve<span class="S10">)</span> <span class="S0"> </span><span class="S5">const</span> <span class="S0"> </span><span class="S10">=</span><span class="S0"> </span> <span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">char</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>StyleAt<span class="S10">(</span><span class="S5">int</span> <span class="S0"> </span>position<span class="S10">)</span><span class="S0"> </span> <span class="S5">const</span><span class="S0"> </span><span class="S10">=</span> <span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>LineFromPosition<span class="S10">(</span><span class="S5">int</span><span class="S0"> </span>position<span class="S10">)</span> <span class="S0"> </span><span class="S5">const</span><span class="S0"> </span><span class="S10">=</span> <span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span> <span class="S5">int</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>LineStart<span class="S10">(</span><span class="S5">int</span><span class="S0"> </span>line<span class="S10">)</span> <span class="S0"> </span><span class="S5">const</span><span class="S0"> </span><span class="S10">=</span> <span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span> <span class="S5">int</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>GetLevel<span class="S10">(</span><span class="S5">int</span><span class="S0"> </span>line<span class="S10">)</span> <span class="S0"> </span> <span class="S5">const</span><span class="S0"> </span><span class="S10">=</span><span class="S0"> </span> <span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span> <span class="S5">int</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>SetLevel<span class="S10">(</span><span class="S5">int</span> <span class="S0"> </span>line<span class="S10">,</span><span class="S0"> </span> <span class="S5">int</span><span class="S0"> </span>level<span class="S10">)</span> <span class="S0"> </span><span class="S10">=</span><span class="S0"> </span> <span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>GetLineState<span class="S10">(</span><span class="S5">int</span> <span class="S0"> </span>line<span class="S10">)</span> <span class="S0"> </span><span class="S5">const</span><span class="S0"> </span> <span class="S10">=</span><span class="S0"> </span><span class="S4">0</span> <span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>SetLineState<span class="S10">(</span><span class="S5">int</span> <span class="S0"> </span>line<span class="S10">,</span> <span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>state<span class="S10">)</span> <span class="S0"> </span><span class="S10">=</span> <span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">void</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>StartStyling<span class="S10">(</span><span class="S5">int</span> <span class="S0"> </span>position<span class="S10">,</span> <span class="S0"> </span><span class="S5">char</span><span class="S0"> </span>mask<span class="S10">)</span> <span class="S0"> </span><span class="S10">=</span> <span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span><span class="S5">bool</span> <span class="S0"> </span>SCI_METHOD <span class="S0"> </span>SetStyleFor<span class="S10">(</span><span class="S5">int</span> <span class="S0"> </span>length<span class="S10">,</span> <span class="S0"> </span><span class="S5">char</span><span class="S0"> </span>style<span class="S10">)</span> <span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span> <span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">bool</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>SetStyles<span class="S10">(</span><span class="S5">int</span> <span class="S0"> </span>length<span class="S10">,</span><span class="S0"> </span> <span class="S5">const</span><span class="S0"> </span><span class="S5">char</span> <span class="S0"> </span><span class="S10">*</span>styles<span class="S10">)</span> <span class="S0"> </span><span class="S10">=</span><span class="S0"> </span> <span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span><span class="S5">void</span> <span class="S0"> </span>SCI_METHOD <span class="S0"> </span>DecorationSetCurrentIndicator<span class="S10">(</span><span class="S5">int</span> <span class="S0"> </span>indicator<span class="S10">)</span> <span class="S0"> </span><span class="S10">=</span> <span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">void</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>DecorationFillRange<span class="S10">(</span><span class="S5">int</span> <span class="S0"> </span>position<span class="S10">,</span> <span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>value<span class="S10">,</span> <span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>fillLength<span class="S10">)</span> <span class="S0"> </span><span class="S10">=</span><span class="S0"> </span> <span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">void</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>ChangeLexerState<span class="S10">(</span><span class="S5">int</span> <span class="S0"> </span>start<span class="S10">,</span> <span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>end<span class="S10">)</span> <span class="S0"> </span><span class="S10">=</span> <span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span> <span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD <span class="S0"> </span>CodePage<span class="S10">()</span><span class="S0"> </span><span class="S5">const</span><span class="S0"> </span> <span class="S10">=</span><span class="S0"> </span><span class="S4">0</span> <span class="S10">;</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span><span class="S5">bool</span> <span class="S0"> </span>SCI_METHOD <span class="S0"> </span>IsDBCSLeadByte<span class="S10">(</span><span class="S5">char</span> <span class="S0"> </span>ch<span class="S10">)</span> <span class="S0"> </span><span class="S5">const</span><span class="S0"> </span><span class="S10">=</span> <span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S10">};</span><br /> </div> <p>Scintilla tries to minimize the consequences of modifying text to only relex and redraw the line of the change where possible. Lexer objects contain their own private extra state which can affect later lines. For example, if the C++ lexer is greying out inactive code segments then changing the statement <code>#define BEOS 0</code> to <code>#define BEOS 1</code> may require restyling and redisplaying later parts of the document. The lexer can call <code>ChangeLexerState</code> to signal to the document that it should relex and display more.</p> <p><code>SetErrorStatus</code> is used to notify the document of exceptions. Exceptions should not be thrown over build boundaries as the two sides may be built with different compilers or incompatible exception options.</p> <h4>IDocumentWithLineEnd</h4> <p> To allow lexers to determine the end position of a line and thus more easily support Unicode line ends <code>IDocument</code> is extended to <code>IDocumentWithLineEnd</code>. </p> <div class="highlighted"> <span class="S5">class</span><span class="S0"> </span>IDocumentWithLineEnd<span class="S0"> </span><span class="S10">:</span><span class="S0"> </span><span class="S5">public</span><span class="S0"> </span>IDocument<span class="S0"> </span><span class="S10">{</span><br /> <span class="S5">public</span><span class="S10">:</span><br /> <span class="S0"> </span><span class="S5">virtual</span><span class="S0"> </span><span class="S5">int</span><span class="S0"> </span>SCI_METHOD<span class="S0"> </span>LineEnd<span class="S10">(</span><span class="S5">int</span><span class="S0"> </span>line<span class="S10">)</span><span class="S0"> </span><span class="S5">const</span><span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><span class="S10">;</span><br /> <span class="S10">};</span><br /> </div> <p>The <code>ILexer</code>, <code>ILexerWithSubStyles</code>, <code>IDocument</code>, and <code>IDocumentWithLineEnd</code> interfaces may be expanded in the future with extended versions (<code>ILexer2</code>...). The <code>Version</code> method indicates which interface is implemented and thus which methods may be called.</p> <h2 id="Notifications">Notifications</h2> <p>Notifications are sent (fired) from the Scintilla control to its container when an event has occurred that may interest the container. Notifications are sent using the <code>WM_NOTIFY</code> message on Windows and the "notify" signal on GTK+. The container is passed a <code>SCNotification</code> structure containing information about the event.</p> <pre id="SCNotification"> struct NotifyHeader { // This matches the Win32 NMHDR structure void *hwndFrom; // environment specific window handle/pointer uptr_t idFrom; // CtrlID of the window issuing the notification unsigned int code; // The SCN_* notification code }; struct SCNotification { struct Sci_NotifyHeader nmhdr; int position; /* SCN_STYLENEEDED, SCN_DOUBLECLICK, SCN_MODIFIED, SCN_MARGINCLICK, */ /* SCN_NEEDSHOWN, SCN_DWELLSTART, SCN_DWELLEND, SCN_CALLTIPCLICK, */ /* SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, SCN_HOTSPOTRELEASECLICK, */ /* SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */ /* SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */ int ch; /* SCN_CHARADDED, SCN_KEY */ int modifiers; /* SCN_KEY, SCN_DOUBLECLICK, SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, */ /* SCN_HOTSPOTRELEASECLICK, SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */ int modificationType; /* SCN_MODIFIED */ const char *text; /* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION, SCN_URIDROPPED */ int length; /* SCN_MODIFIED */ int linesAdded; /* SCN_MODIFIED */ int message; /* SCN_MACRORECORD */ uptr_t wParam; /* SCN_MACRORECORD */ sptr_t lParam; /* SCN_MACRORECORD */ int line; /* SCN_MODIFIED */ int foldLevelNow; /* SCN_MODIFIED */ int foldLevelPrev; /* SCN_MODIFIED */ int margin; /* SCN_MARGINCLICK */ int listType; /* SCN_USERLISTSELECTION */ int x; /* SCN_DWELLSTART, SCN_DWELLEND */ int y; /* SCN_DWELLSTART, SCN_DWELLEND */ int token; /* SCN_MODIFIED with SC_MOD_CONTAINER */ int annotationLinesAdded; /* SCN_MODIFIED with SC_MOD_CHANGEANNOTATION */ int updated; /* SCN_UPDATEUI */ }; </pre> <p>The notification messages that your container can choose to handle and the messages associated with them are:</p> <code><a class="message" href="#SCN_STYLENEEDED">SCN_STYLENEEDED</a><br /> <a class="message" href="#SCN_CHARADDED">SCN_CHARADDED</a><br /> <a class="message" href="#SCN_SAVEPOINTREACHED">SCN_SAVEPOINTREACHED</a><br /> <a class="message" href="#SCN_SAVEPOINTLEFT">SCN_SAVEPOINTLEFT</a><br /> <a class="message" href="#SCN_MODIFYATTEMPTRO">SCN_MODIFYATTEMPTRO</a><br /> <a class="message" href="#SCN_KEY">SCN_KEY</a><br /> <a class="message" href="#SCN_DOUBLECLICK">SCN_DOUBLECLICK</a><br /> <a class="message" href="#SCN_UPDATEUI">SCN_UPDATEUI</a><br /> <a class="message" href="#SCN_MODIFIED">SCN_MODIFIED</a><br /> <a class="message" href="#SCN_MACRORECORD">SCN_MACRORECORD</a><br /> <a class="message" href="#SCN_MARGINCLICK">SCN_MARGINCLICK</a><br /> <a class="message" href="#SCN_NEEDSHOWN">SCN_NEEDSHOWN</a><br /> <a class="message" href="#SCN_PAINTED">SCN_PAINTED</a><br /> <a class="message" href="#SCN_USERLISTSELECTION">SCN_USERLISTSELECTION</a><br /> <a class="message" href="#SCN_URIDROPPED">SCN_URIDROPPED</a><br /> <a class="message" href="#SCN_DWELLSTART">SCN_DWELLSTART</a><br /> <a class="message" href="#SCN_DWELLEND">SCN_DWELLEND</a><br /> <a class="message" href="#SCN_ZOOM">SCN_ZOOM</a><br /> <a class="message" href="#SCN_HOTSPOTCLICK">SCN_HOTSPOTCLICK</a><br /> <a class="message" href="#SCN_HOTSPOTDOUBLECLICK">SCN_HOTSPOTDOUBLECLICK</a><br /> <a class="message" href="#SCN_HOTSPOTRELEASECLICK">SCN_HOTSPOTRELEASECLICK</a><br /> <a class="message" href="#SCN_INDICATORCLICK">SCN_INDICATORCLICK</a><br /> <a class="message" href="#SCN_INDICATORRELEASE">SCN_INDICATORRELEASE</a><br /> <a class="message" href="#SCN_CALLTIPCLICK">SCN_CALLTIPCLICK</a><br /> <a class="message" href="#SCN_AUTOCSELECTION">SCN_AUTOCSELECTION</a><br /> <a class="message" href="#SCN_AUTOCCANCELLED">SCN_AUTOCCANCELLED</a><br /> <a class="message" href="#SCN_AUTOCCHARDELETED">SCN_AUTOCCHARDELETED</a><br /> </code> <p>The following <code>SCI_*</code> messages are associated with these notifications:</p> <code><a class="message" href="#SCI_SETMODEVENTMASK">SCI_SETMODEVENTMASK(int eventMask)</a><br /> <a class="message" href="#SCI_GETMODEVENTMASK">SCI_GETMODEVENTMASK</a><br /> <a class="message" href="#SCI_SETMOUSEDWELLTIME">SCI_SETMOUSEDWELLTIME(int milliseconds)</a><br /> <a class="message" href="#SCI_GETMOUSEDWELLTIME">SCI_GETMOUSEDWELLTIME</a><br /> <a class="message" href="#SCI_SETIDENTIFIER">SCI_SETIDENTIFIER(int identifier)</a><br /> <a class="message" href="#SCI_GETIDENTIFIER">SCI_GETIDENTIFIER</a><br /> </code> <p>The following additional notifications are sent using the <code>WM_COMMAND</code> message on Windows and the "Command" signal on GTK+. This emulates the Windows Edit control. Only the lower 16 bits of the control's ID is passed in these notifications.</p> <code><a class="message" href="#SCEN_CHANGE">SCEN_CHANGE</a><br /> <a class="message" href="#SCEN_SETFOCUS">SCEN_SETFOCUS</a><br /> <a class="message" href="#SCEN_KILLFOCUS">SCEN_KILLFOCUS</a><br /> </code> <p><b id="SCI_SETIDENTIFIER">SCI_SETIDENTIFIER(int identifier)</b><br /> <b id="SCI_GETIDENTIFIER">SCI_GETIDENTIFIER</b><br /> These two messages set and get the identifier of the Scintilla instance which is included in notifications as the <code>idFrom</code> field. When an application creates multiple Scintilla widgets, this allows the source of each notification to be found. On Windows, this value is initialised in the <code>CreateWindow</code> call and stored as the <code>GWLP_ID</code> attribute of the window. The value should be small, preferrably less than 16 bits, rather than a pointer as some of the functions will only transmit 16 or 32 bits. </p> <p><b id="SCN_STYLENEEDED">SCN_STYLENEEDED</b><br /> If you used <code><a class="message" href="#SCI_SETLEXER">SCI_SETLEXER</a>(SCLEX_CONTAINER)</code> to make the container act as the lexer, you will receive this notification when Scintilla is about to display or print text that requires styling. You are required to style the text from the line that contains the position returned by <a class="message" href="#SCI_GETENDSTYLED"><code>SCI_GETENDSTYLED</code></a> up to the position passed in <code>SCNotification.position</code>. Symbolically, you need code of the form:</p> <pre> startPos = <a class="message" href="#SCI_GETENDSTYLED">SCI_GETENDSTYLED</a>() lineNumber = <a class="message" href="#SCI_LINEFROMPOSITION">SCI_LINEFROMPOSITION</a>(startPos); startPos = <a class="message" href="#SCI_POSITIONFROMLINE">SCI_POSITIONFROMLINE</a>(lineNumber); MyStyleRoutine(startPos, SCNotification.position); </pre> <p><b id="SCN_CHARADDED">SCN_CHARADDED</b><br /> This is sent when the user types an ordinary text character (as opposed to a command character) that is entered into the text. The container can use this to decide to display a <a class="jump" href="#CallTips">call tip</a> or an <a class="jump" href="#Autocompletion">auto completion list</a>. The character is in <code>SCNotification.ch</code>. This notification is sent before the character has been styled so processing that depends on styling should instead be performed in the SCN_UPDATEUI notification.</p> <p><b id="SCN_SAVEPOINTREACHED">SCN_SAVEPOINTREACHED</b><br /> <b id="SCN_SAVEPOINTLEFT">SCN_SAVEPOINTLEFT</b><br /> Sent to the container when the save point is entered or left, allowing the container to display a "document dirty" indicator and change its menus.<br /> See also: <a class="message" href="#SCI_SETSAVEPOINT"><code>SCI_SETSAVEPOINT</code></a>, <a class="message" href="#SCI_GETMODIFY"><code>SCI_GETMODIFY</code></a></p> <p><b id="SCN_MODIFYATTEMPTRO">SCN_MODIFYATTEMPTRO</b><br /> When in read-only mode, this notification is sent to the container if the user tries to change the text. This can be used to check the document out of a version control system. You can set the read-only state of a document with <code><a class="message" href="#SCI_SETREADONLY">SCI_SETREADONLY</a></code>.</p> <p><b id="SCN_KEY">SCN_KEY</b><br /> Reports all keys pressed but not consumed by Scintilla. Used on GTK+ because of some problems with keyboard focus and is not sent by the Windows version. <code>SCNotification.ch</code> holds the key code and <code>SCNotification.modifiers</code> holds the modifiers. This notification is sent if the modifiers include <code>SCMOD_ALT</code> or <code>SCMOD_CTRL</code> and the key code is less than 256.</p> <p><b id="SCN_DOUBLECLICK">SCN_DOUBLECLICK</b><br /> The mouse button was double clicked in editor. The <code>position</code> field is set to the text position of the double click, the <code>line</code> field is set to the line of the double click, and the <code>modifiers</code> field is set to the key modifiers held down in a similar manner to <a class="message" href="#SCN_KEY">SCN_KEY</a>.</p> <p><b id="SCN_UPDATEUI">SCN_UPDATEUI</b><br /> Either the text or styling of the document has changed or the selection range or scroll position has changed. Now would be a good time to update any container UI elements that depend on document or view state. The <code>updated</code> field is set to the bit set of things changed since the previous notification.</p> <table cellpadding="1" cellspacing="2" border="0" summary="Modify notification type flags"> <tbody> <tr> <th align="left">Symbol</th> <th>Value</th> <th align="left">Meaning</th> </tr> </tbody> <tbody valign="top"> <tr> <td align="left"><code>SC_UPDATE_CONTENT</code></td> <td align="center">0x01</td> <td>Contents, styling or markers have been changed.</td> </tr> <tr> <td align="left"><code>SC_UPDATE_SELECTION</code></td> <td align="center">0x02</td> <td>Selection has been changed.</td> </tr> <tr> <td align="left"><code>SC_UPDATE_V_SCROLL</code></td> <td align="center">0x04</td> <td>Scrolled vertically.</td> </tr> <tr> <td align="left"><code>SC_UPDATE_H_SCROLL</code></td> <td align="center">0x08</td> <td>Scrolled horizontally.</td> </tr> </tbody> </table> <p><b id="SCN_MODIFIED">SCN_MODIFIED</b><br /> This notification is sent when the text or styling of the document changes or is about to change. You can set a mask for the notifications that are sent to the container with <a class="message" href="#SCI_SETMODEVENTMASK"><code>SCI_SETMODEVENTMASK</code></a>. The notification structure contains information about what changed, how the change occurred and whether this changed the number of lines in the document. No modifications may be performed while in a <code>SCN_MODIFIED</code> event. The <code>SCNotification</code> fields used are:</p> <table cellpadding="1" cellspacing="2" border="0" summary="Modify notification types"> <tbody> <tr> <th align="left">Field</th> <th align="left">Usage</th> </tr> </tbody> <tbody valign="top"> <tr> <td align="left"><code>modificationType</code></td> <td align="left">A set of flags that identify the change(s) made. See the next table.</td> </tr> <tr> <td align="left"><code>position</code></td> <td align="left">Start position of a text or styling change. Set to 0 if not used.</td> </tr> <tr> <td align="left"><code>length</code></td> <td align="left">Length of the change in cells or characters when the text or styling changes. Set to 0 if not used.</td> </tr> <tr> <td align="left"><code>linesAdded</code></td> <td align="left">Number of added lines. If negative, the number of deleted lines. Set to 0 if not used or no lines added or deleted.</td> </tr> <tr> <td align="left"><code>text</code></td> <td align="left">Valid for text changes, not for style changes. If we are collecting undo information this holds a pointer to the text that is handed to the Undo system, otherwise it is zero. For user performed SC_MOD_BEFOREDELETE the text field is 0 and for user performed SC_MOD_BEFOREINSERT the text field points to an array of cells, not bytes and the length is the number of cells.</td> </tr> <tr> <td align="left"><code>line</code></td> <td align="left">The line number at which a fold level or marker change occurred. This is 0 if unused and may be -1 if more than one line changed.</td> </tr> <tr> <td align="left"><code>foldLevelNow</code></td> <td align="left">The new fold level applied to the line or 0 if this field is unused.</td> </tr> <tr> <td align="left"><code>foldLevelPrev</code></td> <td align="left">The previous folding level of the line or 0 if this field is unused.</td> </tr> </tbody> </table> <p>The <code>SCNotification.modificationType</code> field has bits set to tell you what has been done. The <code>SC_MOD_*</code> bits correspond to actions. The <code>SC_PERFORMED_*</code> bits tell you if the action was done by the user, or the result of Undo or Redo of a previous action.</p> <table cellpadding="1" cellspacing="2" border="0" summary="Modify notification type flags"> <tbody> <tr> <th align="left">Symbol</th> <th>Value</th> <th align="left">Meaning</th> <th align="left">SCNotification fields</th> </tr> </tbody> <tbody valign="top"> <tr> <td align="left"><code>SC_MOD_INSERTTEXT</code></td> <td align="center">0x01</td> <td>Text has been inserted into the document.</td> <td><code>position, length, text, linesAdded</code></td> </tr> <tr> <td align="left"><code>SC_MOD_DELETETEXT</code></td> <td align="center">0x02</td> <td>Text has been removed from the document.</td> <td><code>position, length, text, linesAdded</code></td> </tr> <tr> <td align="left"><code>SC_MOD_CHANGESTYLE</code></td> <td align="center">0x04</td> <td>A style change has occurred.</td> <td><code>position, length</code></td> </tr> <tr> <td align="left"><code>SC_MOD_CHANGEFOLD</code></td> <td align="center">0x08</td> <td>A folding change has occurred.</td> <td><code>line, foldLevelNow, foldLevelPrev</code></td> </tr> <tr> <td align="left"><code>SC_PERFORMED_USER</code></td> <td align="center">0x10</td> <td>Information: the operation was done by the user.</td> <td>None</td> </tr> <tr> <td align="left"><code>SC_PERFORMED_UNDO</code></td> <td align="center">0x20</td> <td>Information: this was the result of an Undo.</td> <td>None</td> </tr> <tr> <td align="left"><code>SC_PERFORMED_REDO</code></td> <td align="center">0x40</td> <td>Information: this was the result of a Redo.</td> <td>None</td> </tr> <tr> <td align="left"><code>SC_MULTISTEPUNDOREDO</code></td> <td align="center">0x80</td> <td>This is part of a multi-step Undo or Redo transaction.</td> <td>None</td> </tr> <tr> <td align="left"><code>SC_LASTSTEPINUNDOREDO</code></td> <td align="center">0x100</td> <td>This is the final step in an Undo or Redo transaction.</td> <td>None</td> </tr> <tr> <td align="left"><code>SC_MOD_CHANGEMARKER</code></td> <td align="center">0x200</td> <td>One or more markers has changed in a line.</td> <td><code>line</code></td> </tr> <tr> <td align="left"><code>SC_MOD_BEFOREINSERT</code></td> <td align="center">0x400</td> <td>Text is about to be inserted into the document.</td> <td><code>position, if performed by user then text in cells, length in cells</code></td> </tr> <tr> <td align="left"><code>SC_MOD_BEFOREDELETE</code></td> <td align="center">0x800</td> <td>Text is about to be deleted from the document.</td> <td><code>position, length</code></td> </tr> <tr> <td align="left"><code>SC_MOD_CHANGEINDICATOR</code></td> <td align="center">0x4000</td> <td>An indicator has been added or removed from a range of text.</td> <td><code>position, length</code></td> </tr> <tr> <td align="left"><code id="SC_MOD_CHANGELINESTATE">SC_MOD_CHANGELINESTATE</code></td> <td align="center">0x8000</td> <td>A line state has changed because <a class="message" href="#SCI_SETLINESTATE">SCI_SETLINESTATE</a> was called.</td> <td><code>line</code></td> </tr> <tr> <td align="left"><code id="SC_MOD_LEXERSTATE">SC_MOD_LEXERSTATE</code></td> <td align="center">0x80000</td> <td>The internal state of a lexer has changed over a range.</td> <td><code>position, length</code></td> </tr> <tr> <td align="left"><code id="SC_MOD_CHANGEMARGIN">SC_MOD_CHANGEMARGIN</code></td> <td align="center">0x10000</td> <td>A text margin has changed.</td> <td><code>line</code></td> </tr> <tr> <td align="left"><code id="SC_MOD_CHANGEANNOTATION">SC_MOD_CHANGEANNOTATION</code></td> <td align="center">0x20000</td> <td>An annotation has changed.</td> <td><code>line</code></td> </tr> <tr> <td align="left"><code>SC_MULTILINEUNDOREDO</code></td> <td align="center">0x1000</td> <td>This is part of an Undo or Redo with multi-line changes.</td> <td>None</td> </tr> <tr> <td align="left"><code>SC_STARTACTION</code></td> <td align="center">0x2000</td> <td>This is set on a SC_PERFORMED_USER action when it is the first or only step in an undo transaction. This can be used to integrate the Scintilla undo stack with an undo stack in the container application by adding a Scintilla action to the container's stack for the currently opened container transaction or to open a new container transaction if there is no open container transaction. </td> <td>None</td> </tr> <tr> <td align="left"><code id="SC_MOD_CONTAINER">SC_MOD_CONTAINER</code></td> <td align="center">0x40000</td> <td>This is set on for actions that the container stored into the undo stack with <a class="message" href="#SCI_ADDUNDOACTION"><code>SCI_ADDUNDOACTION</code></a>. </td> <td>token</td> </tr> <tr> <td align="left"><code>SC_MODEVENTMASKALL</code></td> <td align="center">0x7FFFF</td> <td>This is a mask for all valid flags. This is the default mask state set by <a class="message" href="#SCI_SETMODEVENTMASK"><code>SCI_SETMODEVENTMASK</code></a>.</td> <td>None</td> </tr> </tbody> </table> <p><b id="SCEN_CHANGE">SCEN_CHANGE</b><br /> <code>SCEN_CHANGE</code> (768) is fired when the text (not the style) of the document changes. This notification is sent using the <code>WM_COMMAND</code> message on Windows and the "Command" signal on GTK+ as this is the behavior of the standard Edit control (<code>SCEN_CHANGE</code> has the same value as the Windows Edit control <code>EN_CHANGE</code>). No other information is sent. If you need more detailed information use <a class="message" href="#SCN_MODIFIED"><code>SCN_MODIFIED</code></a>. You can filter the types of changes you are notified about with <a class="message" href="#SCI_SETMODEVENTMASK"><code>SCI_SETMODEVENTMASK</code></a>.</p> <p><b id="SCI_SETMODEVENTMASK">SCI_SETMODEVENTMASK(int eventMask)</b><br /> <b id="SCI_GETMODEVENTMASK">SCI_GETMODEVENTMASK</b><br /> These messages set and get an event mask that determines which document change events are notified to the container with <a class="message" href="#SCN_MODIFIED"><code>SCN_MODIFIED</code></a> and <a class="message" href="#SCEN_CHANGE"><code>SCEN_CHANGE</code></a>. For example, a container may decide to see only notifications about changes to text and not styling changes by calling <code>SCI_SETMODEVENTMASK(SC_MOD_INSERTTEXT|SC_MOD_DELETETEXT)</code>.</p> <p>The possible notification types are the same as the <code>modificationType</code> bit flags used by <code>SCN_MODIFIED</code>: <code>SC_MOD_INSERTTEXT</code>, <code>SC_MOD_DELETETEXT</code>, <code>SC_MOD_CHANGESTYLE</code>, <code>SC_MOD_CHANGEFOLD</code>, <code>SC_PERFORMED_USER</code>, <code>SC_PERFORMED_UNDO</code>, <code>SC_PERFORMED_REDO</code>, <code>SC_MULTISTEPUNDOREDO</code>, <code>SC_LASTSTEPINUNDOREDO</code>, <code>SC_MOD_CHANGEMARKER</code>, <code>SC_MOD_BEFOREINSERT</code>, <code>SC_MOD_BEFOREDELETE</code>, <code>SC_MULTILINEUNDOREDO</code>, and <code>SC_MODEVENTMASKALL</code>.</p> <p><b id="SCEN_SETFOCUS">SCEN_SETFOCUS</b><br /> <b id="SCEN_KILLFOCUS">SCEN_KILLFOCUS</b><br /> <code>SCEN_SETFOCUS</code> (512) is fired when Scintilla receives focus and <code>SCEN_KILLFOCUS</code> (256) when it loses focus. These notifications are sent using the <code>WM_COMMAND</code> message on Windows and the "Command" signal on GTK+ as this is the behavior of the standard Edit control. Unfortunately, these codes do not match the Windows Edit notification codes <code>EN_SETFOCUS</code> (256) and <code>EN_KILLFOCUS</code> (512). It is now too late to change the Scintilla codes as clients depend on the current values.</p> <p><b id="SCN_MACRORECORD">SCN_MACRORECORD</b><br /> The <code><a class="message" href="#SCI_STARTRECORD">SCI_STARTRECORD</a></code> and <a class="message" href="#SCI_STOPRECORD"><code>SCI_STOPRECORD</code></a> messages enable and disable macro recording. When enabled, each time a recordable change occurs, the <code>SCN_MACRORECORD</code> notification is sent to the container. It is up to the container to record the action. To see the complete list of <code>SCI_*</code> messages that are recordable, search the Scintilla source <code>Editor.cxx</code> for <code>Editor::NotifyMacroRecord</code>. The fields of <code>SCNotification</code> set in this notification are:</p> <table cellpadding="1" cellspacing="2" border="0" summary="Macro record notification data"> <tbody> <tr> <th align="left">Field</th> <th align="left">Usage</th> </tr> </tbody> <tbody valign="top"> <tr> <td align="left"><code>message</code></td> <td align="left">The <code>SCI_*</code> message that caused the notification.</td> </tr> <tr> <td align="left"><code>wParam</code></td> <td align="left">The value of <code>wParam</code> in the <code>SCI_*</code> message.</td> </tr> <tr> <td align="left"><code>lParam</code></td> <td align="left">The value of <code>lParam</code> in the <code>SCI_*</code> message.</td> </tr> </tbody> </table> <p><b id="SCN_MARGINCLICK">SCN_MARGINCLICK</b><br /> This notification tells the container that the mouse was clicked inside a <a class="jump" href="#Margins">margin</a> that was marked as sensitive (see <a class="message" href="#SCI_SETMARGINSENSITIVEN"><code>SCI_SETMARGINSENSITIVEN</code></a>). This can be used to perform folding or to place breakpoints. The following <code>SCNotification</code> fields are used:</p> <table cellpadding="1" cellspacing="2" border="0" summary="Margin click notification"> <tbody> <tr> <th align="left">Field</th> <th align="left">Usage</th> </tr> </tbody> <tbody valign="top"> <tr> <td align="left"><code>modifiers</code></td> <td align="left">The appropriate combination of <code>SCI_SHIFT</code>, <code>SCI_CTRL</code> and <code>SCI_ALT</code> to indicate the keys that were held down at the time of the margin click.</td> </tr> <tr> <td align="left"><code>position</code></td> <td align="left">The position of the start of the line in the document that corresponds to the margin click.</td> </tr> <tr> <td align="left"><code>margin</code></td> <td align="left">The margin number that was clicked.</td> </tr> </tbody> </table> <p><b id="SCN_NEEDSHOWN">SCN_NEEDSHOWN</b><br /> Scintilla has determined that a range of lines that is currently invisible should be made visible. An example of where this may be needed is if the end of line of a contracted fold point is deleted. This message is sent to the container in case it wants to make the line visible in some unusual way such as making the whole document visible. Most containers will just ensure each line in the range is visible by calling <a class="message" href="#SCI_ENSUREVISIBLE"><code>SCI_ENSUREVISIBLE</code></a>. The <code>position</code> and <code>length</code> fields of <code>SCNotification</code> indicate the range of the document that should be made visible. The container code will be similar to the following code skeleton:</p> <pre> firstLine = SCI_LINEFROMPOSITION(scn.position) lastLine = SCI_LINEFROMPOSITION(scn.position+scn.length-1) for line = lineStart to lineEnd do SCI_ENSUREVISIBLE(line) next </pre> <p><b id="SCN_PAINTED">SCN_PAINTED</b><br /> Painting has just been done. Useful when you want to update some other widgets based on a change in Scintilla, but want to have the paint occur first to appear more responsive. There is no other information in <code>SCNotification</code>.</p> <p><b id="SCN_USERLISTSELECTION">SCN_USERLISTSELECTION</b><br /> The user has selected an item in a <a class="jump" href="#UserLists">user list</a>. The <code>SCNotification</code> fields used are:</p> <table cellpadding="1" cellspacing="2" border="0" summary="User list notification"> <tbody> <tr> <th align="left">Field</th> <th align="left">Usage</th> </tr> </tbody> <tbody valign="top"> <tr> <td align="left"><code>listType</code></td> <td align="left">This is set to the <code>listType</code> parameter from the <a class="message" href="#SCI_USERLISTSHOW"><code>SCI_USERLISTSHOW</code></a> message that initiated the list.</td> </tr> <tr> <td align="left"><code>text</code></td> <td align="left">The text of the selection.</td> </tr> <tr> <td align="left"><code>position</code></td> <td align="left">The position the list was displayed at.</td> </tr> </tbody> </table> <br /> <p><b id="SCN_URIDROPPED">SCN_URIDROPPED</b><br /> Only on the GTK+ version. Indicates that the user has dragged a URI such as a file name or Web address onto Scintilla. The container could interpret this as a request to open the file. The <code>text</code> field of <code>SCNotification</code> points at the URI text.</p> <p><b id="SCN_DWELLSTART">SCN_DWELLSTART</b><br /> <b id="SCN_DWELLEND">SCN_DWELLEND</b><br /> <code>SCN_DWELLSTART</code> is generated when the user keeps the mouse in one position for the dwell period (see <code><a class="message" href="#SCI_SETMOUSEDWELLTIME">SCI_SETMOUSEDWELLTIME</a></code>). <code>SCN_DWELLEND</code> is generated after a <code>SCN_DWELLSTART</code> and the mouse is moved or other activity such as key press indicates the dwell is over. Both notifications set the same fields in <code>SCNotification</code>:</p> <table cellpadding="1" cellspacing="2" border="0" summary="Mouse dwell notification"> <tbody> <tr> <th align="left">Field</th> <th align="left">Usage</th> </tr> </tbody> <tbody valign="top"> <tr> <td align="left"><code>position</code></td> <td align="left">This is the nearest position in the document to the position where the mouse pointer was lingering.</td> </tr> <tr> <td align="left"><code>x, y</code></td> <td align="left">Where the pointer lingered. The <code>position</code> field is set to <code><a class="message" href="#SCI_POSITIONFROMPOINTCLOSE">SCI_POSITIONFROMPOINTCLOSE</a>(x, y)</code>.</td> </tr> </tbody> </table> <br /> <p><b id="SCI_SETMOUSEDWELLTIME">SCI_SETMOUSEDWELLTIME(int milliseconds)</b><br /> <b id="SCI_GETMOUSEDWELLTIME">SCI_GETMOUSEDWELLTIME</b><br /> These two messages set and get the time the mouse must sit still, in milliseconds, to generate a <code><a class="message" href="#SCN_DWELLSTART">SCN_DWELLSTART</a></code> notification. If set to <code>SC_TIME_FOREVER</code>, the default, no dwell events are generated.</p> <p><b id="SCN_ZOOM">SCN_ZOOM</b><br /> This notification is generated when the user zooms the display using the keyboard or the <code><a class="message" href="#SCI_SETZOOM">SCI_SETZOOM</a></code> method is called. This notification can be used to recalculate positions, such as the width of the line number margin to maintain sizes in terms of characters rather than pixels. <code>SCNotification</code> has no additional information.</p> <p> <b id="SCN_HOTSPOTCLICK">SCN_HOTSPOTCLICK</b><br /> <b id="SCN_HOTSPOTDOUBLECLICK">SCN_HOTSPOTDOUBLECLICK</b><br /> <b id="SCN_HOTSPOTRELEASECLICK">SCN_HOTSPOTRELEASECLICK</b><br /> These notifications are generated when the user clicks or double clicks on text that is in a style with the hotspot attribute set. This notification can be used to link to variable definitions or web pages. The <code>position</code> field is set the text position of the click or double click and the <code>modifiers</code> field set to the key modifiers held down in a similar manner to <a class="message" href="#SCN_KEY">SCN_KEY</a>. Only the state of the Ctrl key is reported for <code>SCN_HOTSPOTRELEASECLICK</code>.</p> <p> <b id="SCN_INDICATORCLICK">SCN_INDICATORCLICK</b><br /> <b id="SCN_INDICATORRELEASE">SCN_INDICATORRELEASE</b><br /> These notifications are generated when the user clicks or releases the mouse on text that has an indicator. The <code>position</code> field is set the text position of the click or double click and the <code>modifiers</code> field set to the key modifiers held down in a similar manner to <a class="message" href="#SCN_KEY">SCN_KEY</a>.</p> <p><b id="SCN_CALLTIPCLICK">SCN_CALLTIPCLICK</b><br /> This notification is generated when the user clicks on a calltip. This notification can be used to display the next function prototype when a function name is overloaded with different arguments. The <code>position</code> field is set to 1 if the click is in an up arrow, 2 if in a down arrow, and 0 if elsewhere.</p> <p><b id="SCN_AUTOCSELECTION">SCN_AUTOCSELECTION</b><br /> The user has selected an item in an <a class="jump" href="#Autocompletion">autocompletion list</a>. The notification is sent before the selection is inserted. Automatic insertion can be cancelled by sending a <code><a class="message" href="#SCI_AUTOCCANCEL">SCI_AUTOCCANCEL</a></code> message before returning from the notification. The <code>SCNotification</code> fields used are:</p> <table cellpadding="1" cellspacing="2" border="0" summary="Autocompletion list notification"> <tbody> <tr> <th align="left">Field</th> <th align="left">Usage</th> </tr> </tbody> <tbody valign="top"> <tr> <td align="left"><code>position</code></td> <td align="left">The start position of the word being completed.</td> </tr> <tr> <td align="left"><code>text</code></td> <td align="left">The text of the selection.</td> </tr> </tbody> </table> <p><b id="SCN_AUTOCCANCELLED">SCN_AUTOCCANCELLED</b><br /> The user has cancelled an <a class="jump" href="#Autocompletion">autocompletion list</a>. There is no other information in SCNotification.</p> <p><b id="SCN_AUTOCCHARDELETED">SCN_AUTOCCHARDELETED</b><br /> The user deleted a character while autocompletion list was active. There is no other information in SCNotification.</p> <h2 id="Images">Images</h2> <p>Two formats are supported for images used in margin markers and autocompletion lists, RGBA and XPM.</p> <h3 id="RGBA">RGBA</h3> <p>The RGBA format allows translucency with an <a class="jump" href="#alpha">alpha</a> value for each pixel. It is simpler than <code>XPM</code> and more capable.</p> <p>The data is a sequence of 4 byte pixel values starting with the pixels for the top line, with the leftmost pixel first, then continuing with the pixels for subsequent lines. There is no gap between lines for alignment reasons.</p> <p>Each pixel consists of, in order, a red byte, a green byte, a blue byte and an alpha byte. The colour bytes are not premultiplied by the alpha value. That is, a fully red pixel that is 25% opaque will be [FF, 00, 00, 3F]</p> <p>Since the RGBA pixel data does not include any size information the width and height must previously been set with the <a class="message" href="#SCI_RGBAIMAGESETWIDTH"><code>SCI_RGBAIMAGESETWIDTH</code></a> and <a class="message" href="#SCI_RGBAIMAGESETHEIGHT"><code>SCI_RGBAIMAGESETHEIGHT</code></a> messages.</p> <p>GUI platforms often include functions for reading image file formats like PNG into memory in the RGBA form or a similar form. If there is no suitable platform support, the <a href="http://lodev.org/lodepng/">LodePNG and picoPNG</a> libraries are small libraries for loading and decoding PNG files available under a BSD-style license.</p> <p>RGBA format is supported on Windows, GTK+ and OS X Cocoa. It is not supported on OS X Carbon.</p> <h3 id="XPM">XPM</h3> <p>The XPM format is <a class="jump" href="http://en.wikipedia.org/wiki/X_PixMap">described here</a>. Scintilla is only able to handle XPM pixmaps that use one character per pixel with no named colours. There may be a completely transparent colour named "None".</p> <p>There are two forms of data structure used for XPM images, the first "lines form" format is well suited to embedding an image inside C source code and the "text form" is suited to reading from a file. In the lines form, an array of strings is used with the first string indicating the dimensions and number of colours used. This is followed by a string for each colour and that section is followed by the image with one string per line. The text form contains the same data as one null terminated block formatted as C source code starting with a "/* XPM */" comment to mark the format.</p> <p>Either format may be used with Scintilla APIs with the bytes at the location pointed to examined to determine which format: if the bytes start with "/* XPM */" then it is treated as text form, otherwise it is treated as lines form.</p> <p>XPM format is supported on on all platforms.</p> <h2 id="GTK">GTK+</h2> <p>On GTK+, the following functions create a Scintilla widget, communicate with it and allow resources to be released after all Scintilla widgets have been destroyed.</p> <code><a class="message" href="#scintilla_new">GtkWidget *scintilla_new()</a><br /> <a class="message" href="#scintilla_set_id">void scintilla_set_id(ScintillaObject *sci, uptr_t id)</a><br /> <a class="message" href="#scintilla_send_message">sptr_t scintilla_send_message(ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam)</a><br /> <a class="message" href="#scintilla_release_resources">void scintilla_release_resources()</a><br /> </code> <p><b id="scintilla_new">GtkWidget *scintilla_new()</b><br /> Create a new Scintilla widget. The returned pointer can be added to a container and displayed in the same way as other widgets.</p> <p><b id="scintilla_set_id">void scintilla_set_id(ScintillaObject *sci, uptr_t id)</b><br /> Set the control ID which will be used in the idFrom field of the NotifyHeader structure of all notifications for this instance. This is equivalent to <a class="message" href="#SCI_SETIDENTIFIER">SCI_SETIDENTIFIER</a>.</p> <p><b id="scintilla_send_message">sptr_t scintilla_send_message(ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam)</b><br /> The main entry point allows sending any of the messages described in this document.</p> <p><b id="scintilla_release_resources">void scintilla_release_resources()</b><br /> Call this to free any remaining resources after all the Scintilla widgets have been destroyed.</p> <h2 id="ProvisionalMessages">Provisional messages</h2> <p>Complex new features may be added as 'provisional' to allow further changes to the API. Provisional features may even be removed if experience shows they are a mistake.</p> <p>Provisional features are displayed in this document with <span class="provisional">a distinctive background colour</span>.</p> <p>Some developers may want to only use features that are stable and have graduated from provisional status. To avoid using provisional messages compile with the symbol <code>SCI_DISABLE_PROVISIONAL</code> defined.</p> <h2 id="DeprecatedMessages">Deprecated messages and notifications</h2> <p>The following messages are currently supported to emulate existing Windows controls, but they will be removed in future versions of Scintilla. If you use these messages you should replace them with the Scintilla equivalent.</p> <pre> WM_GETTEXT(int length, char *text) WM_SETTEXT(<unused>, const char *text) EM_GETLINE(int line, char *text) EM_REPLACESEL(<unused>, const char *text) EM_SETREADONLY EM_GETTEXTRANGE(<unused>, TEXTRANGE *tr) WM_CUT WM_COPY WM_PASTE WM_CLEAR WM_UNDO EM_CANUNDO EM_EMPTYUNDOBUFFER WM_GETTEXTLENGTH EM_GETFIRSTVISIBLELINE EM_GETLINECOUNT EM_GETMODIFY EM_SETMODIFY(bool isModified) EM_GETRECT(RECT *rect) EM_GETSEL(int *start, int *end) EM_EXGETSEL(<unused>, CHARRANGE *cr) EM_SETSEL(int start, int end) EM_EXSETSEL(<unused>, CHARRANGE *cr) EM_GETSELTEXT(<unused>, char *text) EM_LINEFROMCHAR(int position) EM_EXLINEFROMCHAR(int position) EM_LINEINDEX(int line) EM_LINELENGTH(int position) EM_SCROLL(int line) EM_LINESCROLL(int column, int line) EM_SCROLLCARET() EM_CANPASTE EM_CHARFROMPOS(<unused>, POINT *location) EM_POSFROMCHAR(int position, POINT *location) EM_SELECTIONTYPE EM_HIDESELECTION(bool hide) EM_FINDTEXT(int flags, FINDTEXTEX *ft) EM_FINDTEXTEX(int flags, FINDTEXTEX *ft) EM_GETMARGINS EM_SETMARGINS(EC_LEFTMARGIN or EC_RIGHTMARGIN or EC_USEFONTINFO, int val) EM_FORMATRANGE </pre> <p>The following are features that are only included if you define <code>INCLUDE_DEPRECATED_FEATURES</code> in <code>Scintilla.h</code>. To ensure future compatibility you should change them as indicated.</p> <p><b id="SC_CP_DBCS">SC_CP_DBCS</b> Deprecated<br /> This was used to set a DBCS (Double Byte Character Set) mode on GTK+. An explicit DBCS code page should be used when calling <a class="message" href="#SCI_SETCODEPAGE">SCI_SETCODEPAGE</a></p> <p><b id="SCI_SETUSEPALETTE">SCI_SETUSEPALETTE(bool allowPaletteUse)</b> Deprecated<br /> <b id="SCI_GETUSEPALETTE">SCI_GETUSEPALETTE</b> Deprecated<br /> Scintilla no longer supports palette mode. The last version to support palettes was 2.29. Any calls to these methods should be removed.</p> <h2 id="EditMessagesNeverSupportedByScintilla">Edit messages never supported by Scintilla</h2> <pre> EM_GETWORDBREAKPROC EM_GETWORDBREAKPROCEX EM_SETWORDBREAKPROC EM_SETWORDBREAKPROCEX EM_GETWORDWRAPMODE EM_SETWORDWRAPMODE EM_LIMITTEXT EM_EXLIMITTEXT EM_SETRECT EM_SETRECTNP EM_FMTLINES EM_GETHANDLE EM_SETHANDLE EM_GETPASSWORDCHAR EM_SETPASSWORDCHAR EM_SETTABSTOPS EM_FINDWORDBREAK EM_GETCHARFORMAT EM_SETCHARFORMAT EM_GETOLEINTERFACE EM_SETOLEINTERFACE EM_SETOLECALLBACK EM_GETPARAFORMAT EM_SETPARAFORMAT EM_PASTESPECIAL EM_REQUESTRESIZE EM_GETBKGNDCOLOR EM_SETBKGNDCOLOR EM_STREAMIN EM_STREAMOUT EM_GETIMECOLOR EM_SETIMECOLOR EM_GETIMEOPTIONS EM_SETIMEOPTIONS EM_GETOPTIONS EM_SETOPTIONS EM_GETPUNCTUATION EM_SETPUNCTUATION EM_GETTHUMB EM_GETEVENTMASK EM_SETEVENTMASK EM_DISPLAYBAND EM_SETTARGETDEVICE </pre> <p>Scintilla tries to be a superset of the standard windows Edit and RichEdit controls wherever that makes sense. As it is not intended for use in a word processor, some edit messages can not be sensibly handled. Unsupported messages have no effect.</p> <h2 id="BuildingScintilla">Building Scintilla</h2> <p>To build Scintilla or SciTE, see the README file present in both the Scintilla and SciTE directories. For Windows, GCC 3.2, Borland C++ or Microsoft Visual Studio .NET can be used for building. There is a make file for building Scintilla but not SciTE with Visual C++ 6 at scintilla/win32/scintilla_vc6.mak. For GTK+, GCC 3.1 should be used. GTK+ 1.2x and 2.0x are supported. The version of GTK+ installed should be detected automatically. When both GTK+ 1 and GTK+ 2 are present, building for GTK+ 1.x requires defining GTK1 on the command line.</p> <h3>Static linking</h3> <p>On Windows, Scintilla is normally used as a dynamic library as a .DLL file. If you want to link Scintilla directly into your application .EXE or .DLL file, then the <code>STATIC_BUILD</code> preprocessor symbol should be defined and <code>Scintilla_RegisterClasses</code> called. <code>STATIC_BUILD</code> prevents compiling the <code>DllMain</code> function which will conflict with any <code>DllMain</code> defined in your code. <code>Scintilla_RegisterClasses</code> takes the <code>HINSTANCE</code> of your application and ensures that the "Scintilla" window class is registered.</p> <h3>Ensuring lexers are linked into Scintilla</h3> <p>Depending on the compiler and linker used, the lexers may be stripped out. This is most often caused when building a static library. To ensure the lexers are linked in, the <code>Scintilla_LinkLexers()</code> function may be called.</p> <h3>Changing set of lexers</h3> <p>To change the set of lexers in Scintilla, add and remove lexer source files (<code>Lex*.cxx</code>) from the <code>scintilla/src directory</code> and run the <code>src/LexGen.py</code> script from the <code>src</code> directory to update the make files and <code>KeyWords.cxx</code>. <code>LexGen.py</code> requires Python 2.1 or later. If you do not have access to Python, you can hand edit <code>KeyWords.cxx</code> in a simple-minded way, following the patterns of other lexers. The important thing is to include <code>LINK_LEXER(lmMyLexer);</code> to correspond with the <code>LexerModule lmMyLexer(...);</code> in your lexer source code.</p> <h3>Building with an alternative Regular Expression implementation</h3> <p id="AlternativeRegEx">A simple interface provides support for switching the Regular Expressions engine at compile time. You must implement <code>RegexSearchBase</code> for your chosen engine, look at the built-in implementation <code>BuiltinRegex</code> to see how this is done. You then need to implement the factory method <code>CreateRegexSearch</code> to create an instance of your class. You must disable the built-in implementation by defining <code>SCI_OWNREGEX</code>.</p> </body> </html> |
Added doc/ScintillaDownload.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="HTML Tidy, see www.w3.org" /> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title> Download Scintilla </title> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5">Download Scintilla</font></a> </td> </tr> </table> <table bgcolor="#CCCCCC" width="100%" cellspacing="0" cellpadding="8" border="0"> <tr> <td> <font size="4"> <a href="http://prdownloads.sourceforge.net/scintilla/scintilla330.zip?download"> Windows</a> <a href="http://prdownloads.sourceforge.net/scintilla/scintilla330.tgz?download"> GTK+/Linux</a> </font> </td> </tr> </table> <h2> Download. </h2> <p> The <a href="License.txt">license</a> for using Scintilla or SciTE is similar to that of Python containing very few restrictions. </p> <h3> Release 3.3.0 </h3> <h4> Source Code </h4> The source code package contains all of the source code for Scintilla but no binary executable code and is available in <ul> <li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla330.zip?download">zip format</a> (1250K) commonly used on Windows</li> <li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla330.tgz?download">tgz format</a> (1100K) commonly used on Linux and compatible operating systems</li> </ul> Instructions for building on both Windows and Linux are included in the readme file. <h4> Windows Executable Code </h4> There is no download available containing only the Scintilla DLL. However, it is included in the <a href="SciTEDownload.html">SciTE executable full download</a> as SciLexer.DLL. <p> <a href="SciTEDownload.html">SciTE</a> is a good demonstration of Scintilla. </p> <p> Previous versions can be downloaded from the <a href="ScintillaHistory.html">history page</a>. </p> </body> </html> |
Added doc/ScintillaHistory.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 7049 7050 7051 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164 7165 7166 7167 7168 7169 7170 7171 7172 7173 7174 7175 7176 7177 7178 7179 7180 7181 7182 7183 7184 7185 7186 7187 7188 7189 7190 7191 7192 7193 7194 7195 7196 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315 7316 7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 7327 7328 7329 7330 7331 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 7358 7359 7360 7361 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 7392 7393 7394 7395 7396 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 7407 7408 7409 7410 7411 7412 7413 7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512 7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593 7594 7595 7596 7597 7598 7599 7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646 7647 7648 7649 7650 7651 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669 7670 7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752 7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 7820 7821 7822 7823 7824 7825 7826 7827 7828 7829 7830 7831 7832 7833 7834 7835 7836 7837 7838 7839 7840 7841 7842 7843 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 7936 7937 7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968 7969 7970 7971 7972 7973 7974 7975 7976 7977 7978 7979 7980 7981 7982 7983 7984 7985 7986 7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093 8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 8143 8144 8145 8146 8147 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213 8214 8215 8216 8217 8218 8219 8220 8221 8222 8223 8224 8225 8226 8227 8228 8229 8230 8231 8232 8233 8234 8235 8236 8237 8238 8239 8240 8241 8242 8243 8244 8245 8246 8247 8248 8249 8250 8251 8252 8253 8254 8255 8256 8257 8258 8259 8260 8261 8262 8263 8264 8265 8266 8267 8268 8269 8270 8271 8272 8273 8274 8275 8276 8277 8278 8279 8280 8281 8282 8283 8284 8285 8286 8287 8288 8289 8290 8291 8292 8293 8294 8295 8296 8297 8298 8299 8300 8301 8302 8303 8304 8305 8306 8307 8308 8309 8310 8311 8312 8313 8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 8335 8336 8337 8338 8339 8340 8341 8342 8343 8344 8345 8346 8347 8348 8349 8350 8351 8352 8353 8354 8355 8356 8357 8358 8359 8360 8361 8362 8363 8364 8365 8366 8367 8368 8369 8370 8371 8372 8373 8374 8375 8376 8377 8378 8379 8380 8381 8382 8383 8384 8385 8386 8387 8388 8389 8390 8391 8392 8393 8394 8395 8396 8397 8398 8399 8400 8401 8402 8403 8404 8405 8406 8407 8408 8409 8410 8411 8412 8413 8414 8415 8416 8417 8418 8419 8420 8421 8422 8423 8424 8425 8426 8427 8428 8429 8430 8431 8432 8433 8434 8435 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449 8450 8451 8452 8453 8454 8455 8456 8457 8458 8459 8460 8461 8462 8463 8464 8465 8466 8467 8468 8469 8470 8471 8472 8473 8474 8475 8476 8477 8478 8479 8480 8481 8482 8483 8484 8485 8486 8487 8488 8489 8490 8491 8492 8493 8494 8495 8496 8497 8498 8499 8500 8501 8502 8503 8504 8505 8506 8507 8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 8532 8533 8534 8535 8536 8537 8538 8539 8540 8541 8542 8543 8544 8545 8546 8547 8548 8549 8550 8551 8552 8553 8554 8555 8556 8557 8558 8559 8560 8561 8562 8563 8564 8565 8566 8567 8568 8569 8570 8571 8572 8573 8574 8575 8576 8577 8578 8579 8580 8581 8582 8583 8584 8585 8586 8587 8588 8589 8590 8591 8592 8593 8594 8595 8596 8597 8598 8599 8600 8601 8602 8603 8604 8605 8606 8607 8608 8609 8610 8611 8612 8613 8614 8615 8616 8617 8618 8619 8620 8621 8622 8623 8624 8625 8626 8627 8628 8629 8630 8631 8632 8633 8634 8635 8636 8637 8638 8639 8640 8641 8642 8643 8644 8645 8646 8647 8648 8649 8650 8651 8652 8653 8654 8655 8656 8657 8658 8659 8660 8661 8662 8663 8664 8665 8666 8667 8668 8669 8670 8671 8672 8673 8674 8675 8676 8677 8678 8679 8680 8681 8682 8683 8684 8685 8686 8687 8688 8689 8690 8691 8692 8693 8694 8695 8696 8697 8698 8699 8700 8701 8702 8703 8704 8705 8706 8707 8708 8709 8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 8732 8733 8734 8735 8736 8737 8738 8739 8740 8741 8742 8743 8744 8745 8746 8747 8748 8749 8750 8751 8752 8753 8754 8755 8756 8757 8758 8759 8760 8761 8762 8763 8764 8765 8766 8767 8768 8769 8770 8771 8772 8773 8774 8775 8776 8777 8778 8779 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 8813 8814 8815 8816 8817 8818 8819 8820 8821 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 8846 8847 8848 8849 8850 8851 8852 8853 8854 8855 8856 8857 8858 8859 8860 8861 8862 8863 8864 8865 8866 8867 8868 8869 8870 8871 8872 8873 8874 8875 8876 8877 8878 8879 8880 8881 8882 8883 8884 8885 8886 8887 8888 8889 8890 8891 8892 8893 8894 8895 8896 8897 8898 8899 8900 8901 8902 8903 8904 8905 8906 8907 8908 8909 8910 8911 8912 8913 8914 8915 8916 8917 8918 8919 8920 8921 8922 8923 8924 8925 8926 8927 8928 8929 8930 8931 8932 8933 8934 8935 8936 8937 8938 8939 8940 8941 8942 8943 8944 8945 8946 8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="HTML Tidy, see www.w3.org" /> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title> Scintilla and SciTE </title> <style type="text/css"> table { border-collapse: collapse; font-size: 80%; } td { xborder: 1px solid #1F1F1F; padding: 0px 4px; } </style> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5">Scintilla and SciTE</font></a> </td> </tr> </table> <h2> History of Scintilla and SciTE </h2> <h3> Contributors </h3> <p> Thanks to all the people that have contributed patches, bug reports and suggestions. </p> <p> Source code and documentation have been contributed by </p> <table> <tr> <td>Atsuo Ishimoto</td> <td>Mark Hammond</td> <td>Francois Le Coguiec</td> <td>Dale Nagata</td> </tr><tr> <td>Ralf Reinhardt</td> <td>Philippe Lhoste</td> <td>Andrew McKinlay</td> <td>Stephan R. A. Deibel</td> </tr><tr> <td>Hans Eckardt</td> <td>Vassili Bourdo</td> <td>Maksim Lin</td> <td>Robin Dunn</td> </tr><tr> <td>John Ehresman</td> <td>Steffen Goeldner</td> <td>Deepak S.</td> <td>Yann Gaillard</td> </tr><tr> <td>Aubin Paul</td> <td>Jason Diamond</td> <td>Ahmad Baitalmal</td> <td>Paul Winwood</td> </tr><tr> <td>Maxim Baranov</td> <td>Ragnar Højland</td> <td>Christian Obrecht</td> <td>Andreas Neukoetter</td> </tr><tr> <td>Adam Gates</td> <td>Steve Lhomme</td> <td>Ferdinand Prantl</td> <td>Jan Dries</td> </tr><tr> <td>Markus Gritsch</td> <td>Tahir Karaca</td> <td>Ahmad Zawawi</td> <td>Laurent le Tynevez</td> </tr><tr> <td>Walter Braeu</td> <td>Ashley Cambrell</td> <td>Garrett Serack</td> <td>Holger Schmidt</td> </tr><tr> <td><a href="http://www.activestate.com">ActiveState</a></td> <td>James Larcombe</td> <td>Alexey Yutkin</td> <td>Jan Hercek</td> </tr><tr> <td>Richard Pecl</td> <td>Edward K. Ream</td> <td>Valery Kondakoff</td> <td>Smári McCarthy</td> </tr><tr> <td>Clemens Wyss</td> <td>Simon Steele</td> <td>Serge A. Baranov</td> <td>Xavier Nodet</td> </tr><tr> <td>Willy Devaux</td> <td>David Clain</td> <td>Brendon Yenson</td> <td>Vamsi Potluru</td> </tr><tr> <td>Praveen Ambekar</td> <td>Alan Knowles</td> <td>Kengo Jinno</td> <td>Valentin Valchev</td> </tr><tr> <td>Marcos E. Wurzius</td> <td>Martin Alderson</td> <td>Robert Gustavsson</td> <td>José Fonseca</td> </tr><tr> <td>Holger Kiemes</td> <td>Francis Irving</td> <td>Scott Kirkwood</td> <td>Brian Quinlan</td> </tr><tr> <td>Ubi</td> <td>Michael R. Duerig</td> <td>Deepak T</td> <td>Don Paul Beletsky</td> </tr><tr> <td>Gerhard Kalab</td> <td>Olivier Dagenais</td> <td>Josh Wingstrom</td> <td>Bruce Dodson</td> </tr><tr> <td>Sergey Koshcheyev</td> <td>Chuan-jian Shen</td> <td>Shane Caraveo</td> <td>Alexander Scripnik</td> </tr><tr> <td>Ryan Christianson</td> <td>Martin Steffensen</td> <td>Jakub Vrána</td> <td>The Black Horus</td> </tr><tr> <td>Bernd Kreuss</td> <td>Thomas Lauer</td> <td>Mike Lansdaal</td> <td>Yukihiro Nakai</td> </tr><tr> <td>Jochen Tucht</td> <td>Greg Smith</td> <td>Steve Schoettler</td> <td>Mauritius Thinnes</td> </tr><tr> <td>Darren Schroeder</td> <td>Pedro Guerreiro</td> <td>Dan Petitt</td> <td>Biswapesh Chattopadhyay</td> </tr><tr> <td>Kein-Hong Man</td> <td>Patrizio Bekerle</td> <td>Nigel Hathaway</td> <td>Hrishikesh Desai</td> </tr><tr> <td>Sergey Puljajev</td> <td>Mathias Rauen</td> <td>Angelo Mandato</td> <td>Denis Sureau</td> </tr><tr> <td>Kaspar Schiess</td> <td>Christoph Hösler</td> <td>João Paulo F Farias</td> <td>Ron Schofield</td> </tr><tr> <td>Stefan Wosnik</td> <td>Marius Gheorghe</td> <td>Naba Kumar</td> <td>Sean O'Dell</td> </tr><tr> <td>Stefanos Togoulidis</td> <td>Hans Hagen</td> <td>Jim Cape</td> <td>Roland Walter</td> </tr><tr> <td>Brian Mosher</td> <td>Nicholas Nemtsev</td> <td>Roy Wood</td> <td>Peter-Henry Mander</td> </tr><tr> <td>Robert Boucher</td> <td>Christoph Dalitz</td> <td>April White</td> <td>S. Umar</td> </tr><tr> <td>Trent Mick</td> <td>Filip Yaghob</td> <td>Avi Yegudin</td> <td>Vivi Orunitia</td> </tr><tr> <td>Manfred Becker</td> <td>Dimitris Keletsekis</td> <td>Yuiga</td> <td>Davide Scola</td> </tr><tr> <td>Jason Boggs</td> <td>Reinhold Niesner</td> <td>Jos van der Zande</td> <td>Pescuma</td> </tr><tr> <td>Pavol Bosik</td> <td>Johannes Schmid</td> <td>Blair McGlashan</td> <td>Mikael Hultgren</td> </tr><tr> <td>Florian Balmer</td> <td>Hadar Raz</td> <td>Herr Pfarrer</td> <td>Ben Key</td> </tr><tr> <td>Gene Barry</td> <td>Niki Spahiev</td> <td>Carsten Sperber</td> <td>Phil Reid</td> </tr><tr> <td>Iago Rubio</td> <td>Régis Vaquette</td> <td>Massimo Corà</td> <td>Elias Pschernig</td> </tr><tr> <td>Chris Jones</td> <td>Josiah Reynolds</td> <td>Robert Roessler <a href="http://www.rftp.com">rftp.com</a></td> <td>Steve Donovan</td> </tr><tr> <td>Jan Martin Pettersen</td> <td>Sergey Philippov</td> <td>Borujoa</td> <td>Michael Owens</td> </tr><tr> <td>Franck Marcia</td> <td>Massimo Maria Ghisalberti</td> <td>Frank Wunderlich</td> <td>Josepmaria Roca</td> </tr><tr> <td>Tobias Engvall</td> <td>Suzumizaki Kimitaka</td> <td>Michael Cartmell</td> <td>Pascal Hurni</td> </tr><tr> <td>Andre</td> <td>Randy Butler</td> <td>Georg Ritter</td> <td>Michael Goffioul</td> </tr><tr> <td>Ben Harper</td> <td>Adam Strzelecki</td> <td>Kamen Stanev</td> <td>Steve Menard</td> </tr><tr> <td>Oliver Yeoh</td> <td>Eric Promislow</td> <td>Joseph Galbraith</td> <td>Jeffrey Ren</td> </tr><tr> <td>Armel Asselin</td> <td>Jim Pattee</td> <td>Friedrich Vedder</td> <td>Sebastian Pipping</td> </tr><tr> <td>Andre Arpin</td> <td>Stanislav Maslovski</td> <td>Martin Stone</td> <td>Fabien Proriol</td> </tr><tr> <td>mimir</td> <td>Nicola Civran</td> <td>Snow</td> <td>Mitchell Foral</td> </tr><tr> <td>Pieter Holtzhausen</td> <td>Waldemar Augustyn</td> <td>Jason Haslam</td> <td>Sebastian Steinlechner</td> </tr><tr> <td>Chris Rickard</td> <td>Rob McMullen</td> <td>Stefan Schwendeler</td> <td>Cristian Adam</td> </tr><tr> <td>Nicolas Chachereau</td> <td>Istvan Szollosi</td> <td>Xie Renhui</td> <td>Enrico Tröger</td> </tr><tr> <td>Todd Whiteman</td> <td>Yuval Papish</td> <td>instanton</td> <td>Sergio Lucato</td> </tr><tr> <td>VladVRO</td> <td>Dmitry Maslov</td> <td>chupakabra</td> <td>Juan Carlos Arevalo Baeza</td> </tr><tr> <td>Nick Treleaven</td> <td>Stephen Stagg</td> <td>Jean-Paul Iribarren</td> <td>Tim Gerundt</td> </tr><tr> <td>Sam Harwell</td> <td>Boris</td> <td>Jason Oster</td> <td>Gertjan Kloosterman</td> </tr><tr> <td>alexbodn</td> <td>Sergiu Dotenco</td> <td>Anders Karlsson</td> <td>ozlooper</td> </tr><tr> <td>Marko Njezic</td> <td>Eugen Bitter</td> <td>Christoph Baumann</td> <td>Christopher Bean</td> </tr><tr> <td>Sergey Kishchenko</td> <td>Kai Liu</td> <td>Andreas Rumpf</td> <td>James Moffatt</td> </tr><tr> <td>Yuzhou Xin</td> <td>Nic Jansma</td> <td>Evan Jones</td> <td>Mike Lischke</td> </tr><tr> <td>Eric Kidd</td> <td>maXmo</td> <td>David Severwright</td> <td>Jon Strait</td> </tr><tr> <td>Oliver Kiddle</td> <td>Etienne Girondel</td> <td>Haimag Ren</td> <td>Andrey Moskalyov</td> </tr><tr> <td>Xavi</td> <td>Toby Inkster</td> <td>Eric Forgeot</td> <td>Colomban Wendling</td> </tr><tr> <td>Neo</td> <td>Jordan Russell</td> <td>Farshid Lashkari</td> <td>Sam Rawlins</td> </tr><tr> <td>Michael Mullin</td> <td>Carlos SS</td> <td>vim</td> <td>Martial Demolins</td> </tr><tr> <td>Tino Weinkauf</td> <td>Jérôme Laforge</td> <td>Udo Lechner</td> <td>Marco Falda</td> </tr><tr> <td>Dariusz Knociński</td> <td>Ben Fisher</td> <td>Don Gobin</td> <td>John Yeung</td> </tr><tr> <td>Adobe</td> <td>Elizabeth A. Irizarry</td> <td>Mike Schroeder</td> <td>Morten MacFly</td> </tr><tr> <td>Jaime Gimeno</td> <td>Thomas Linder Puls</td> <td>Artyom Zuikov</td> <td>Gerrit</td> </tr><tr> <td>Occam's Razor</td> <td>Ben Bluemel</td> <td>David Wolfendale</td> <td>Chris Angelico</td> </tr><tr> <td>Marat Dukhan</td> <td>Stefan Weil</td> <td>Rex Conn</td> <td>Ross McKay</td> </tr><tr> <td>Bruno Barbieri</td> <td>Gordon Smith</td> <td>dimitar</td> <td>Sébastien Granjoux</td> </tr><tr> <td>zeniko</td> <td>James Ribe</td> <td>Markus Nißl</td> <td>Martin Panter</td> </tr><tr> <td>Mark Yen</td> <td>Philippe Elsass</td> <td>Dimitar Zhekov</td> <td>Fan Yang</td> </tr><tr> <td>Denis Shelomovskij</td> <td>darmar</td> <td>John Vella</td> <td>Chinh Nguyen</td> </tr><tr> <td>Sakshi Verma</td> <td>Joel B. Mohler</td> <td>Isiledhel</td> <td>Vidya Wasi</td> </tr><tr> <td>G. Hu</td> <td>Byron Hawkins</td> <td>Alpha</td> </tr> </table> <p> Images used in GTK+ version </p> <ul> <li> <a href="http://sourceforge.net/projects/icon-collection/"> Icons</a> Copyright(C) 1998 by Dean S. Jones<br /> </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite330.zip?download">Release 3.3.0</a> </h3> <ul> <li> Released 30 March 2013. </li> <li> Overlay scrollers and kinetic scrolling implemented on Cocoa. </li> <li> To improve display smoothness, styling and UI Update notifications will, when possible, be performed in a high-priority idle task on Cocoa instead of during painting. Performing these jobs inside painting can cause paints to be abandoned and a new paint scheduled. On GTK+, the high-priority idle task is used in more cases. </li> <li> SCI_SCROLLRANGE added to scroll the view to display a range of text. If the whole range can not be displayed, priority is given to one end. </li> <li> C++ lexer no longer recognises raw (R"") strings when the first character after " is invalid. <a href="http://sourceforge.net/p/scintilla/bugs/1454/">Bug #1454.</a> </li> <li> HTML lexer recognises JavaScript RegEx literals in more contexts. <a href="http://sourceforge.net/p/scintilla/bugs/1412/">Bug #1412.</a> </li> <li> Fixed automatic display of folded text when return pressed at end of fold header and first folded line was blank. <a href="http://sourceforge.net/p/scintilla/bugs/1455/">Bug #1455.</a> </li> <li> SCI_VISIBLEFROMDOCLINE fixed to never return a line beyond the document end. </li> <li> SCI_LINESCROLL fixed for a negative column offset. <a href="http://sourceforge.net/p/scintilla/bugs/1450/">Bug #1450.</a> </li> <li> On GTK+, fix tab markers so visible if indent markers are visible. <a href="http://sourceforge.net/p/scintilla/bugs/1453/">Bug #1453.</a> </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite325.zip?download">Release 3.2.5</a> </h3> <ul> <li> Released 26 February 2013. </li> <li> To allow cooperation between different uses of extended (beyond 255) styles they should be allocated using SCI_ALLOCATEEXTENDEDSTYLES. </li> <li> For Unicode documents, lexers that use StyleContext will retrieve whole characters instead of bytes. LexAccessor provides a LineEnd method which can be a more efficient way to handle line ends and can enable Unicode line ends. </li> <li> The C++ lexer understands the #undef directive when determining preprocessor definitions. <a href="http://sourceforge.net/p/scintilla/feature-requests/978/">Feature #978.</a> </li> <li> The errorlist lexer recognises gcc include path diagnostics that appear before an error. </li> <li> Folding implemented for GetText (PO) translation language. <a href="http://sourceforge.net/p/scintilla/bugs/1437/">Bug #1437.</a> </li> <li> HTML lexer does not interrupt comment style for processing instructions. <a href="http://sourceforge.net/p/scintilla/bugs/1447/">Bug #1447.</a> </li> <li> Fix SciTE forgetting caret x-position when switching documents. <a href="http://sourceforge.net/p/scintilla/bugs/1442/">Bug #1442.</a> </li> <li> Fixed bug where vertical scrollbar thumb appeared at beginning of document when scrollbar shown. <a href="http://sourceforge.net/p/scintilla/bugs/1446/">Bug #1446.</a> </li> <li> Fixed brace-highlighting bug on OS X 10.8 where matching brace is on a different line. </li> <li> <a href="ScintillaDoc.html#ProvisionalMessages">Provisional features</a> are new features that may change or be removed if they cause problems but should become permanent if they work well. For this release <a href="ScintillaDoc.html#SCI_GETLINEENDTYPESSUPPORTED">Unicode line ends</a> and <a href="ScintillaDoc.html#Substyles">substyles</a> are provisional features. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite324.zip?download">Release 3.2.4</a> </h3> <ul> <li> Released 17 January 2013. </li> <li> Caret line highlight can optionally remain visible when window does not have focus. <a href="http://sourceforge.net/p/scintilla/feature-requests/964/">Feature #964.</a> </li> <li> Delegate mechanism for notifications added on Cocoa. </li> <li> NUL characters in selection are copied to clipboard as spaces to avoid truncating at the NUL. <a href="http://sourceforge.net/p/scintilla/bugs/1289/">Bug #1289.</a> </li> <li> C++ lexer fixes problem with showing inactive sections when preprocessor lines contain trailing comment. <a href="http://sourceforge.net/p/scintilla/bugs/1413/">Bug #1413.</a> </li> <li> C++ lexer fixes problem with JavaScript regular expressions with '/' in character ranges. <a href="http://sourceforge.net/p/scintilla/bugs/1415/">Bug #1415.</a> </li> <li> LaTeX folder added. <a href="http://sourceforge.net/p/scintilla/feature-requests/970/">Feature #970.</a> </li> <li> LaTeX lexer improves styling of math environments. <a href="http://sourceforge.net/p/scintilla/feature-requests/970/">Feature #970.</a> </li> <li> MySQL lexer implements hidden commands. </li> <li> Only produce a single undo step when autocompleting a single word. <a href="http://sourceforge.net/p/scintilla/bugs/1421/">Bug #1421.</a> </li> <li> Fixed crash when printing lines longer than 8000 characters. <a href="http://sourceforge.net/p/scintilla/bugs/1430/">Bug #1430.</a> </li> <li> Fixed problem in character movement extends selection mode where reversing direction collapsed the selection. </li> <li> Memory issues fixed on Cocoa, involving object ownership, lifetime of timers, and images held by the info bar. <a href="http://sourceforge.net/p/scintilla/bugs/1436/">Bug #1436.</a> </li> <li> Cocoa key binding for Alt+Delete changed to delete previous word to be more compatible with platform standards. </li> <li> Fixed crash on Cocoa with scrollbar when there is no scrolling possible. <a href="http://sourceforge.net/p/scintilla/bugs/1416/">Bug #1416.</a> </li> <li> On Cocoa with retina display fixed positioning of autocompletion lists. </li> <li> Fixed SciTE on Windows failure to run a batch file with a name containing a space by quoting the path in the properties file. <a href="http://sourceforge.net/p/scintilla/bugs/1423/">Bug #1423.</a> </li> <li> Fixed scaling bug when printing on GTK+. <a href="http://sourceforge.net/p/scintilla/bugs/1427/">Bug #1427.</a> </li> <li> SciTE on GTK toolbar.detachable feature removed. </li> <li> Fixed some background saving bugs in SciTE. <a href="http://sourceforge.net/p/scintilla/bugs/1366/">Bug #1366.</a> <a href="http://sourceforge.net/p/scintilla/bugs/1339/">Bug #1339.</a> </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite323.zip?download">Release 3.2.3</a> </h3> <ul> <li> Released 21 October 2012. </li> <li> Improve speed when performing multiple searches. </li> <li> SciTE adds definition of PLAT_UNIX for both PLAT_GTK and PLAT_MAC to allow consolidation of settings valid on all Unix variants. </li> <li> Signal autoCompleteCancelled added on Qt. </li> <li> Bash lexer supports nested delimiter pairs. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3569352&group_id=2439">Feature #3569352.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1515556&group_id=2439">Bug #1515556.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3008483&group_id=2439">Bug #3008483.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3512208&group_id=2439">Bug #3512208.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3515392&group_id=2439">Bug #3515392.</a> </li> <li> For C/C++, recognise exponent in floating point hexadecimal literals. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3576454&group_id=2439">Bug #3576454.</a> </li> <li> For C #include statements, do not treat // in the path as a comment. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3519260&group_id=2439">Bug #3519260.</a> </li> <li> Lexer for GetText translations (PO) improved with additional styles and single instance limitation fixed. </li> <li> Ruby for loop folding fixed. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3240902&group_id=2439">Bug #3240902.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3567391&group_id=2439">Bug #3567391.</a> </li> <li> Ruby recognition of here-doc after class or instance variable fixed. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3567809&group_id=2439">Bug #3567809.</a> </li> <li> SQL folding of loop and case fixed. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3567905&group_id=2439">Bug #3567905.</a> </li> <li> SQL folding of case with assignment fixed. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3571820&group_id=2439">Bug #3571820.</a> </li> <li> Fix hang when removing all characters from indicator at end of document. </li> <li> Fix failure of \xhh in regular expression search for values greater than 0x79. </li> <li> On Cocoa on OS X 10.8, fix inverted drawing of find indicator. </li> <li> On Cocoa, fix double drawing when horizontal scroll range small and user swipes horizontally. </li> <li> On Cocoa, remove incorrect setting of save point when reading information through 'string' and 'selectedString'. </li> <li> On Cocoa, fix incorrect memory managment of infoBar. </li> <li> On GTK+ 3 Ubuntu, fix crash when drawing margin. </li> <li> On ncurses, fix excessive spacing with italics line end. </li> <li> On Windows, search for D2D1.DLL and DWRITE.DLL in system directory to avoid loading from earlier in path where could be planted by malware. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite322.zip?download">Release 3.2.2</a> </h3> <ul> <li> Released 31 August 2012. </li> <li> Retina display support for Cocoa. Text size fixed. Scale factor for images implemented so they can be displayed in high definition. </li> <li> Implement INDIC_SQUIGGLEPIXMAP as a faster version of INDIC_SQUIGGLE. Avoid poor drawing at right of INDIC_SQUIGGLE. Align INDIC_DOTBOX to pixel grid for full intensity. </li> <li> Implement SCI_GETSELECTIONEMPTY API. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3543121&group_id=2439">Bug #3543121.</a> </li> <li> Added SCI_VCHOMEDISPLAY and SCI_VCHOMEDISPLAYEXTEND key commands. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3561433&group_id=2439">Feature #3561433.</a> </li> <li> Allow specifying SciTE Find in Files directory with find.in.directory property. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3558594&group_id=2439">Feature #3558594.</a> </li> <li> Override SciTE global strip.trailing.spaces with strip.trailing.spaces by pattern files. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3556320&group_id=2439">Feature #3556320.</a> </li> <li> Fix long XML script tag handling in XML lexer. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3534190&group_id=2439">Bug #3534190.</a> </li> <li> Fix rectangular selection range after backspace. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3543097&group_id=2439">Bug #3543097.</a> </li> <li> Send SCN_UPDATEUI with SC_UPDATE_SELECTION for backspace in virtual space. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3543121&group_id=2439">Bug #3543121.</a> </li> <li> Avoid problems when calltip highlight range is negative. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3545938&group_id=2439">Bug #3545938.</a> </li> <li> On Cocoa, fix image drawing code so that image is not accessed after being freed and is drawn in the correct location. </li> <li> On Cocoa, limit horizontal touch scrolling to existing established width. </li> <li> On Cocoa, decrease sensitivity of pinch-zoom. </li> <li> Fix Cocoa drawing where style changes were not immediately visible. </li> <li> Fix Cocoa memory leak due to reference cycle. </li> <li> Fix Cocoa bug where notifications were sent after Scintilla was freed. </li> <li> SciTE on OS X user shortcuts treats "Ctrl+D" as equivalent to "Ctrl+d". </li> <li> On Windows, saving SciTE's Lua startup script causes it to run. </li> <li> Limit time allowed to highlight current word in SciTE to 0.25 seconds to remain responsive. </li> <li> Fixed SciTE read-only mode to stick with buffer. </li> <li> For SciTE on Windows, enable Ctrl+Z, Ctrl+X, and Ctrl+C (Undo, Cut, and Copy) in the editable fields of find and replace strips </li> <li> Remove limit on logical line length in SciTE .properties files. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3544312&group_id=2439">Bug #3544312.</a> </li> <li> Improve performance of SciTE Save As command. </li> <li> Fix SciTE crash with empty .properties files. Bug #3545938. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3555308&group_id=2439">Bug #3555308.</a> </li> <li> Fix repeated letter in SciTE calltips. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3545938&group_id=2439">Bug #3545938.</a> </li> <li> Refine build time checking for Direct2D and DirectWrite. </li> <li> Avoid potential build problems on Windows with MultiMon.h by explicitly checking for multi-monitor APIs. </li> <li> Automatically disable themed drawing in SciTE when building on Windows 2000. Reenable building for Windows NT 4 on NT 4 . </li> <li> Added ncurses platform definitions. Implementation is maintained separately as <a href="http://foicica.com/scinterm/">Scinterm</a>. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite321.zip?download">Release 3.2.1</a> </h3> <ul> <li> Released 14 July 2012. </li> <li> In Scintilla.iface, specify features as properties instead of functions where possible and fix some enumerations. </li> <li> In SciTE Lua scripts, string properties in Scintilla API can be retrieved as well as set using property notation. </li> <li> Added character class APIs: SCI_SETPUNCTUATIONCHARS, SCI_GETWORDCHARS, SCI_GETWHITESPACECHARS, and SCI_GETPUNCTUATIONCHARS. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3529805&group_id=2439">Feature #3529805.</a> </li> <li> Less/Hss support added to CSS lexer. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3532413&group_id=2439">Feature #3532413.</a> </li> <li> C++ lexer style SCE_C_PREPROCESSORCOMMENT added for stream comments in preprocessor. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3487406&group_id=2439">Bug #3487406.</a> </li> <li> Fix incorrect styling of inactive code in C++ lexer. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3533036&group_id=2439">Bug #3533036.</a> </li> <li> Fix incorrect styling by C++ lexer after empty lines in preprocessor style. </li> <li> C++ lexer option "lexer.cpp.allow.dollars" fixed so can be turned off after being on. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3541461&group_id=2439">Bug #3541461.</a> </li> <li> Fortran fixed format lexer fixed to style comments from column 73. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3540486&group_id=2439">Bug #3540486.</a> </li> <li> Fortran folder folds CRITICAL .. END CRITICAL. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3540486&group_id=2439">Bug #3540486.</a> </li> <li> Fortran lexer fixes styling after comment line ending with '&'. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3087226&group_id=2439">Bug #3087226.</a> </li> <li> Fortran lexer styles preprocessor lines so they do not trigger incorrect folding. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2906275&group_id=2439">Bug #2906275.</a> </li> <li> Fortran folder fixes folding of nested ifs. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2809176&group_id=2439">Bug #2809176.</a> </li> <li> HTML folder fixes folding of CDATA when fold.html.preprocessor=0. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3540491&group_id=2439">Bug #3540491.</a> </li> <li> On Cocoa, fix autocompletion font lifetime issue and row height computation. </li> <li> In 'choose single' mode, autocompletion will close an existing list if asked to display a single entry list. </li> <li> Fixed SCI_MARKERDELETE to only delete one marker per call. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3535806&group_id=2439">Bug #3535806.</a> </li> <li> Properly position caret after undoing coalesced delete operations. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3523326&group_id=2439">Bug #3523326.</a> </li> <li> Ensure margin is redrawn when SCI_MARGINSETSTYLE called. </li> <li> Fix clicks in first pixel of margins to send SCN_MARGINCLICK. </li> <li> Fix infinite loop when drawing block caret for a zero width space character at document start. </li> <li> Crash fixed for deleting negative range. </li> <li> For characters that overlap the beginning of their space such as italics descenders and bold serifs, allow start of text to draw 1 pixel into margin. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=699587&group_id=2439">Bug #699587.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3537799&group_id=2439">Bug #3537799.</a> </li> <li> Fixed problems compiling Scintilla for Qt with GCC 4.7.1 x64. </li> <li> Fixed problem with determining GTK+ sub-platform caused when adding Qt support in 3.2.0. </li> <li> Fix incorrect measurement of untitled file in SciTE on Linux leading to message "File ...' is 2147483647 bytes long". <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3537764&group_id=2439">Bug #3537764.</a> </li> <li> In SciTE, fix open of selected filename with line number to go to that line. </li> <li> Fix problem with last visible buffer closing in SciTE causing invisible buffers to be active. </li> <li> Avoid blinking of SciTE's current word highlight when output pane changes. </li> <li> SciTE properties files can be longer than 60K. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite320.zip?download">Release 3.2.0</a> </h3> <ul> <li> Released 1 June 2012. </li> <li> Platform layer added for the Qt open-source cross-platform application and user interface framework for development in C++ or in Python with the PySide bindings for Qt. </li> <li> Direct access provided to the document bytes for ranges within Scintilla. This is similar to the existing SCI_GETCHARACTERPOINTER API but allows for better performance. </li> <li> Ctrl+Double Click and Ctrl+Triple Click add the word or line to the set of selections. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3520037&group_id=2439">Feature #3520037.</a> </li> <li> A SCI_DELETERANGE API was added for deleting a range of text. </li> <li> Line wrap markers may now be drawn in the line number margin. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3518198&group_id=2439">Feature #3518198.</a> </li> <li> SciTE on OS X adds option to hide hidden files in the open dialog box. </li> <li> Lexer added for OScript language. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3523197&group_id=2439">Feature #3523197.</a> </li> <li> Lexer added for Visual Prolog language. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3523018&group_id=2439">Feature #3523018.</a> </li> <li> UTF-8 validity is checked more stringently and consistently. All 66 non-characters are now treated as invalid. </li> <li> HTML lexer bug fixed with inconsistant highlighting for PHP when attribute on separate line from tag. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3520027&group_id=2439">Bug #3520027.</a> </li> <li> HTML lexer bug fixed for JavaScript block comments. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3520032&group_id=2439">Bug #3520032.</a> </li> <li> Annotation drawing bug fixed when box displayed with different colours on different lines. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3519872&group_id=2439">Bug #3519872.</a> </li> <li> On Windows with Direct2D, fix drawing with 125% and 150% DPI system settings. </li> <li> Virtual space selection bug fixed for rectangular selections. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3519246&group_id=2439">Bug #3519246.</a> </li> <li> Replacing multiple selection with newline changed to only affect main selection. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3522251&group_id=2439">Bug #3522251.</a> </li> <li> Replacing selection with newline changed to group deletion and insertion as a single undo action. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3522250&group_id=2439">Bug #3522250.</a> </li> <li> Auto-completion lists on GTK+ 3 set height correctly instead of showing too few lines. </li> <li> Mouse wheel scrolling changed to avoid GTK+ bug in recent distributions. </li> <li> IME bug on Windows fixed for horizontal jump. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3529728&group_id=2439">Bug #3529728.</a> </li> <li> SciTE case-insensitive autocompletion filters equal identifiers better. Calltip arrows work with bare word identifiers. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3517810&group_id=2439">Bug #3517810.</a> </li> <li> SciTE bug fixed where shbang lines not setting file type when switching to file loaded in background. </li> <li> SciTE on GTK+ shows open and save dialogs with the directory of the current file displayed. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite310.zip?download">Release 3.1.0</a> </h3> <ul> <li> Released 20 April 2012. </li> <li> Animated find indicator added on Cocoa. </li> <li> Buttons can be made default in SciTE user strips. </li> <li> SciTE allows find and replace histories to be saved in session. </li> <li> Option added to allow case-insensitive selection in auto-completion lists. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3516538&group_id=2439">Bug #3516538.</a> </li> <li> Replace \0 by complete found text in regular expressions. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3510979&group_id=2439">Feature #3510979.</a> </li> <li> Fixed single quoted strings in bash lexer. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3512208&group_id=2439">Bug #3512208.</a> </li> <li> Incorrect highlighting fixed in C++ lexer for continued lines. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3509317&group_id=2439">Bug #3509317.</a> </li> <li> Hang fixed in diff lexer. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3508602&group_id=2439">Bug #3508602.</a> </li> <li> Folding improved for SQL CASE/MERGE statement. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3503277&group_id=2439">Bug #3503277.</a> </li> <li> Fix extra drawing of selection inside word wrap indentation. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3515555&group_id=2439">Bug #3515555.</a> </li> <li> Fix problem with determining the last line that needs styling when drawing. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3514882&group_id=2439">Bug #3514882.</a> </li> <li> Fix problems with drawing in margins. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3514882&group_id=2439">Bug #3514882.</a> </li> <li> Fix printing crash when using Direct2D to display on-screen. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3513946&group_id=2439">Bug #3513946.</a> </li> <li> Fix SciTE bug where background.*.size disabled restoration of bookmarks and positions from session. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3514885&group_id=2439">Bug #3514885.</a> </li> <li> Fixed the Move Selected Lines command when last line does not end with a line end character. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3511023&group_id=2439">Bug #3511023.</a> </li> <li> Fix word wrap indentation printing to use printer settings instead of screen settings. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3512961&group_id=2439">Bug #3512961.</a> </li> <li> Fix SciTE bug where executing an empty command prevented executing further commands <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3512976&group_id=2439">Bug #3512976.</a> </li> <li> Fix SciTE bugs with focus in user strips and made strips more robust with invalid definitions. </li> <li> Suppress SciTE regular expression option when searching with find next selection. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3510985&group_id=2439">Bug #3510985.</a> </li> <li> SciTE Find in Files command matches empty pattern to all files. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3495918&group_id=2439">Feature #3495918.</a> </li> <li> Fix scroll with mouse wheel on GTK+. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3501321&group_id=2439">Bug #3501321.</a> </li> <li> Fix column finding method so that tab is counted correctly. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3483713&group_id=2439">Bug #3483713.</a> </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite304.zip?download">Release 3.0.4</a> </h3> <ul> <li> Released 8 March 2012. </li> <li> SciTE scripts can create user interfaces as strips. </li> <li> SciTE can save files automatically in the background. </li> <li> Pinch zoom implemented on Cocoa. </li> <li> ECL lexer added. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3488209&group_id=2439">Feature #3488209.</a> </li> <li> CPP lexer fixes styling after document comment keywords. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3495445&group_id=2439">Bug #3495445.</a> </li> <li> Pascal folder improves handling of some constructs. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3486385&group_id=2439">Feature #3486385.</a> </li> <li> XML lexer avoids entering a bad mode due to complex preprocessor instructions. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3488060&group_id=2439">Bug #3488060.</a> </li> <li> Duplicate command is always remembered as a distinct command for undo. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3495836&group_id=2439">Bug #3495836.</a> </li> <li> SciTE xml.auto.close.tags no longer closes with PHP code similar to <a $this-> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3488067&group_id=2439">Bug #3488067.</a> </li> <li> Fix bug where setting an indicator for the whole document would fail. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3487440&group_id=2439">Bug #3487440.</a> </li> <li> Crash fixed for SCI_MOVESELECTEDLINESDOWN with empty vertical selection. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3496403&group_id=2439">Bug #3496403.</a> </li> <li> Differences between buffered and unbuffered mode on Direct2D eliminated. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3495791&group_id=2439">Bug #3495791.</a> </li> <li> Font leading implemented for Direct2D to improve display of character blobs. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3494744&group_id=2439">Bug #3494744.</a> </li> <li> Fractional widths used for line numbers, character markers and other situations. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3494492&group_id=2439">Bug #3494492.</a> </li> <li> Translucent rectangles drawn using Direct2D with sharper corners. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3494492&group_id=2439">Bug #3494492.</a> </li> <li> RGBA markers drawn sharper when centred using Direct2D. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3494202&group_id=2439">Bug #3494202.</a> </li> <li> RGBA markers are drawn centred when taller than line. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3494184&group_id=2439">Bug #3494184.</a> </li> <li> Image marker drawing problem fixed for markers taller than line. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3493503&group_id=2439">Bug #3493503.</a> </li> <li> Markers are drawn horizontally off-centre based on margin type instead of dimensions. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3488696&group_id=2439">Bug #3488696.</a> </li> <li> Fold tail markers drawn vertically centred. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3488289&group_id=2439">Feature #3488289.</a> </li> <li> On Windows, Scintilla is more responsive in wrap mode. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3487397&group_id=2439">Bug #3487397.</a> </li> <li> Unimportant "Gdk-CRITICAL" messages are no longer displayed. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3488481&group_id=2439">Bug #3488481.</a> </li> <li> SciTE on Windows Find in Files sets focus to dialog when already created; allows opening dialog when a job is running. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3480635&group_id=2439">Bug #3480635.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3486657&group_id=2439">Bug #3486657.</a> </li> <li> Fixed problems with multiple clicks in margin and with mouse actions combined with virtual space. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3484370&group_id=2439">Bug #3484370.</a> </li> <li> Fixed bug with using page up and down and not returning to original line. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3485669&group_id=2439">Bug #3485669.</a> </li> <li> Down arrow with wrapped text no longer skips lines. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1776560&group_id=2439">Bug #1776560.</a> </li> <li> Fix problem with dwell ending immediately due to word wrap. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3484416&group_id=2439">Bug #3484416.</a> </li> <li> Wrapped lines are rewrapped more consistently while resizing window. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3484179&group_id=2439">Bug #3484179.</a> </li> <li> Selected line ends are highlighted more consistently. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3484330&group_id=2439">Bug #3484330.</a> </li> <li> Fix grey background on files that use shbang to choose language. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3482777&group_id=2439">Bug #3482777.</a> </li> <li> Fix failure messages from empty commands in SciTE. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3480645&group_id=2439">Bug #3480645.</a> </li> <li> Redrawing reduced for some marker calls. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3493530&group_id=2439">Feature #3493530.</a> </li> <li> Match brace and select brace commands work in SciTE output pane. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3486598&group_id=2439">Feature #3486598.</a> </li> <li> Performing SciTE "Show Calltip" command when a calltip is already visible shows the next calltip. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3487017&group_id=2439">Feature #3487017.</a> </li> <li> SciTE allows saving file even when file unchanged. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3486654&group_id=2439">Feature #3486654.</a> </li> <li> SciTE allows optional use of character escapes in calltips. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3495239&group_id=2439">Feature #3495239.</a> </li> <li> SciTE can open file:// URLs with Ctrl+Shift+O. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3495389&group_id=2439">Feature #3495389.</a> </li> <li> Key modifiers updated for GTK+ on OS X to match upstream changes. </li> <li> SciTE hang when marking all occurrences of regular expressions fixed. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite303.zip?download">Release 3.0.3</a> </h3> <ul> <li> Released 28 January 2012. </li> <li> Printing works on GTK+ version 2.x as well as 3.x. </li> <li> Lexer added for the AviSynth language. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3475611&group_id=2439">Feature #3475611.</a> </li> <li> Lexer added for the Take Command / TCC scripting language. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3462462&group_id=2439">Feature #3462462.</a> </li> <li> CSS lexer gains support for SCSS. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3268017&group_id=2439">Feature #3268017.</a> </li> <li> CPP lexer fixes problems in the preprocessor structure caused by continuation lines. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3458508&group_id=2439">Bug #3458508.</a> </li> <li> Errorlist lexer handles column numbers for GCC format diagnostics. In SciTE, Next Message goes to column where this can be decoded from GCC format diagnostics. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3453075&group_id=2439">Feature #3453075.</a> </li> <li> HTML folder fixes spurious folds on some tags. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3459262&group_id=2439">Bug #3459262.</a> </li> <li> Ruby lexer fixes bug where '=' at start of file caused whole file to appear as a comment. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3452488&group_id=2439">Bug #3452488.</a> </li> <li> SQL folder folds blocks of single line comments. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3467425&group_id=2439">Feature #3467425.</a> </li> <li> On Windows using Direct2D, defer invalidation of render target until completion of painting to avoid failures. </li> <li> Further support of fractional positioning. Spaces, tabs, and single character tokens can take fractional space and wrapped lines are positioned taking fractional positions into account. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3471998&group_id=2439">Bug #3471998.</a> </li> <li> On Windows using Direct2D, fix extra carets appearing. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3471998&group_id=2439">Bug #3471998.</a> </li> <li> For autocompletion lists Page Up and Down move by the list height instead of by 5 lines. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3455493&group_id=2439">Bug #3455493.</a> </li> <li> For SCI_LINESCROLLDOWN/UP don't select into virtual space. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3451681&group_id=2439">Bug #3451681.</a> </li> <li> Fix fold highlight not being fully drawn. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3469936&group_id=2439">Bug #3469936.</a> </li> <li> Fix selection margin appearing black when starting in wrap mode. </li> <li> Fix crash when changing end of document after adding an annotation. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3476637&group_id=2439">Bug #3476637.</a> </li> <li> Fix problems with building to make RPMs. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3476149&group_id=2439">Bug #3476149.</a> </li> <li> Fix problem with building on GTK+ where recent distributions could not find gmodule. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3469056&group_id=2439">Bug #3469056.</a> </li> <li> Fix problem with installing SciTE on GTK+ due to icon definition in .desktop file including an extension. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3476117&group_id=2439">Bug #3476117.</a> </li> <li> Fix SciTE bug where new buffers inherited some properties from previously opened file. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3457060&group_id=2439">Bug #3457060.</a> </li> <li> Fix focus when closing tab in SciTE with middle click. Focus moves to edit pane instead of staying on tab bar. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3440142&group_id=2439">Bug #3440142.</a> </li> <li> For SciTE on Windows fix bug where Open Selected Filename for URL would append a file extension. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3459185&group_id=2439">Feature #3459185.</a> </li> <li> For SciTE on Windows fix key handling of control characters in Parameters dialog so normal editing (Ctrl+C, ...) works. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3459345&group_id=2439">Bug #3459345.</a> </li> <li> Fix SciTE bug where files became read-only after saving. Drop the "*" dirty marker after save completes. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3467432&group_id=2439">Bug #3467432.</a> </li> <li> For SciTE handling of diffs with "+++" and "---" lines, also handle case where not followed by tab. Go to correct line for diff "+++" message. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3467143&group_id=2439">Bug #3467143.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3467178&group_id=2439">Bug #3467178.</a> </li> <li> SciTE on GTK+ now performs threaded actions even on GTK+ versions before 2.12. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite302.zip?download">Release 3.0.2</a> </h3> <ul> <li> Released 9 December 2011. </li> <li> SciTE saves files in the background without blocking the user interface. </li> <li> Printing implemented in SciTE on GTK+ 3.x. </li> <li> ILoader interface for background loading finalised and documented. </li> <li> CoffeeScript lexer added. </li> <li> C++ lexer fixes crash with "#if defined( XXX 1". </li> <li> Crash with Direct2D on Windows fixed. </li> <li> Backspace removing protected range fixed. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3445911&group_id=2439">Bug #3445911.</a> </li> <li> Cursor setting failure on Windows when screen saver on fixed. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3438780&group_id=2439">Bug #3438780.</a> </li> <li> SciTE on GTK+ hang fixed with -open:file option. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3441980&group_id=2439">Bug #3441980.</a> </li> <li> Failure to evaluate shbang fixed in SciTE. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3441801&group_id=2439">Bug #3441801.</a> </li> <li> SciTE failure to treat files starting with "<?xml" as XML fixed. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3440718&group_id=2439">Bug #3440718.</a> </li> <li> Made untitled tab saveable when created by closing all files. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3440244&group_id=2439">Bug #3440244.</a> </li> <li> SciTE crash fixed when using Scintillua. </li> <li> SciTE revert command fixed so that undo works on individual actions instead of undoing to revert point. </li> <li> Focus loss in SciTE when opening a recent file fixed. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3440142&group_id=2439">Bug #3440142.</a> </li> <li> Fixed SciTE SelLength property to measure characters instead of bytes. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3283519&group_id=2439">Bug #3283519.</a> </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite301.zip?download">Release 3.0.1</a> </h3> <ul> <li> Released 15 November 2011. </li> <li> SciTE on Windows now runs Lua scripts directly on the main thread instead of starting them on a secondary thread and then moving back to the main thread. </li> <li> Highlight "else" as a keyword for TCL in the same way as other languages. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1836954&group_id=2439">Bug #1836954.</a> </li> <li> Fix problems with setting fonts for autocompletion lists on Windows where font handles were copied and later deleted causing a system default font to be used. </li> <li> Fix font size used on Windows for Asian language input methods which sometimes led to IME not being visible. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3436753&group_id=2439">Bug #3436753.</a> </li> <li> Fixed polygon drawing on Windows so fold symbols are visible again. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3433558&group_id=2439">Bug #3433558.</a> </li> <li> Changed background drawing on GTK+ to allow for fractional character positioning as occurs on OS X as this avoids faint lines at lexeme boundaries. </li> <li> Ensure pixmaps allocated before painting as there was a crash when Scintilla drew without common initialisation calls. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3432354&group_id=2439">Bug #3432354.</a> </li> <li> Fixed SciTE on Windows bug causing wrong caret position after indenting a selection. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3433433&group_id=2439">Bug #3433433.</a> </li> <li> Fixed SciTE session saving to store buffer position matching buffer. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3434372&group_id=2439">Bug #3434372.</a> </li> <li> Fixed leak of document objects in SciTE. </li> <li> Recognise URL characters '?' and '%' for Open Selected command in SciTE. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3429409&group_id=2439">Bug #3429409.</a> </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite300.zip?download">Release 3.0.0</a> </h3> <ul> <li> Released 1 November 2011. </li> <li> Carbon platform support removed. OS X applications should switch to Cocoa. </li> <li> On Windows Vista or newer, drawing may be performed with Direct2D and DirectWrite instead of GDI. </li> <li> Cairo is now used for all drawing on GTK+. GDK drawing was removed. </li> <li> Paletted display support removed. </li> <li> Fractional font sizes can be specified. </li> <li> Different weights of text supported on some platforms instead of just normal and bold. </li> <li> Sub-pixel character positioning supported. </li> <li> SciTE loads files in the background without blocking the user interface. </li> <li> SciTE can display diagnostic messages interleaved with the text of files immediately after the line referred to by the diagnostic. </li> <li> New API to see if all lines are visible which can be used to optimize processing fold structure notifications. </li> <li> Scrolling optimized by avoiding invalidation of fold margin when redrawing whole window. </li> <li> Optimized SCI_MARKERNEXT. </li> <li> C++ lexer supports Pike hash quoted strings when turned on with lexer.cpp.hashquoted.strings. </li> <li> Fixed incorrect line height with annotations in wrapped mode when there are multiple views. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3388159&group_id=2439">Bug #3388159.</a> </li> <li> Calltips may be displayed above the text as well as below. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3410830&group_id=2439">Bug #3410830.</a> </li> <li> For huge files SciTE only examines the first megabyte for newline discovery. </li> <li> SciTE on GTK+ removes the fileselector.show.hidden property and check box as this was buggy and GTK+ now supports an equivalent feature. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3413630&group_id=2439">Bug #3413630.</a> </li> <li> SciTE on GTK+ supports mnemonics in dynamic menus. </li> <li> SciTE on GTK+ displays the user's home directory as '~' in menus to make them shorter. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite229.zip?download">Release 2.29</a> </h3> <ul> <li> Released 16 September 2011. </li> <li> To automatically discover the encoding of a file when opening it, SciTE can run a program set with command.discover.properties. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3324341&group_id=2439">Feature #3324341.</a> </li> <li> Cairo always used for drawing on GTK+. </li> <li> The set of properties files imported by SciTE can be controlled with the properties imports.include and imports.exclude. The import statement has been extended to allow "import *". The properties files for some languages are no longer automatically loaded by default. The properties files affected are avenue, baan, escript, lot, metapost, and mmixal. </li> <li> C++ lexer fixed a bug with raw strings being recognised too easily. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3388122&group_id=2439">Bug #3388122.</a> </li> <li> LaTeX lexer improved with more states and fixes to most outstanding bugs. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1493111&group_id=2439">Bug #1493111.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1856356&group_id=2439">Bug #1856356.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3081692&group_id=2439">Bug #3081692.</a> </li> <li> Lua lexer updates for Lua 5.2 beta with goto labels and "\z" string escape. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3386330&group_id=2439">Feature #3386330.</a> </li> <li> Perl string styling highlights interpolated variables. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3394258&group_id=2439">Feature #3394258.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3076629&group_id=2439">Bug #3076629.</a> </li> <li> Perl lexer updated for Perl 5.14.0 with 0X and 0B numeric literal prefixes, break keyword and "+" supported in subroutine prototypes. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3388802&group_id=2439">Feature #3388802.</a> </li> <li> Perl bug fixed with CRLF line endings. </li> <li> Markdown lexer fixed to not change state with "_" in middle of word. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3398184&group_id=2439">Bug #3398184.</a> </li> <li> Cocoa restores compatibility with OS X 10.5. </li> <li> Mouse pointer changes over selection to an arrow near start when scrolled horizontally. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3389055&group_id=2439">Bug #3389055.</a> </li> <li> Indicators that finish at the end of the document no longer expand when text is appended. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3378718&group_id=2439">Bug #3378718.</a> </li> <li> SparseState merge fixed to check if other range is empty. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3387053&group_id=2439">Bug #3387053.</a> </li> <li> On Windows, autocompletion lists will scroll instead of document when mouse wheel spun. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3403600&group_id=2439">Feature #3403600.</a> </li> <li> SciTE performs more rapid polling for command completion so will return faster and report more accurate times. </li> <li> SciTE resizes panes proportionally when switched between horizontal and vertical layout. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3376784&group_id=2439">Feature #3376784.</a> </li> <li> SciTE on GTK+ opens multiple files into a single instance more reliably. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3363754&group_id=2439">Bug #3363754.</a> </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite228.zip?download">Release 2.28</a> </h3> <ul> <li> Released 1 August 2011. </li> <li> GTK+ Cairo support works back to GTK+ version 2.8. Requires changing Scintilla source code to enable before GTK+ 2.22. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3322351&group_id=2439">Bug #3322351.</a> </li> <li> Translucent images in RGBA format can be used for margin markers and in autocompletion lists. </li> <li> INDIC_DOTBOX added as a translucent dotted rectangular indicator. </li> <li> Asian text input using IME works for GTK+ 3.x and GTK+ 2.x with Cairo. </li> <li> On GTK+, IME works for Ctrl+Shift+U Unicode input in Scintilla. For SciTE, Ctrl+Shift+U is still Make Selection Uppercase. </li> <li> Key bindings for GTK+ on OS X made compatible with Cocoa port and platform conventions. </li> <li> Cocoa port supports different character encodings, improves scrolling performance and drag image appearance. The control ID is included in WM_COMMAND notifications. Text may be deleted by dragging to the trash. ScrollToStart and ScrollToEnd key commands added to simplify implementation of standard OS X Home and End behaviour. </li> <li> SciTE on GTK+ uses a paned widget to contain the edit and output panes instead of custom code. This allows the divider to be moved easily on GTK+ 3 and its appearance follows GTK+ conventions more closely. </li> <li> SciTE builds and installs on BSD. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3324644&group_id=2439">Bug #3324644.</a> </li> <li> Cobol supports fixed format comments. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3014850&group_id=2439">Bug #3014850.</a> </li> <li> Mako template language block syntax extended and ## comments recognised. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3325178&group_id=2439">Feature #3325178.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3318818&group_id=2439">Bug #3318818.</a> </li> <li> Folding of Mako template language within HTML fixed. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3324563&group_id=2439">Bug #3324563.</a> </li> <li> Python lexer has lexer.python.keywords2.no.sub.identifiers option to avoid highlighting second set of keywords following '.'. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3325333&group_id=2439">Bug #3325333.</a> </li> <li> Python folder fixes bug where fold would not extend to final line. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3349157&group_id=2439">Bug #3349157.</a> </li> <li> SciTE treats LPEG lexers the same as script lexers by setting all 8 style bits. </li> <li> For Cocoa, crashes with unsupported font variants and memory leaks for colour objects fixed. </li> <li> Shift-JIS lead byte ranges modified to match Windows. </li> <li> Mouse pointer changes over selection to an arrow more consistently. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3315756&group_id=2439">Bug #3315756.</a> </li> <li> Bug fixed with annotations beyond end of document. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3347268&group_id=2439">Bug #3347268.</a> </li> <li> Incorrect drawing fixed for combination of background colour change and translucent selection. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3377116&group_id=2439">Bug #3377116.</a> </li> <li> Lexers initialized correctly when started at position other than start of line. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3377148&group_id=2439">Bug #3377148.</a> </li> <li> Fold highlight drawing fixed for some situations. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3323015&group_id=2439">Bug #3323015.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3323805&group_id=2439">Bug #3323805.</a> </li> <li> Case insensitive search fixed for cases where folded character uses fewer bytes than base character. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3362038&group_id=2439">Bug #3362038.</a> </li> <li> SciTE bookmark.alpha setting fixed. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3373907&group_id=2439">Bug #3373907.</a> </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite227.zip?download">Release 2.27</a> </h3> <ul> <li> Released 20 June 2011. </li> <li> On recent GTK+ 2.x versions when using Cairo, bug fixed where wrong colours were drawn. </li> <li> SciTE on GTK+ slow performance in menu maintenance fixed. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3315233&group_id=2439">Bug #3315233.</a> </li> <li> Cocoa platform supports 64-bit builds and uses only non-deprecated APIs. Asian Input Method Editors are supported. Autocompletion lists and calltips implemented. Control identifier used in notifications. </li> <li> On Cocoa, rectangular selection now uses Option/Alt key to be compatible with Apple Human Interface Guidelines and other applications. The Control key is reported with an SCMOD_META modifier bit. </li> <li> API added for setting and retrieving the identifier number used in notifications. </li> <li> SCI_SETEMPTYSELECTION added to set selection without scrolling or redrawing more than needed. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3314877&group_id=2439">Feature #3314877.</a> </li> <li> Added new indicators. INDIC_DASH and INDIC_DOTS are variants of underlines. INDIC_SQUIGGLELOW indicator added as shorter alternative to INDIC_SQUIGGLE for small fonts. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3314591&group_id=2439">Bug #3314591</a> </li> <li> Margin line selection can be changed to select display lines instead of document lines. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3312763&group_id=2439">Bug #3312763.</a> </li> <li> On Windows, SciTE can perform reverse searches by pressing Shift+Enter in the Find or Replace strips or dialogs. </li> <li> Matlab lexer does not special case '\' in single quoted strings. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=948757&group_id=2439">Bug #948757</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1755950&group_id=2439">Bug #1755950</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1888738&group_id=2439">Bug #1888738</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3316852&group_id=2439">Bug #3316852.</a> </li> <li> Verilog lexer supports SystemVerilog folding and keywords. </li> <li> Font leak fixed. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3306156&group_id=2439">Bug #3306156.</a> </li> <li> Automatic scrolling works for long wrapped lines. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3312763&group_id=2439">Bug #3312763.</a> </li> <li> Multiple typing works for cases where selections collapse together. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3309906&group_id=2439">Bug #3309906.</a> </li> <li> Fold expanded when needed in word wrap mode. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3291579&group_id=2439">Bug #3291579.</a> </li> <li> Bug fixed with edge drawn in wrong place on wrapped lines. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3314807&group_id=2439">Bug #3314807.</a> </li> <li> Bug fixed with unnecessary scrolling for SCI_GOTOLINE. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3303406&group_id=2439">Bug #3303406.</a> </li> <li> Bug fixed where extra step needed to undo SCI_CLEAR in virtual space. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3159691&group_id=2439">Bug #3159691.</a> </li> <li> Regular expression search fixed for \$ on last line of search range. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3313746&group_id=2439">Bug #3313746.</a> </li> <li> SciTE performance improved when switching to a tab with a very large file. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3311421&group_id=2439">Bug #3311421.</a> </li> <li> On Windows, SciTE advanced search remembers the "Search only in this style" setting. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3313344&group_id=2439">Bug #3313344.</a> </li> <li> On GTK+, SciTE opens help using "xdg-open" instead of "netscape" as "netscape" no longer commonly installed. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3314377&group_id=2439">Bug #3314377.</a> </li> <li> SciTE script lexers can use 256 styles. </li> <li> SciTE word highlight works for words containing DBCS characters. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3315173&group_id=2439">Bug #3315173.</a> </li> <li> Compilation fixed for wxWidgets. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3306156&group_id=2439">Bug #3306156.</a> </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite226.zip?download">Release 2.26</a> </h3> <ul> <li> Released 25 May 2011. </li> <li> Folding margin symbols can be highlighted for the current folding block. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3147069&group_id=2439">Feature #3147069.</a> </li> <li> Selected lines can be moved up or down together. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3304850&group_id=2439">Feature #3304850.</a> </li> <li> SciTE can highlight all occurrences of the current word or selected text. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3291636&group_id=2439">Feature #3291636.</a> </li> <li> Experimental GTK+ 3.0 support: build with "make GTK3=1". </li> <li> INDIC_STRAIGHTBOX added. Is similar to INDIC_ROUNDBOX but without rounded corners. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3290435&group_id=2439">Bug #3290435.</a> </li> <li> Can show brace matching and mismatching with indicators instead of text style. Translucency of outline can be altered for INDIC_ROUNDBOX and INDIC_STRAIGHTBOX. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3290434&group_id=2439">Feature #3290434.</a> </li> <li> SciTE can automatically indent python by examining previous line for scope-starting ':' with indent.python.colon. </li> <li> Batch file lexer allows braces '(' or ')' inside variable names. </li> <li> The cpp lexer only recognises Vala triple quoted strings when lexer.cpp.triplequoted.strings property is set. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3239234&group_id=2439">Bug #3239234.</a> </li> <li> Make file lexer treats a variable with a nested variable like $(f$(qx)b) as one variable. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3298223&group_id=2439">Bug #3298223.</a> </li> <li> Folding bug fixed for JavaScript with nested PHP. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3193530&group_id=2439">Bug #3193530.</a> </li> <li> HTML lexer styles Django's {# #} comments. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3013798&group_id=2439">Bug #3013798.</a> </li> <li> HTML lexer styles JavaScript regular expression correctly for /abc/i.test('abc');. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3209108&group_id=2439">Bug #3209108.</a> </li> <li> Inno Setup Script lexer now works properly when it restarts from middle of [CODE] section. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3283880&group_id=2439">Bug #3283880.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3129044&group_id=2439">Bug #3129044.</a> </li> <li> Lua lexer updated for Lua 5.2 with hexadecimal floating-point numbers and '\*' whitespace escaping in strings. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3243811&group_id=2439">Feature #3243811.</a> </li> <li> Perl folding folds "here doc"s and adds options fold.perl.at.else and fold.perl.comment.explicit. Fold structure for Perl fixed. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3112671&group_id=2439">Feature #3112671.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3265401&group_id=2439">Bug #3265401.</a> </li> <li> Python lexer supports cpdef keyword for Cython. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3279728&group_id=2439">Bug #3279728.</a> </li> <li> SQL folding option lexer.sql.fold.at.else renamed to fold.sql.at.else. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3271474&group_id=2439">Bug #3271474.</a> </li> <li> SQL lexer no longer treats ';' as terminating a comment. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3196071&group_id=2439">Bug #3196071.</a> </li> <li> Text drawing and measurement segmented into smaller runs to avoid platform bugs. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3277449&group_id=2439">Bug #3277449.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3165743&group_id=2439">Bug #3165743.</a> </li> <li> SciTE on Windows adds temp.files.sync.load property to open dropped temporary files synchronously as they may be removed before they can be opened asynchronously. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3072009&group_id=2439">Bug #3072009.</a> </li> <li> Bug fixed with indentation guides ignoring first line in SC_IV_LOOKBOTH mode. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3291317&group_id=2439">Bug #3291317.</a> </li> <li> Bugs fixed in backward regex search. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3292659&group_id=2439">Bug #3292659.</a> </li> <li> Bugs with display of folding structure fixed for wrapped lines and where there is a fold header but no body. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3291579&group_id=2439">Bug #3291579.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3265401&group_id=2439">Bug #3265401.</a> </li> <li> SciTE on Windows cursor changes to an arrow now when over horizontal splitter near top of window. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3286620&group_id=2439">Bug #3286620.</a> </li> <li> Fixed default widget size problem on GTK+. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3267892&group_id=2439">Bug #3267892.</a> </li> <li> Fixed font size when using Cairo on GTK+. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3272662&group_id=2439">Bug #3272662.</a> </li> <li> Fixed primary selection and cursor issues on GTK+ when unrealized then realized. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3256153&group_id=2439">Bug #3256153.</a> </li> <li> Right click now cancels selection on GTK+ like on Windows. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3235190&group_id=2439">Bug #3235190.</a> </li> <li> SciTE on GTK+ implements z-order buffer switching like on Windows. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3228384&group_id=2439">Bug #3228384.</a> </li> <li> Improve selection position after SciTE Insert Abbreviation command when abbreviation expansion includes '|'. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite225.zip?download">Release 2.25</a> </h3> <ul> <li> Released 21 March 2011. </li> <li> SparseState class makes it easier to write lexers which have to remember complex state between lines. </li> <li> Visual Studio project (.dsp) files removed. The make files should be used instead as described in the README. </li> <li> Modula 3 lexer added along with SciTE support. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3173374&group_id=2439">Feature #3173374.</a> </li> <li> Asm, Basic, and D lexers add extra folding properties. </li> <li> Raw string literals for C++0x supported in C++ lexer. </li> <li> Triple-quoted strings used in Vala language supported in C++ lexer. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3177601&group_id=2439">Feature #3177601.</a> </li> <li> The errorlist lexer used in SciTE's output pane colours lines that start with '<' as diff deletions. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3172878&group_id=2439">Feature #3172878.</a> </li> <li> The Fortran lexer correctly folds type-bound procedures from Fortran 2003. </li> <li> LPeg lexer support improved in SciTE. </li> <li> SciTE on Windows-64 fixes for menu localisation and Lua scripts. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3204502&group_id=2439">Bug #3204502.</a> </li> <li> SciTE on Windows avoids locking folders when using the open or save dialogs. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1795484&group_id=2439">Bug #1795484.</a> </li> <li> Diff lexer fixes problem where diffs of diffs producing lines that start with "----". <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3197952&group_id=2439">Bug #3197952.</a> </li> <li> Bug fixed when searching upwards in Chinese code page 936. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3176271&group_id=2439">Bug #3176271.</a> </li> <li> On Cocoa, translucent drawing performed as on other platforms instead of 2.5 times less translucent. </li> <li> Performance issue and potential bug fixed on GTK+ with caret line for long lines. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite224.zip?download">Release 2.24</a> </h3> <ul> <li> Released 3 February 2011. </li> <li> Fixed memory leak in GTK+ Cairo code. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3157655&group_id=2439">Feature #3157655.</a> </li> <li> Insert Abbreviation dialog added to SciTE on GTK+. </li> <li> SCN_UPDATEUI notifications received when window scrolled. An 'updated' bit mask indicates which types of update have occurred from SC_UPDATE_SELECTION, SC_UPDATE_CONTENT, SC_UPDATE_H_SCROLL or SC_UPDATE_V_SCROLL. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3125977&group_id=2439">Feature #3125977.</a> </li> <li> On Windows, to ensure reverse arrow cursor matches platform default, it is now generated by reflecting the platform arrow cursor. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3143968&group_id=2439">Feature #3143968.</a> </li> <li> Can choose mouse cursor used in margins. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3161326&group_id=2439">Feature #3161326.</a> </li> <li> On GTK+, SciTE sets a mime type of text/plain in its .desktop file so that it will appear in the shell context menu. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3137126&group_id=2439">Feature #3137126.</a> </li> <li> Bash folder handles here docs. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3118223&group_id=2439">Feature #3118223.</a> </li> <li> C++ folder adds fold.cpp.syntax.based, fold.cpp.comment.multiline, fold.cpp.explicit.start, fold.cpp.explicit.end, and fold.cpp.explicit.anywhere properties to allow more control over folding and choice of explicit fold markers. </li> <li> C++ lexer fixed to always handle single quote strings continued past a line end. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3150522&group_id=2439">Bug #3150522.</a> </li> <li> Ruby folder handles here docs. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3118224&group_id=2439">Feature #3118224.</a> </li> <li> SQL lexer allows '.' to be part of words. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3103129&group_id=2439">Feature #3103129.</a> </li> <li> SQL folder handles case statements in more situations. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3135027&group_id=2439">Feature #3135027.</a> </li> <li> SQL folder adds fold points inside expressions based on bracket structure. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3165488&group_id=2439">Feature #3165488.</a> </li> <li> SQL folder drops fold.sql.exists property as 'exists' is handled automatically. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3164194&group_id=2439">Bug #3164194.</a> </li> <li> SciTE only forwards properties to lexers when they have been explicitly set so the defaults set by lexers are used rather than 0. </li> <li> Mouse double click word selection chooses the word around the character under the mouse rather than the inter-character position under the mouse. This makes double clicking select what the user is pointing at and avoids selecting adjacent non-word characters. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3111174&group_id=2439">Bug #3111174.</a> </li> <li> Fixed mouse double click to always perform word select, not line select. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3143635&group_id=2439">Bug #3143635.</a> </li> <li> Right click cancels autocompletion. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3144531&group_id=2439">Bug #3144531.</a> </li> <li> Fixed multiPaste to work when additionalSelectionTyping off. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3126221&group_id=2439">Bug #3126221.</a> </li> <li> Fixed virtual space problems when text modified at caret. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3154986&group_id=2439">Bug #3154986.</a> </li> <li> Fixed memory leak in lexer object code. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3133672&group_id=2439">Bug #3133672.</a> </li> <li> Fixed SciTE on GTK+ search failure when using regular expression. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3156217&group_id=2439">Bug #3156217.</a> </li> <li> Avoid unnecessary full window redraw for SCI_GOTOPOS. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3146650&group_id=2439">Feature #3146650.</a> </li> <li> Avoid unnecessary redraw when indicator fill range makes no real change. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite223.zip?download">Release 2.23</a> </h3> <ul> <li> Released 7 December 2010. </li> <li> On GTK+ version 2.22 and later, drawing is performed with Cairo rather than GDK. This is in preparation for GTK+ 3.0 which will no longer support GDK drawing. The appearance of some elements will be different with Cairo as it is anti-aliased and uses sub-pixel positioning. Cairo may be turned on for GTK+ versions before 2.22 by defining USE_CAIRO although this has not been extensively tested. </li> <li> New lexer a68k for Motorola 68000 assembler. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3101598&group_id=2439">Feature #3101598.</a> </li> <li> Borland C++ is no longer supported for building Scintilla or SciTE on Windows. </li> <li> Performance improved when creating large rectangular selections. </li> <li> PHP folder recognises #region and #endregion comments. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3101624&group_id=2439">Feature #3101624.</a> </li> <li> SQL lexer has a lexer.sql.numbersign.comment option to turn off use of '#' comments as these are a non-standard feature only available in some implementations. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3098071&group_id=2439">Feature #3098071.</a> </li> <li> SQL folder recognises case statements and understands the fold.at.else property. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3104091&group_id=2439">Bug #3104091.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3107362&group_id=2439">Bug #3107362.</a> </li> <li> SQL folder fixes bugs with end statements when fold.sql.only.begin=1. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3104091&group_id=2439">Bug #3104091.</a> </li> <li> SciTE on Windows bug fixed with multi-line tab bar not adjusting correctly when maximizing and demaximizing. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3097517&group_id=2439">Bug #3097517.</a> </li> <li> Crash fixed on GTK+ when Scintilla widget destroyed while it still has an outstanding style idle pending. </li> <li> Bug fixed where searching backwards in DBCS text (code page 936 or similar) failed to find occurrences at the start of the line. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3103936&group_id=2439">Bug #3103936.</a> </li> <li> SciTE on Windows supports Unicode file names when executing help applications with winhelp and htmlhelp subsystems. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite222.zip?download">Release 2.22</a> </h3> <ul> <li> Released 27 October 2010. </li> <li> SciTE includes support for integrating with Scintillua which allows lexers to be implemented in Lua as a Parsing Expression Grammar (PEG). </li> <li> Regular expressions allow use of '?' for non-greedy matches or to match 0 or 1 instances of an item. </li> <li> SCI_CONTRACTEDFOLDNEXT added to allow rapid retrieval of folding state. </li> <li> SCN_HOTSPOTRELEASECLICK notification added which is similar to SCN_HOTSPOTCLICK but occurs when the mouse is released. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3082409&group_id=2439">Feature #3082409.</a> </li> <li> Command added for centring current line in window. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3064696&group_id=2439">Feature #3064696.</a> </li> <li> SciTE performance improved by not examining document for line ends when switching buffers and not storing folds when folding turned off. </li> <li> Bug fixed where scrolling to ensure the caret is visible did not take into account all pixels of the line. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3081721&group_id=2439">Bug #3081721.</a> </li> <li> Bug fixed for autocompletion list overlapping text when WS_EX_CLIENTEDGE used. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3079778&group_id=2439">Bug #3079778.</a> </li> <li> After autocompletion, the caret's X is updated. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3079114&group_id=2439">Bug #3079114.</a> </li> <li> On Windows, default to the system caret blink time. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3079784&group_id=2439">Feature #3079784.</a> </li> <li> PgUp/PgDn fixed to allow virtual space. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3077452&group_id=2439">Bug #3077452.</a> </li> <li> Crash fixed when AddMark and AddMarkSet called with negative argument. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3075074&group_id=2439">Bug #3075074.</a> </li> <li> Dwell notifications fixed so that they do not occur when the mouse is outside Scintilla. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3073481&group_id=2439">Bug #3073481.</a> </li> <li> Bash lexer bug fixed for here docs starting with <<-. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3063822&group_id=2439">Bug #3063822.</a> </li> <li> C++ lexer bug fixed for // comments that are continued onto a second line by a \. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3066031&group_id=2439">Bug #3066031.</a> </li> <li> C++ lexer fixes wrong highlighting for float literals containing +/-. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3058924&group_id=2439">Bug #3058924.</a> </li> <li> JavaScript lexer recognise regexes following return keyword. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3062287&group_id=2439">Bug #3062287.</a> </li> <li> Ruby lexer handles % quoting better and treats range dots as operators in 1..2 and 1...2. Ruby folder handles "if" keyword used as a modifier even when it is separated from the modified statement by an escaped new line. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2093767&group_id=2439">Bug #2093767.</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3058496&group_id=2439">Bug #3058496.</a> </li> <li> Bug fixed where upwards search failed with DBCS code pages. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3065912&group_id=2439">Bug #3065912.</a> </li> <li> SciTE has a default Lua startup script name distributed in SciTEGlobal.properties. No error message is displayed if this file does not exist. </li> <li> SciTE on Windows tab control height is calculated better. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2635702&group_id=2439">Bug #2635702.</a> </li> <li> SciTE on Windows uses better themed check buttons in find and replace strips. </li> <li> SciTE on Windows fixes bug with Find strip appearing along with Incremental Find strip. </li> <li> SciTE setting find.close.on.find added to allow preventing the Find dialog from closing. </li> <li> SciTE on Windows attempts to rerun commands that fail by prepending them with "cmd.exe /c". This allows commands built in to the command processor like "dir" to run. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite221.zip?download">Release 2.21</a> </h3> <ul> <li> Released 1 September 2010. </li> <li> Asian Double Byte Character Set (DBCS) support improved. Case insensitive search works and other operations are much faster. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2999125&group_id=2439">Bug #2999125,</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2774616&group_id=2439">Bug #2774616,</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2991942&group_id=2439">Bug #2991942,</a> <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3005688&group_id=2439">Bug #3005688.</a> </li> <li> Scintilla on GTK+ uses only non-deprecated APIs (for GTK+ 2.20) except for GdkFont and GdkFont use can be disabled with the preprocessor symbol DISABLE_GDK_FONT. </li> <li> IDocument interface used by lexers adds BufferPointer and GetLineIndentation methods. </li> <li> On Windows, clicking sets focus before processing the click or sending notifications. </li> <li> Bug on OS X (macosx platform) fixed where drag/drop overwrote clipboard. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3039732&group_id=2439">Bug #3039732.</a> </li> <li> GTK+ drawing bug when the view was horizontally scrolled more than 32000 pixels fixed. </li> <li> SciTE bug fixed with invoking Complete Symbol from output pane. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3050957&group_id=2439">Bug #3050957.</a> </li> <li> Bug fixed where it was not possible to disable folding. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3040649&group_id=2439">Bug #3040649.</a> </li> <li> Bug fixed with pressing Enter on a folded fold header line not opening the fold. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3043419&group_id=2439">Bug #3043419.</a> </li> <li> SciTE 'Match case' option in find and replace user interfaces changed to 'Case sensitive' to allow use of 'v' rather than 'c' as the mnemonic. </li> <li> SciTE displays stack trace for Lua when error occurs.. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3051397&group_id=2439">Bug #3051397.</a> </li> <li> SciTE on Windows fixes bug where double clicking on error message left focus in output pane. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1264835&group_id=2439">Bug #1264835.</a> </li> <li> SciTE on Windows uses SetDllDirectory to avoid a security problem. </li> <li> C++ lexer crash fixed with preprocessor expression that looked like division by 0. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3056825&group_id=2439">Bug #3056825.</a> </li> <li> Haskell lexer improved. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3039490&group_id=2439">Feature #3039490.</a> </li> <li> HTML lexing fixed around Django {% %} tags. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3034853&group_id=2439">Bug #3034853.</a> </li> <li> HTML JavaScript lexing fixed when line end escaped. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3038381&group_id=2439">Bug #3038381.</a> </li> <li> HTML lexer stores line state produced by a line on that line rather than on the next line. </li> <li> Markdown lexer fixes infinite loop. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3045386&group_id=2439">Bug #3045386.</a> </li> <li> MySQL folding bugs with END statements fixed. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3031742&group_id=2439">Bug #3031742.</a> </li> <li> PowerShell lexer allows '_' as a word character. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3042228&group_id=2439">Feature #3042228.</a> </li> <li> SciTE on GTK+ abandons processing of subsequent commands if a command.go.needs command fails. </li> <li> When SciTE is closed, all buffers now receive an OnClose call. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3033857&group_id=2439">Bug #3033857.</a> </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite220.zip?download">Release 2.20</a> </h3> <ul> <li> Released 30 July 2010. </li> <li> Lexers are implemented as objects so that they may retain extra state. The interfaces defined for this are tentative and may change before the next release. Compatibility classes allow current lexers compiled into Scintilla to run with few changes. The interface to external lexers has changed and existing external lexers will need to have changes made and be recompiled. A single lexer object is attached to a document whereas previously lexers were attached to views which could lead to different lexers being used for split views with confusing results. </li> <li> C++ lexer understands the preprocessor enough to grey-out inactive code due to conditional compilation. </li> <li> SciTE can use strips within the main window for find and replace rather than dialogs. On Windows SciTE always uses a strip for incremental search. </li> <li> Lexer added for Txt2Tags language. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3018736&group_id=2439">Feature #3018736.</a> </li> <li> Sticky caret feature enhanced with additional SC_CARETSTICKY_WHITESPACE mode . <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3027559&group_id=2439">Feature #3027559.</a> </li> <li> Bash lexer implements basic parsing of compound commands and constructs. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3033135&group_id=2439">Feature #3033135.</a> </li> <li> C++ folder allows disabling explicit fold comments. </li> <li> Perl folder works for array blocks, adjacent package statements, nested PODs, and terminates package folding at __DATA__, ^D and ^Z. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3030887&group_id=2439">Feature #3030887.</a> </li> <li> PowerShell lexer supports multiline <# .. #> comments and adds 2 keyword classes. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3015176&group_id=2439">Feature #3015176.</a> </li> <li> Lexing performed incrementally when needed by wrapping to make user interface more responsive. </li> <li> SciTE setting replaceselection:yes works on GTK+. </li> <li> SciTE Lua scripts calling io.open or io.popen on Windows have arguments treated as UTF-8 and converted to Unicode so that non-ASCII file paths will work. Lua files with non-ASCII paths run. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3016951&group_id=2439">Bug #3016951.</a> </li> <li> Crash fixed when searching for empty string. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3017572&group_id=2439">Bug #3017572.</a> </li> <li> Bugs fixed with folding and lexing when Enter pressed at start of line. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3032652&group_id=2439">Bug #3032652.</a> </li> <li> Bug fixed with line selection mode not affecting selection range. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3021480&group_id=2439">Bug #3021480.</a> </li> <li> Bug fixed where indicator alpha was limited to 100 rather than 255. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3021473&group_id=2439">Bug #3021473.</a> </li> <li> Bug fixed where changing annotation did not cause automatic redraw. </li> <li> Regular expression bug fixed when a character range included non-ASCII characters. </li> <li> Compilation failure with recent compilers fixed on GTK+. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3022027&group_id=2439">Bug #3022027.</a> </li> <li> Bug fixed on Windows with multiple monitors where autocomplete pop up would appear off-screen or straddling monitors. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3017512&group_id=2439">Bug #3017512.</a> </li> <li> SciTE on Windows bug fixed where changing directory to a Unicode path failed. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3011987&group_id=2439">Bug #3011987.</a> </li> <li> SciTE on Windows bug fixed where combo boxes were not allowing Unicode characters. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3012986&group_id=2439">Bug #3012986.</a> </li> <li> SciTE on GTK+ bug fixed when dragging files into SciTE on KDE. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3026555&group_id=2439">Bug #3026555.</a> </li> <li> SciTE bug fixed where closing untitled file could lose data if attempt to name file same as another buffer. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3011680&group_id=2439">Bug #3011680.</a> </li> <li> COBOL number masks now correctly highlighted. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3012164&group_id=2439">Bug #3012164.</a> </li> <li> PHP comments can include <?PHP without triggering state change. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2854183&group_id=2439">Bug #2854183.</a> </li> <li> VHDL lexer styles unclosed string correctly. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3029627&group_id=2439">Bug #3029627.</a> </li> <li> Memory leak fixed in list boxes on GTK+. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3007669&group_id=2439">Bug #3007669.</a> </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite212.zip?download">Release 2.12</a> </h3> <ul> <li> Released 1 June 2010. </li> <li> Drawing optimizations improve speed and fix some visible flashing when scrolling. </li> <li> Copy Path command added to File menu in SciTE. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2986745&group_id=2439">Feature #2986745.</a> </li> <li> Optional warning displayed by SciTE when saving a file which has been modified by another process. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2975041&group_id=2439">Feature #2975041.</a> </li> <li> Flagship lexer for xBase languages updated to follow the language much more closely. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2992689&group_id=2439">Feature #2992689.</a> </li> <li> HTML lexer highlights Django templates in more regions. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=3002874&group_id=2439">Feature #3002874.</a> </li> <li> Dropping files on SciTE on Windows, releases the drag object earlier and opens the files asynchronously, leading to smoother user experience. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2986724&group_id=2439">Feature #2986724.</a> </li> <li> SciTE HTML exports take the Use Monospaced Font setting into account. </li> <li> SciTE window title "[n of m]" localised. </li> <li> When new line inserted at start of line, markers are moved down. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2986727&group_id=2439">Bug #2986727.</a> </li> <li> On Windows, dropped text has its line ends converted, similar to pasting. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3005328&group_id=2439">Bug #3005328.</a> </li> <li> Fixed bug with middle-click paste in block select mode where text was pasted next to selection rather than at cursor. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2984460&group_id=2439">Bug #2984460.</a> </li> <li> Fixed SciTE crash where a style had a size parameter without a value. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3003834&group_id=2439">Bug #3003834.</a> </li> <li> Debug assertions in multiple lexers fixed. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3000566&group_id=2439">Bug #3000566.</a> </li> <li> CSS lexer fixed bug where @font-face displayed incorrectly <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2994224&group_id=2439">Bug #2994224.</a> </li> <li> CSS lexer fixed bug where open comment caused highlighting error. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1683672&group_id=2439">Bug #1683672.</a> </li> <li> Shell file lexer fixed highlight glitch with here docs where the first line is a comment. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2830239&group_id=2439">Bug #2830239.</a> </li> <li> Bug fixed in SciTE openpath property that caused Open Selected File to fail to open the selected file. </li> <li> Bug fixed in SciTE FileExt property when file name with no extension evaluated to whole path. </li> <li> Fixed SciTE on Windows printing bug where the $(CurrentTime), $(CurrentPage) variables were not expanded. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2994612&group_id=2439">Bug #2994612.</a> </li> <li> SciTE compiles for 64-bit Windows and runs without crashing. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2986312&group_id=2439">Bug #2986312.</a> </li> <li> Full Screen mode in Windows Vista/7 improved to hide Start button and size borders a little better. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=3002813&group_id=2439">Bug #3002813.</a> </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite211.zip?download">Release 2.11</a> </h3> <ul> <li> Released 9 April 2010. </li> <li> Fixes compatibility of Scintilla.h with the C language. </li> <li> With a rectangular selection SCI_GETSELECTIONSTART and SCI_GETSELECTIONEND return limits of the rectangular selection rather than the limits of the main selection. </li> <li> When SciTE on Windows is minimized to tray, only takes a single click to restore rather than a double click. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=981917&group_id=2439">Feature #981917.</a> </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite210.zip?download">Release 2.10</a> </h3> <ul> <li> Released 4 April 2010. </li> <li> Version 1.x of GTK+ is no longer supported. </li> <li> SciTE is no longer supported on Windows 95, 98 or ME. </li> <li> Case-insensitive search works for non-ASCII characters in UTF-8 and 8-bit encodings. Non-regex search in DBCS encodings is always case-sensitive. </li> <li> Non-ASCII characters may be changed to upper and lower case. </li> <li> SciTE on Windows can access all files including those with names outside the user's preferred character encoding. </li> <li> SciTE may be extended with lexers written in Lua. </li> <li> When there are multiple selections, the paste command can go either to the main selection or to each selection. This is controlled with SCI_SETMULTIPASTE. </li> <li> More forms of bad UTF-8 are detected including overlong sequences, surrogates, and characters outside the valid range. Bad UTF-8 bytes are now displayed as 2 hex digits preceded by 'x'. </li> <li> SCI_GETTAG retrieves the value of captured expressions within regular expression searches. </li> <li> Django template highlighting added to the HTML lexer. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2974889&group_id=2439">Feature #2974889.</a> </li> <li> Verilog line comments can be folded. </li> <li> SciTE on Windows allows specifying a filter for the Save As dialog. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2943445&group_id=2439">Feature #2943445.</a> </li> <li> Bug fixed when multiple selection disabled where rectangular selections could be expanded into multiple selections. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2948260&group_id=2439">Bug #2948260.</a> </li> <li> Bug fixed when document horizontally scrolled and up/down-arrow did not return to the same column after horizontal scroll occurred. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2950799&group_id=2439">Bug #2950799.</a> </li> <li> Bug fixed to remove hotspot highlight when mouse is moved out of the document. Windows only fix. <a href="https://sourceforge.net/tracker/?func=detail&aid=2951353&group_id=2439&atid=102439">Bug #2951353.</a> </li> <li> R lexer now performs case-sensitive check for keywords. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2956543&group_id=2439">Bug #2956543.</a> </li> <li> Bug fixed on GTK+ where text disappeared when a wrap occurred. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2958043&group_id=2439">Bug #2958043.</a> </li> <li> Bug fixed where regular expression replace cannot escape the '\' character by using '\\'. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2959876&group_id=2439">Bug #2959876.</a> </li> <li> Bug fixed on GTK+ when virtual space disabled, middle-click could still paste text beyond end of line. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2971618&group_id=2439">Bug #2971618.</a> </li> <li> SciTE crash fixed when double clicking on a malformed error message in the output pane. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2976551&group_id=2439">Bug #2976551.</a> </li> <li> Improved performance on GTK+ when changing parameters associated with scroll bars to the same value. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2964357&group_id=2439">Bug #2964357.</a> </li> <li> Fixed bug with pressing Shift+Tab with a rectangular selection so that it performs an un-indent similar to how Tab performs an indent. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite203.zip?download">Release 2.03</a> </h3> <ul> <li> Released 14 February 2010. </li> <li> Added SCI_SETFIRSTVISIBLELINE to match SCI_GETFIRSTVISIBLELINE. </li> <li> Erlang lexer extended set of numeric bases recognised; separate style for module:function_name; detects built-in functions, known module attributes, and known preprocessor instructions; recognises EDoc and EDoc macros; separates types of comments. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2942448&group_id=2439">Bug #2942448.</a> </li> <li> Python lexer extended with lexer.python.strings.over.newline option that allows non-triple-quoted strings to extend past line ends. This allows use of the Ren'Py language. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2945550&group_id=2439">Feature #2945550.</a> </li> <li> Fixed bugs with cursor movement after deleting a rectangular selection. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2942131&group_id=2439">Bug #2942131.</a> </li> <li> Fixed bug where calling SCI_SETSEL when there is a rectangular selection left the additional selections selected. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2947064&group_id=2439">Bug #2947064.</a> </li> <li> Fixed macro recording bug where not all bytes in multi-byte character insertions were reported through SCI_REPLACESEL. </li> <li> Fixed SciTE bug where using Ctrl+Enter followed by Ctrl+Space produced an autocompletion list with only a single line containing all the identifiers. </li> <li> Fixed SciTE on GTK+ bug where running a tool made the user interface completely unresponsive. </li> <li> Fixed SciTE on Windows Copy to RTF bug. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2108574&group_id=2439">Bug #2108574.</a> </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite202.zip?download">Release 2.02</a> </h3> <ul> <li> Released on 25 January 2010. </li> <li> Markdown lexer added. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2844081&group_id=2439">Feature #2844081.</a> </li> <li> On GTK+, include code that understands the ranges of lead bytes for code pages 932, 936, and 950 so that most Chinese and Japanese text can be used on systems that are not set to the corresponding locale. </li> <li> Allow changing the size of dots in visible whitespace using SCI_SETWHITESPACESIZE. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2839427&group_id=2439">Feature #2839427.</a> </li> <li> Additional carets can be hidden with SCI_SETADDITIONALCARETSVISIBLE. </li> <li> Can choose anti-aliased, non-anti-aliased or lcd-optimized text using SCI_SETFONTQUALITY. </li> <li> Retrieve the current selected text in the autocompletion list with SCI_AUTOCGETCURRENTTEXT. </li> <li> Retrieve the name of the current lexer with SCI_GETLEXERLANGUAGE. </li> <li> Progress 4GL lexer improves handling of comments in preprocessor declaration. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2902206&group_id=2439">Feature #2902206.</a> </li> <li> HTML lexer extended to handle Mako template language. </li> <li> SQL folder extended for SQL Anywhere "EXISTS" and "ENDIF" keywords. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2887524&group_id=2439">Feature #2887524.</a> </li> <li> SciTE adds APIPath and AbbrevPath variables. </li> <li> SciTE on GTK+ uses pipes instead of temporary files for running tools. This should be more secure. </li> <li> Fixed crash when calling SCI_STYLEGETFONT for a style which does not have a font set. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2857425&group_id=2439">Bug #2857425.</a> </li> <li> Fixed crash caused by not having sufficient styles allocated after choosing a lexer. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2881279&group_id=2439">Bug #2881279.</a> </li> <li> Fixed crash in SciTE using autocomplete word when word characters includes space. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2840141&group_id=2439">Bug #2840141.</a> </li> <li> Fixed bug with handling upper-case file extensions SciTE on GTK+. </li> <li> Fixed SciTE loading files from sessions with folded folds where it would not be scrolled to the correct location. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2882775&group_id=2439">Bug #2882775.</a> </li> <li> Fixed SciTE loading files from sessions when file no longer exists. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2883437&group_id=2439">Bug #2883437.</a> </li> <li> Fixed SciTE export to HTML using the wrong background colour. </li> <li> Fixed crash when adding an annotation and then adding a new line after the annotation. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2929708&group_id=2439">Bug #2929708.</a> </li> <li> Fixed crash in SciTE setting a property to nil from Lua. </li> <li> SCI_GETSELTEXT fixed to return correct length. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2929441&group_id=2439">Bug #2929441.</a> </li> <li> Fixed text positioning problems with selection in some circumstances. </li> <li> Fixed text positioning problems with ligatures on GTK+. </li> <li> Fixed problem pasting into rectangular selection with caret at bottom caused text to go from the caret down rather than replacing the selection. </li> <li> Fixed problem replacing in a rectangular selection where only the final line was changed. </li> <li> Fixed inability to select a rectangular area using Alt+Shift+Click at both corners. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2899746&group_id=2439">Bug #2899746.</a> </li> <li> Fixed problem moving to start/end of a rectangular selection with left/right key. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2871358&group_id=2439">Bug #2871358.</a> </li> <li> Fixed problem with Select All when there's a rectangular selection. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2930488&group_id=2439">Bug #2930488.</a> </li> <li> Fixed SCI_LINEDUPLICATE on a rectangular selection to not produce multiple discontinuous selections. </li> <li> Virtual space removed when performing delete word left or delete line left. Virtual space converted to real space for delete word right. Preserve virtual space when pressing Delete key. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2882566&group_id=2439">Bug #2882566.</a> </li> <li> Fixed problem where Shift+Alt+Down did not move through wrapped lines. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2871749&group_id=2439">Bug #2871749.</a> </li> <li> Fixed incorrect background colour when using coloured lines with virtual space. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2914691&group_id=2439">Bug #2914691.</a> </li> <li> Fixed failure to display wrap symbol for SC_WRAPVISUALFLAGLOC_END_BY_TEXT. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2936108&group_id=2439">Bug #2936108.</a> </li> <li> Fixed blank background colour with EOLFilled style on last line. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2890105&group_id=2439">Bug #2890105.</a> </li> <li> Fixed problem in VB lexer with keyword at end of file. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2901239&group_id=2439">Bug #2901239.</a> </li> <li> Fixed SciTE bug where double clicking on a tab closed the file. </li> <li> Fixed SciTE brace matching commands to only work when the caret is next to the brace, not when it is in virtual space. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2885560&group_id=2439">Bug #2885560.</a> </li> <li> Fixed SciTE on Windows Vista to access files in the Program Files directory rather than allow Windows to virtualize access. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2916685&group_id=2439">Bug #2916685.</a> </li> <li> Fixed NSIS folder to handle keywords that start with '!'. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2872157&group_id=2439">Bug #2872157.</a> </li> <li> Changed linkage of Scintilla_LinkLexers to "C" so that it can be used by clients written in C. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2844718&group_id=2439">Bug #2844718.</a> </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite201.zip?download">Release 2.01</a> </h3> <ul> <li> Released on 19 August 2009. </li> <li> Fix to positioning rectangular paste when viewing line ends. </li> <li> Don't insert new lines and indentation for line ends at end of rectangular paste. </li> <li> When not in additional selection typing mode, cutting a rectangular selection removes all of the selected text. </li> <li> Rectangular selections are copied to the clipboard in document order, not in the order of selection. </li> <li> SCI_SETCURRENTPOS and SCI_SETANCHOR work in rectangular mode. </li> <li> On GTK+, drag and drop to a later position in the document now drops at the position. </li> <li> Fix bug where missing property did not use default value. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite200.zip?download">Release 2.0</a> </h3> <ul> <li> Released on 11 August 2009. </li> <li> Multiple pieces of text can be selected simultaneously by holding control while dragging the mouse. Typing, backspace and delete may affect all selections together. </li> <li> Virtual space allows selecting beyond the last character on a line. </li> <li> SciTE on GTK+ path bar is now optional and defaults to off. </li> <li> MagikSF lexer recognises numbers correctly. </li> <li> Folding of Python comments and blank lines improved. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=210240&group_id=2439">Bug #210240.</a> </li> <li> Bug fixed where background colour of last character in document leaked past that character. </li> <li> Crash fixed when adding marker beyond last line in document. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2830307&group_id=2439">Bug #2830307.</a> </li> <li> Resource leak fixed in SciTE for Windows when printing fails. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2816524&group_id=2439">Bug #2816524.</a> </li> <li> Bug fixed on Windows where the system caret was destroyed during destruction when another window was using the system caret. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2830223&group_id=2439">Bug #2830223.</a> </li> <li> Bug fixed where indentation guides were drawn over text when the indentation used a style with a different space width to the default style. </li> <li> SciTE bug fixed where box comment added a bare line feed rather than the chosen line end. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2818104&group_id=2439">Bug #2818104.</a> </li> <li> Reverted fix that led to wrapping whole document when displaying the first line of the document. </li> <li> Export to LaTeX in SciTE fixed to work in more cases and not use as much space. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=1286548&group_id=2439">Bug #1286548.</a> </li> <li> Bug fixed where EN_CHANGE notification was sent when performing a paste operation in a read-only document. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2825485&group_id=2439">Bug #2825485.</a> </li> <li> Refactored code so that Scintilla exposes less of its internal implementation and uses the C++ standard library for some basic collections. Projects that linked to Scintilla's SString or PropSet classes should copy this code from a previous version of Scintilla or from SciTE. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite179.zip?download">Release 1.79</a> </h3> <ul> <li> Released on 1 July 2009. </li> <li> Memory exhaustion and other exceptions handled by placing an error value into the status property rather than crashing. Scintilla now builds with exception handling enabled and requires exception handling to be enabled. <br /> This is a major change and application developers should consider how they will deal with Scintilla exhausting memory since Scintilla may not be in a stable state. </li> <li> Deprecated APIs removed. The symbols removed are: <ul> <li>SCI_SETCARETPOLICY</li> <li> CARET_CENTER</li> <li> CARET_XEVEN</li> <li> CARET_XJUMPS</li> <li> SC_FOLDFLAG_BOX</li> <li> SC_FOLDLEVELBOXHEADERFLAG</li> <li> SC_FOLDLEVELBOXFOOTERFLAG</li> <li> SC_FOLDLEVELCONTRACTED</li> <li> SC_FOLDLEVELUNINDENT</li> <li> SCN_POSCHANGED</li> <li> SCN_CHECKBRACE</li> <li> SCLEX_ASP</li> <li> SCLEX_PHP</li> </ul> </li> <li> Cocoa platform added. </li> <li> Names of struct types in Scintilla.h now start with "Sci_" to avoid possible clashes with platform definitions. Currently, the old names still work but these will be phased out. </li> <li> When lines are wrapped, subsequent lines may be indented to match the indent of the initial line, or one more indentation level. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2796119&group_id=2439">Feature #2796119.</a> </li> <li> APIs added for finding the character at a point rather than an inter-character position. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2646738&group_id=2439">Feature #2646738.</a> </li> <li> A new marker SC_MARK_BACKGROUND_UNDERLINE is drawn in the text area as an underline the full width of the window. </li> <li> Batch file lexer understands variables surrounded by '!'. </li> <li> CAML lexer also supports SML. </li> <li> D lexer handles string and numeric literals more accurately. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2793782&group_id=2439">Feature #2793782.</a> </li> <li> Forth lexer is now case-insensitive and better supports numbers like $hex and %binary. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2804894&group_id=2439">Feature #2804894.</a> </li> <li> Lisp lexer treats '[', ']', '{', and '}' as balanced delimiters which is common usage. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2794989&group_id=2439">Feature #2794989.</a> <br /> It treats keyword argument names as being equivalent to symbols. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2794901&group_id=2439">Feature #2794901.</a> </li> <li> Pascal lexer bug fixed to prevent hang when 'interface' near beginning of file. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2802863&group_id=2439">Bug #2802863.</a> </li> <li> Perl lexer bug fixed where previous lexical states persisted causing "/" special case styling and subroutine prototype styling to not be correct. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2809168&group_id=2439">Bug #2809168.</a> </li> <li> XML lexer fixes bug where Unicode entities like '&—' were broken into fragments. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2804760&group_id=2439">Bug #2804760.</a> </li> <li> SciTE on GTK+ enables scrolling the tab bar on recent versions of GTK+. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2061821&group_id=2439">Feature #2061821.</a> </li> <li> SciTE on Windows allows tab bar tabs to be reordered by drag and drop. </li> <li> Unit test script for Scintilla on Windows included with source code. </li> <li> User defined menu items are now localised when there is a matching translation. </li> <li> Width of icon column of autocompletion lists on GTK+ made more consistent. </li> <li> Bug with slicing UTF-8 text into character fragments when there is a sequence of 100 or more 3 byte characters. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2780566&group_id=2439">Bug #2780566.</a> </li> <li> Folding bugs introduced in 1.78 fixed. Some of the fix was generic and there was also a specific fix for C++. </li> <li> Bug fixed where a rectangular paste was not padding the line with sufficient spaces to align the pasted text. </li> <li> Bug fixed with showing all text on each line of multi-line annotations when styling the whole annotation using SCI_ANNOTATIONSETSTYLE. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2789430&group_id=2439">Bug #2789430.</a> </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite178.zip?download">Release 1.78</a> </h3> <ul> <li> Released on 28 April 2009. </li> <li> Annotation lines may be added to each line. </li> <li> A text margin may be defined with different text on each line. </li> <li> Application actions may be added to the undo history. </li> <li> Can query the symbol defined for a marker. An available symbol added for applications to indicate that plugins may allocate a marker. </li> <li> Can increase the amount of font ascent and descent. </li> <li> COBOL lexer added. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2127406&group_id=2439">Feature #2127406.</a> </li> <li> Nimrod lexer added. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2642620&group_id=2439">Feature #2642620.</a> </li> <li> PowerPro lexer added. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2195308&group_id=2439">Feature #2195308.</a> </li> <li> SML lexer added. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2710950&group_id=2439">Feature #2710950.</a> </li> <li> SORCUS Installation file lexer added. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2343375&group_id=2439">Feature #2343375.</a> </li> <li> TACL lexer added. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2127406&group_id=2439">Feature #2127406.</a> </li> <li> TAL lexer added. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2127406&group_id=2439">Feature #2127406.</a> </li> <li> Rewritten Pascal lexer with improved folding and other fixes. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2190650&group_id=2439">Feature #2190650.</a> </li> <li> INDIC_ROUNDBOX translucency level can be modified. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2586290&group_id=2439">Feature #2586290.</a> </li> <li> C++ lexer treats angle brackets in #include directives as quotes when styling.within.preprocessor. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2551033&group_id=2439">Bug #2551033.</a> </li> <li> Inno Setup lexer is sensitive to whether within the [Code] section and handles comments better. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2552973&group_id=2439">Bug #2552973.</a> </li> <li> HTML lexer does not go into script mode when script tag is self-closing. </li> <li> HTML folder fixed where confused by comments when fold.html.preprocessor off. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2532774&group_id=2439">Bug #2532774.</a> </li> <li> Perl lexer fixes problem with string matching caused by line endings. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2648342&group_id=2439">Bug #2648342.</a> </li> <li> Progress lexer fixes problem with "last-event:function" phrase. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2483619&group_id=2439">Bug #2483619.</a> </li> <li> Properties file lexer extended to handle RFC2822 text when lexer.props.allow.initial.spaces on. </li> <li> Python lexer adds options for Python 3 and Cython. </li> <li> Shell lexer fixes heredoc problem caused by line endings. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2635257&group_id=2439">Bug #2635257.</a> </li> <li> TeX lexer handles comment at end of line correctly. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2698766&group_id=2439">Bug #2698766.</a> </li> <li> SciTE retains selection range when performing a replace selection command. <a href="https://sourceforge.net/tracker/?func=detail&atid=352439&aid=2339160&group_id=2439">Feature #2339160.</a> </li> <li> SciTE definition of word characters fixed to match documentaiton. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2464531&group_id=2439">Bug #2464531.</a> </li> <li> SciTE on GTK+ performing Search or Replace when dialog already shown now brings dialog to foreground. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2634224&group_id=2439">Bug #2634224.</a> </li> <li> Fixed encoding bug with calltips on GTK+. </li> <li> Block caret drawn in correct place on wrapped lines. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2126144&group_id=2439">Bug #2126144.</a> </li> <li> Compilation for 64 bit Windows works using MinGW. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2515578&group_id=2439">Bug #2515578.</a> </li> <li> Incorrect memory freeing fixed on OS X. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2354098&group_id=2439">Bug #2354098</a>, <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2671749&group_id=2439">Bug #2671749.</a> </li> <li> SciTE on GTK+ crash fixed on startup when child process exits before initialisation complete. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2716987&group_id=2439">Bug #2716987.</a> </li> <li> Crash fixed when AutoCompleteGetCurrent called with no active autocompletion. </li> <li> Flickering diminished when pressing Tab. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2723006&group_id=2439">Bug #2723006.</a> </li> <li> Namespace compilation issues with GTK+ on OS X fixed. </li> <li> Increased maximum length of SciTE's Language menu on GTK+ to 100 items. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2528241&group_id=2439">Bug #2528241.</a> </li> <li> Fixed incorrect Python lexing for multi-line continued strings. <a href="https://sourceforge.net/tracker/?func=detail&atid=102439&aid=2450963&group_id=2439">Bug #2450963.</a> </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite177.zip?download">Release 1.77</a> </h3> <ul> <li> Released on 18 October 2008. </li> <li> Direct temporary access to Scintilla's text buffer to allow simple efficient interfacing to libraries like regular expression libraries. </li> <li> Scintilla on Windows can interpret keys as Unicode even when a narrow character window with SCI_SETKEYSUNICODE. </li> <li> Notification sent when autocompletion cancelled. </li> <li> MySQL lexer added. </li> <li> Lexer for gettext .po files added. </li> <li> Abaqus lexer handles program structure more correctly. </li> <li> Assembler lexer works with non-ASCII text. </li> <li> C++ lexer allows mixed case doc comment tags. </li> <li> CSS lexer updated and works with non-ASCII. </li> <li> Diff lexer adds style for changed lines, handles subversion diffs better and fixes styling and folding for lines containing chunk dividers ("---"). </li> <li> FORTRAN lexer accepts more styles of compiler directive. </li> <li> Haskell lexer allows hexadecimal literals. </li> <li> HTML lexer improves PHP and JavaScript folding. PHP heredocs, nowdocs, strings and comments processed more accurately. Internet Explorer's non-standard >comment< tag supported. Script recognition in XML can be controlled with lexer.xml.allow.scripts property. </li> <li> Lua lexer styles last character correctly. </li> <li> Perl lexer update. </li> <li> Comment folding implemented for Ruby. </li> <li> Better TeX folding. </li> <li> Verilog lexer updated. </li> <li> Windows Batch file lexer handles %~ and %*. </li> <li> YAML lexer allows non-ASCII text. </li> <li> SciTE on GTK+ implements "Replace in Buffers" in advanced mode. </li> <li> The extender OnBeforeSave method can override the default file saving behaviour by retuning true. </li> <li> Window position and recent files list may be saved into the session file. </li> <li> Right button press outside the selection moves the caret. </li> <li> SciTE load.on.activate works when closing a document reveals a changed document. </li> <li> SciTE bug fixed where eol.mode not used for initial buffer. </li> <li> SciTE bug fixed where a file could be saved as the same name as another buffer leading to confusing behaviour. </li> <li> Fixed display bug for long lines in same style on Windows. </li> <li> Fixed SciTE crash when finding matching preprocessor command used on some files. </li> <li> Drawing performance improved for files with many blank lines. </li> <li> Folding bugs fixed where changing program text produced a decrease in fold level on a fold header line. </li> <li> Clearing document style now clears all indicators. </li> <li> SciTE's embedded Lua updated to 5.1.4. </li> <li> SciTE will compile with versions of GTK+ before 2.8 again. </li> <li> SciTE on GTK+ bug fixed where multiple files not opened. </li> <li> Bug fixed with SCI_VCHOMEWRAP and SCI_VCHOMEWRAPEXTEND on white last line. </li> <li> Regular expression bug fixed where "^[^(]+$" matched empty lines. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite176.zip?download">Release 1.76</a> </h3> <ul> <li> Released on 16 March 2008. </li> <li> Support for PowerShell. </li> <li> Lexer added for Magik. </li> <li> Director extension working on GTK+. </li> <li> Director extension may set focus to SciTE through "focus:" message on GTK+. </li> <li> C++ folder handles final line better in some cases. </li> <li> SCI_COPYALLOWLINE added which is similar to SCI_COPY except that if the selection is empty then the line holding the caret is copied. On Windows an extra clipboard format allows pasting this as a whole line before the current selection. This behaviour is compatible with Visual Studio. </li> <li> On Windows, the horizontal scroll bar can handle wider files. </li> <li> On Windows, a system palette leak was fixed. Should not affect many as palette mode is rarely used. </li> <li> Install command on GTK+ no longer tries to set explicit owner. </li> <li> Perl lexer handles defined-or operator "//". </li> <li> Octave lexer fixes "!=" operator. </li> <li> Optimized selection change drawing to not redraw as much when not needed. </li> <li> SciTE on GTK+ no longer echoes Lua commands so is same as on Windows. </li> <li> Automatic vertical scrolling limited to one line at a time so is not too fast. </li> <li> Crash fixed when line states set beyond end of line states. This occurred when lexers did not set a line state for each line. </li> <li> Crash in SciTE on Windows fixed when search for 513 character string fails. </li> <li> SciTE disables translucent features on Windows 9x due to crashes reported when using translucency. </li> <li> Bug fixed where whitespace background was not seen on wrapped lines. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite175.zip?download">Release 1.75</a> </h3> <ul> <li> Released on 22 November 2007. </li> <li> Some WordList and PropSet functionality moved from Scintilla to SciTE. Projects that link to Scintilla's code for these classes may need to copy code from SciTE. </li> <li> Borland C++ can no longer build Scintilla. </li> <li> Invalid bytes in UTF-8 mode are displayed as hex blobs. This also prevents crashes due to passing invalid UTF-8 to platform calls. </li> <li> Indentation guides enhanced to be visible on completely empty lines when possible. </li> <li> The horizontal scroll bar may grow to match the widest line displayed. </li> <li> Allow autocomplete pop ups to appear outside client rectangle in some cases. </li> <li> When line state changed, SC_MOD_CHANGELINESTATE modification notification sent and margin redrawn. </li> <li> SciTE scripts can access the menu command values IDM_*. </li> <li> SciTE's statement.end property has been implemented again. </li> <li> SciTE shows paths and matches in different styles for Find In Files. </li> <li> Incremental search in SciTE for Windows is modeless to make it easier to exit. </li> <li> Folding performance improved. </li> <li> SciTE for GTK+ now includes a Browse button in the Find In Files dialog. </li> <li> On Windows versions that support Unicode well, Scintilla is a wide character window which allows input for some less common languages like Armenian, Devanagari, Tamil, and Georgian. To fully benefit, applications should use wide character calls. </li> <li> Lua function names are exported from SciTE to allow some extension libraries to work. </li> <li> Lexers added for Abaqus, Ansys APDL, Asymptote, and R. </li> <li> SCI_DELWORDRIGHTEND added for closer compatibility with GTK+ entry widget. </li> <li> The styling buffer may now use all 8 bits in each byte for lexical states with 0 bits for indicators. </li> <li> Multiple characters may be set for SciTE's calltip.<lexer>.parameters.start property. </li> <li> Bash lexer handles octal literals. </li> <li> C++/JavaScript lexer recognises regex literals in more situations. </li> <li> Haskell lexer fixed for quoted strings. </li> <li> HTML/XML lexer does not notice XML indicator if there is non-whitespace between the "<?" and "XML". ASP problem fixed where </ is used inside a comment. </li> <li> Error messages from Lua 5.1 are recognised. </li> <li> Folding implemented for Metapost. </li> <li> Perl lexer enhanced for handling minus-prefixed barewords, underscores in numeric literals and vector/version strings, ^D and ^Z similar to __END__, subroutine prototypes as a new lexical class, formats and format blocks as new lexical classes, and '/' suffixed keywords and barewords. </li> <li> Python lexer styles all of a decorator in the decorator style rather than just the name. </li> <li> YAML lexer styles colons as operators. </li> <li> Fixed SciTE bug where undo would group together multiple separate modifications. </li> <li> Bug fixed where setting background colour of calltip failed. </li> <li> SciTE allows wildcard suffixes for file pattern based properties. </li> <li> SciTE on GTK+ bug fixed where user not prompted to save untitled buffer. </li> <li> SciTE bug fixed where property values from one file were not seen by lower priority files. </li> <li> Bug fixed when showing selection with a foreground colour change which highlighted an incorrect range in some positions. </li> <li> Cut now invokes SCN_MODIFYATTEMPTRO notification. </li> <li> Bug fixed where caret not shown at beginning of wrapped lines. Caret made visible in some cases after wrapping and scroll bar updated after wrapping. </li> <li> Modern indicators now work on wrapped lines. </li> <li> Some crashes fixed for 64-bit GTK+. </li> <li> On GTK+ clipboard features improved for VMWare tools copy and paste. SciTE exports the clipboard more consistently on shut down. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite174.zip?download">Release 1.74</a> </h3> <ul> <li> Released on 18 June 2007. </li> <li> OS X support. </li> <li> Indicators changed to be a separate data structure allowing more indicators. Storing indicators in high bits of styling bytes is deprecated and will be removed in the next version. </li> <li> Unicode support extended to all Unicode characters not just the Basic Multilingual Plane. </li> <li> Performance improved on wide lines by breaking long runs in a single style into shorter segments. </li> <li> Performance improved by caching layout of short text segments. </li> <li> SciTE includes Lua 5.1. </li> <li> Caret may be displayed as a block. </li> <li> Lexer added for GAP. </li> <li> Lexer added for PL/M. </li> <li> Lexer added for Progress. </li> <li> SciTE session files have changed format to be like other SciTE .properties files and now use the extension .session. Bookmarks and folds may optionally be saved in session files. Session files created with previous versions of SciTE will not load into this version. </li> <li> SciTE's extension and scripting interfaces add OnKey, OnDwellStart, and OnClose methods. </li> <li> On GTK+, copying to the clipboard does not include the text/urilist type since this caused problems when pasting into Open Office. </li> <li> On GTK+, Scintilla defaults caret blink rate to platform preference. </li> <li> Dragging does not start until the mouse has been dragged a certain amount. This stops spurious drags when just clicking inside the selection. </li> <li> Bug fixed where brace highlight not shown when caret line background set. </li> <li> Bug fixed in Ruby lexer where out of bounds access could occur. </li> <li> Bug fixed in XML folding where tags were not being folded because they are singletons in HTML. </li> <li> Bug fixed when many font names used. </li> <li> Layout bug fixed on GTK+ where fonts have ligatures available. </li> <li> Bug fixed with SCI_LINETRANSPOSE on a blank line. </li> <li> SciTE hang fixed when using UNC path with directory properties feature. </li> <li> Bug on Windows fixed by examining dropped text for Unicode even in non-Unicode mode so it can work when source only provides Unicode or when using an encoding different from the system default. </li> <li> SciTE bug on GTK+ fixed where Stop Executing did not work when more than a single process started. </li> <li> SciTE bug on GTK+ fixed where mouse wheel was not switching between buffers. </li> <li> Minor line end fix to PostScript lexer. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite173.zip?download">Release 1.73</a> </h3> <ul> <li> Released on 31 March 2007. </li> <li> SciTE adds a Directory properties file to configure behaviour for files in a directory and its subdirectories. </li> <li> Style changes may be made during text modification events. </li> <li> Regular expressions recognise \d, \D, \s, \S, \w, \W, and \xHH. </li> <li> Support for cmake language added. </li> <li> More Scintilla properties can be queried. </li> <li> Edge line drawn under text. </li> <li> A savesession command added to SciTE director interface. </li> <li> SciTE File | Encoding menu item names changed to be less confusing. </li> <li> SciTE on GTK+ dialog buttons reordered to follow guidelines. </li> <li> SciTE on GTK+ removed GTK+ 1.x compatible file dialog code. </li> <li> SciTE on GTK+ recognises key names KeypadMultiply and KeypadDivide. </li> <li> Background colour of line wrapping visual flag changed to STYLE_DEFAULT. </li> <li> Makefile lexing enhanced for ':=' operator and when lines start with tab. </li> <li> TADS3 lexer and folder improved. </li> <li> SCN_DOUBLECLICK notification may set SCI_SHIFT, SCI_CTRL, and SCI_ALT flags on modifiers field. </li> <li> Slow folding of large constructs in Python fixed. </li> <li> MSSQL folding fixed to be case-insensitive and fold at more keywords. </li> <li> SciTE's brace matching works better for HTML. </li> <li> Determining API list items checks for specified parameters start character before default '('. </li> <li> Hang fixed in HTML lexer. </li> <li> Bug fixed in with LineTranspose command where markers could move to different line. </li> <li> Memory released when buffer completely emptied. </li> <li> If translucency not available on Windows, draw rectangular outline instead. </li> <li> Bash lexer handles "-x" in "--x-includes..." better. </li> <li> AutoIt3 lexer fixes string followed by '+'. </li> <li> LinesJoin fixed where it stopped early due to not adjusting for inserted spaces.. </li> <li> StutteredPageDown fixed when lines wrapped. </li> <li> FormatRange fixed to not double count line number width which could lead to a large space. </li> <li> SciTE Export As PDF and Latex commands fixed to format floating point numbers with '.' even in locales that use ','. </li> <li> SciTE bug fixed where File | New could produce buffer with contents of previous file when using read-only mode. </li> <li> SciTE retains current scroll position when switching buffers and fold.on.open set. </li> <li> SciTE crash fixed where '*' used to invoke parameters dialog. </li> <li> SciTE bugs when writing large UCS-2 files fixed. </li> <li> Bug fixed when scrolling inside a SCN_PAINTED event by invalidating window rather than trying to perform synchronous painting. </li> <li> SciTE for GTK+ View | Full Screen works on recent versions of GTK+. </li> <li> SciTE for Windows enables and disables toolbar commands correctly. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite172.zip?download">Release 1.72</a> </h3> <ul> <li> Released on 15 January 2007. </li> <li> Performance of per-line data improved. </li> <li> SC_STARTACTION flag set on the first modification notification in an undo transaction to help synchronize the container's undo stack with Scintilla's. </li> <li> On GTK+ drag and drop defaults to move rather than copy. </li> <li> Scintilla supports extending appearance of selection to right hand margin. </li> <li> Incremental search available on GTK+. </li> <li> SciTE Indentation Settings dialog available on GTK+ and adds a "Convert" button. </li> <li> Find in Files can optionally ignore binary files or directories that start with ".". </li> <li> Lexer added for "D" language. </li> <li> Export as HTML shows folding with underline lines and +/- symbols. </li> <li> Ruby lexer interprets interpolated strings as expressions. </li> <li> Lua lexer fixes some cases of numeric literals. </li> <li> C++ folder fixes bug with "@" in doc comments. </li> <li> NSIS folder handles !if and related commands. </li> <li> Inno setup lexer adds styling for single and double quoted strings. </li> <li> Matlab lexer handles backslashes in string literals correctly. </li> <li> HTML lexer fixed to allow "?>" in comments in Basic script. </li> <li> Added key codes for Windows key and Menu key. </li> <li> Lua script method scite.MenuCommand(x) performs a menu command. </li> <li> SciTE bug fixed with box comment command near start of file setting selection to end of file. </li> <li> SciTE on GTK+, fixed loop that occurred with automatic loading for an unreadable file. </li> <li> SciTE asks whether to save files when Windows shuts down. </li> <li> Save Session on Windows now defaults the extension to "ses". </li> <li> Bug fixed with single character keywords. </li> <li> Fixed infinite loop for SCI_GETCOLUMN for position beyond end of document. </li> <li> Fixed failure to accept typing on Solaris/GTK+ when using default ISO-8859-1 encoding. </li> <li> Fixed warning from Lua in SciTE when creating a new buffer when already have maximum number of buffers open. </li> <li> Crash fixed with "%%" at end of batch file. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite171.zip?download">Release 1.71</a> </h3> <ul> <li> Released on 21 August 2006. </li> <!--li> On GTK+ drag and drop defaults to move rather than copy. </li--> <li> Double click notification includes line and position. </li> <li> VB lexer bugs fixed for preprocessor directive below a comment or some other states and to use string not closed style back to the starting quote when there are internal doubled quotes. </li> <li> C++ lexer allows identifiers to contain '$' and non-ASCII characters such as UTF-8. The '$' character can be disallowed with lexer.cpp.allow.dollars=0. </li> <li> Perl lexer allows UTF-8 identifiers and has some other small improvements. </li> <li> SciTE's $(CurrentWord) uses word.characters.<filepattern> to define the word rather than a hardcoded list of word characters. </li> <li> SciTE Export as HTML adds encoding information for UTF-8 file and fixes DOCTYPE. </li> <li> SciTE session and .recent files default to the user properties directory rather than global properties directory. </li> <li> Left and right scroll events handled correctly on GTK+ and horizontal scroll bar has more sensible distances for page and arrow clicks. </li> <li> SciTE on GTK+ tab bar fixed to work on recent versions of GTK+. </li> <li> On GTK+, if the approximate character set conversion is unavailable, a second attempt is made without approximations. This may allow keyboard input and paste to work on older systems. </li> <li> SciTE on GTK+ can redefine the Insert key. </li> <li> SciTE scripting interface bug fixed where some string properties could not be changed. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite170.zip?download">Release 1.70</a> </h3> <ul> <li> Released on 20 June 2006. </li> <li> On GTK+, character set conversion is performed using an option that allows approximate conversions rather than failures when a character can not be converted. This may lead to similar characters being inserted or when no similar character is available a '?' may be inserted. </li> <li> On GTK+, the internationalised IM (Input Method) feature is used for all typed input for all character sets. </li> <li> Scintilla has new margin types SC_MARGIN_BACK and SC_MARGIN_FORE that use the default style's background and foreground colours (normally white and black) as the background to the margin. </li> <li> Scintilla/GTK+ allows file drops on Windows when drop is of type DROPFILES_DND as well as text/uri-list. </li> <li> Code page can only be set to one of the listed valid values. </li> <li> Text wrapping fixed for cases where insertion was not wide enough to trigger wrapping before being styled but was after styling. </li> <li> SciTE find marks are removed before printing or exporting to avoid producing incorrect styles. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite169.zip?download">Release 1.69</a> </h3> <ul> <li> Released on 29 May 2006. </li> <li> SciTE supports z-order based buffer switching on Ctrl+Tab. </li> <li> Translucent support for selection and whole line markers. </li> <li> SciTE may have per-language abbreviations files. </li> <li> Support for Spice language. </li> <li> On GTK+ autocompletion lists are optimised and use correct selection colours. </li> <li> On GTK+ the URI data type is preferred in drag and drop so that applications will see files dragged from the shell rather than dragging the text of the file name into the document. </li> <li> Increased number of margins to 5. </li> <li> Basic lexer allows include directive $include: "file name". </li> <li> SQL lexer no longer bases folding on indentation. </li> <li> Line ends are transformed when copied to clipboard on Windows/GTK+2 as well as Windows/GTK+ 1. </li> <li> Lexing code masks off the indicator bits on the start style before calling the lexer to avoid confusing the lexer when an application has used an indicator. </li> <li> SciTE savebefore:yes only saves the file when it has been changed. </li> <li> SciTE adds output.initial.hide setting to allow setting the size of the output pane without it showing initially. </li> <li> SciTE on Windows Go To dialog allows line number with more digits. </li> <li> Bug in HTML lexer fixed where a segment of PHP could switch scripting language based on earlier text on that line. </li> <li> Memory bug fixed when freeing regions on GTK+. Other minor bugs fixed on GTK+. </li> <li> Deprecated GTK+ calls in Scintilla replaced with current calls. </li> <li> Fixed a SciTE bug where closing the final buffer, if read-only, left the text present in an untitled buffer. </li> <li> Bug fixed in bash lexer that prevented folding. </li> <li> Crash fixed in bash lexer when backslash at end of file. </li> <li> Crash on recent releases of GTK+ 2.x avoided by changing default font from X core font to Pango font "!Sans". </li> <li> Fix for SciTE properties files where multiline properties continued over completely blank lines. </li> <li> Bug fixed in SciTE/GTK+ director interface where more data available than buffer size. </li> <li> Minor visual fixes to SciTE splitter on GTK+. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite168.zip?download">Release 1.68</a> </h3> <ul> <li> Released on 9 March 2006. </li> <li> Translucent drawing implemented for caret line and box indicators. </li> <li> Lexer specifically for TCL is much more accurate than reusing C++ lexer. </li> <li> Support for Inno Setup scripts. </li> <li> Support for Opal language. </li> <li> Calltips may use a new style, STYLE_CALLTIP which allows choosing a different font for calltips. </li> <li> Python lexer styles comments on decorators. </li> <li> HTML lexer refined handling of "?>" and "%>" within server side scripts. </li> <li> Batch file lexer improved. </li> <li> Eiffel lexer doesn't treat '.' as a name character. </li> <li> Lua lexer handles length operator, #, and hex literals. </li> <li> Properties file lexer has separate style for keys. </li> <li> PL/SQL folding improved. </li> <li> SciTE Replace dialog always searches in forwards direction. </li> <li> SciTE can detect language of file from initial #! line. </li> <li> SciTE on GTK+ supports output.scroll=2 setting. </li> <li> SciTE can perform an import a properties file from the command line. </li> <li> Set of word characters used for regular expression \< and \>. </li> <li> Bug fixed with SCI_COPYTEXT stopping too early. </li> <li> Bug fixed with splitting lines so that all lines are split. </li> <li> SciTE calls OnSwitchFile when closing one buffer causes a switch to another. </li> <li> SciTE bug fixed where properties were being reevaluated without good reason after running a macro. </li> <li> Crash fixed when clearing document with some lines contracted in word wrap mode. </li> <li> Palette expands as more entries are needed. </li> <li> SCI_POSITIONFROMPOINT returns more reasonable value when close to last text on a line. </li> <li> On Windows, long pieces of text may be drawn in segments if they fail to draw as a whole. </li> <li> Bug fixed with bad drawing when some visual changes made inside SCN_UPDATEUI notification. </li> <li> SciTE bug fixed with groupundo setting. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite167.zip?download">Release 1.67</a> </h3> <ul> <li> Released on 17 December 2005. </li> <li> Scintilla checks the paint region more accurately when seeing if an area is being repainted. Platform layer implementations may need to change for this to take effect. This fixes some drawing and styling bugs. Also optimized some parts of marker code to only redraw the line of the marker rather than whole of the margin. </li> <li> Quoted identifier style for SQL. SQL folding performed more simply. </li> <li> Ruby lexer improved to better handle here documents and non-ASCII characters. </li> <li> Lua lexer supports long string and block comment syntax from Lua 5.1. </li> <li> Bash lexer handles here documents better. </li> <li> JavaScript lexing recognises regular expressions more accurately and includes flag characters in the regular expression style. This is both in JavaScript files and when JavaScript is embedded in HTML. </li> <li> Scintilla API provided to reveal how many style bits are needed for the current lexer. </li> <li> Selection duplicate added. </li> <li> Scintilla API for adding a set of markers to a line. </li> <li> DBCS encodings work on Windows 9x. </li> <li> Convention defined for property names to be used by lexers and folders so they can be automatically discovered and forwarded from containers. </li> <li> Default bookmark in SciTE changed to a blue sphere image. </li> <li> SciTE stores the time of last asking for a save separately for each buffer which fixes bugs with automatic reloading. </li> <li> On Windows, pasted text has line ends converted to current preference. GTK+ already did this. </li> <li> Kid template language better handled by HTML lexer by finishing ASP Python mode when a ?> is found. </li> <li> SciTE counts number of characters in a rectangular selection correctly. </li> <li> 64-bit compatibility improved. One change that may affect user code is that the notification message header changed to include a pointer-sized id field to match the current Windows definition. </li> <li> Empty ranges can no longer be dragged. </li> <li> Crash fixed when calls made that use layout inside the painted notification. </li> <li> Bug fixed where Scintilla created pixmap buffers that were too large leading to failures when many instances used. </li> <li> SciTE sets the directory of a new file to the directory of the currently active file. </li> <li> SciTE allows choosing a code page for the output pane. </li> <li> SciTE HTML exporter no longer honours monospaced font setting. </li> <li> Line layout cache in page mode caches the line of the caret. An assertion is now used to ensure that the layout reentrancy problem that caused this is easier to find. </li> <li> Speed optimized for long lines and lines containing many control characters. </li> <li> Bug fixed in brace matching in DBCS files where byte inside character is same as brace. </li> <li> Indent command does not indent empty lines. </li> <li> SciTE bug fixed for commands that operate on files with empty extensions. </li> <li> SciTE bug fixed where monospaced option was copied for subsequently opened files. </li> <li> SciTE on Windows bug fixed in the display of a non-ASCII search string which can not be found. </li> <li> Bugs fixed with nested calls displaying a new calltip while one is already displayed. </li> <li> Bug fixed when styling PHP strings. </li> <li> Bug fixed when styling C++ continued preprocessor lines. </li> <li> SciTE bug fixed where opening file from recently used list reset choice of language. </li> <li> SciTE bug fixed when compiled with NO_EXTENSIONS and closing one file closes the application. </li> <li> SciTE crash fixed for error messages that look like Lua messages but aren't in the same order. </li> <li> Remaining fold box support deprecated. The symbols SC_FOLDLEVELBOXHEADERFLAG, SC_FOLDLEVELBOXFOOTERFLAG, SC_FOLDLEVELCONTRACTED, SC_FOLDLEVELUNINDENT, and SC_FOLDFLAG_BOX are deprecated. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite166.zip?download">Release 1.66</a> </h3> <ul> <li> Released on 26 August 2005. </li> <li> New, more ambitious Ruby lexer. </li> <li> SciTE Find in Files dialog has options for matching case and whole words which are enabled when the internal find command is used. </li> <li> SciTE output pane can display automatic completion after "$(" typed. An initial ">" on a line is ignored when Enter pressed. </li> <li> C++ lexer recognises keywords within line doc comments. It continues styles over line end characters more consistently so that eolfilled style can be used for preprocessor lines and line comments. </li> <li> VB lexer improves handling of file numbers and date literals. </li> <li> Lua folder handles repeat until, nested comments and nested strings. </li> <li> POV lexer improves handling of comment lines. </li> <li> AU3 lexer and folder updated. COMOBJ style added. </li> <li> Bug fixed with text display on GTK+ with Pango 1.8. </li> <li> Caret painting avoided when not focused. </li> <li> SciTE on GTK+ handles file names used to reference properties as case-sensitive. </li> <li> SciTE on GTK+ Save As and Export commands set the file name field. On GTK+ the Export commands modify the file name in the same way as on Windows. </li> <li> Fixed SciTE problem where confirmation was not displaying when closing a file where all contents had been deleted. </li> <li> Middle click on SciTE tab now closes correct buffer on Windows when tool bar is visible. </li> <li> SciTE bugs fixed where files contained in directory that includes '.' character. </li> <li> SciTE bug fixed where import in user options was reading file from directory of global options. </li> <li> SciTE calltip bug fixed where single line calltips had arrow displayed incorrectly. </li> <li> SciTE folding bug fixed where empty lines were shown for no reason. </li> <li> Bug fixed where 2 byte per pixel XPM images caused crash although they are still not displayed. </li> <li> Autocompletion list size tweaked. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite165.zip?download">Release 1.65</a> </h3> <ul> <li> Released on 1 August 2005. </li> <li> FreeBasic support. </li> <li> SciTE on Windows handles command line arguments "-" (read standard input into buffer), "--" (read standard input into output pane) and "-@" (read file names from standard input and open each). </li> <li> SciTE includes a simple implementation of Find in Files which is used if no find.command is set. </li> <li> SciTE can close tabs with a mouse middle click. </li> <li> SciTE includes a save.all.for.build setting. </li> <li> Folder for MSSQL. </li> <li> Batch file lexer understands more of the syntax and the behaviour of built in commands. </li> <li> Perl lexer handles here docs better; disambiguates barewords, quote-like delimiters, and repetition operators; handles Pods after __END__; recognises numbers better; and handles some typeglob special variables. </li> <li> Lisp adds more lexical states. </li> <li> PHP allows spaces after <<<. </li> <li> TADS3 has a simpler set of states and recognises identifiers. </li> <li> Avenue elseif folds better. </li> <li> Errorlist lexer treats lines starting with '+++' and '---' as separate styles from '+' and '-' as they indicate file names in diffs. </li> <li> SciTE error recogniser handles file paths in extra explanatory lines from MSVC and in '+++' and '---' lines from diff. </li> <li> Bugs fixed in SciTE and Scintilla folding behaviour when text pasted before folded text caused unnecessary unfolding and cutting text could lead to text being irretrievably hidden. </li> <li> SciTE on Windows uses correct font for dialogs and better font for tab bar allowing better localisation </li> <li> When Windows is used with a secondary monitor before the primary monitor, autocompletion lists are not forced onto the primary monitor. </li> <li> Scintilla calltip bug fixed where down arrow setting wrong value in notification if not in first line. SciTE bug fixed where second arrow only shown on multiple line calltip and was therefore misinterpreting the notification value. </li> <li> Lexers will no longer be re-entered recursively during, for example, fold level setting. </li> <li> Undo of typing in overwrite mode undoes one character at a time rather than requiring a removal and addition step for each character. </li> <li> EM_EXSETSEL(0,-1) fixed. </li> <li> Bug fixed where part of a rectangular selection was not shown as selected. </li> <li> Autocomplete window size fixed. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite164.zip?download">Release 1.64</a> </h3> <ul> <li> Released on 6 June 2005. </li> <li> TADS3 support </li> <li> Smalltalk support. </li> <li> Rebol support. </li> <li> Flagship (Clipper / XBase) support. </li> <li> CSound support. </li> <li> SQL enhanced to support SQL*Plus. </li> <li> SC_MARK_FULLRECT margin marker fills the whole marker margin for marked lines with a colour. </li> <li> Performance improved for some large undo and redo operations and modification flags added in notifications. </li> <li> SciTE adds command equivalents for fold margin mouse actions. </li> <li> SciTE adds OnUpdateUI to set of events that can be handled by a Lua script. </li> <li> Properties set in Scintilla can be read. </li> <li> GTK+ SciTE exit confirmation adds Cancel button. </li> <li> More accurate lexing of numbers in PHP and Caml. </li> <li> Perl can fold POD and package sections. POD verbatim section style. Globbing syntax recognised better. </li> <li> Context menu moved slightly on GTK+ so that it will be under the mouse and will stay open if just clicked rather than held. </li> <li> Rectangular selection paste works the same whichever direction the selection was dragged in. </li> <li> EncodedFromUTF8 handles -1 length argument as documented. </li> <li> Undo and redo can cause SCN_MODIFYATTEMPTRO notifications. </li> <li> Indicators display correctly when they start at the second character on a line. </li> <li> SciTE Export As HTML uses standards compliant CSS. </li> <li> SciTE automatic indentation handles keywords for indentation better. </li> <li> SciTE fold.comment.python property removed as does not work. </li> <li> Fixed problem with character set conversion when pasting on GTK+. </li> <li> SciTE default character set changed from ANSI_CHARSET to DEFAULT_CHARSET. </li> <li> Fixed crash when creating empty autocompletion list. </li> <li> Autocomplete window size made larger under some conditions to make truncation less common. </li> <li> Bug fixed where changing case of a selection did not affect initial character of lines in multi-byte encodings. </li> <li> Bug fixed where rectangular selection not displayed after Alt+Shift+Click. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite163.zip?download">Release 1.63</a> </h3> <ul> <li> Released on 4 April 2005. </li> <li> Autocompletion on Windows changed to use pop up window, be faster, allow choice of maximum width and height, and to highlight only the text of the selected item rather than both the text and icon if any. </li> <li> Extra items can be added to the context menu in SciTE. </li> <li> Character wrap mode in Scintilla helps East Asian languages. </li> <li> Lexer added for Haskell. </li> <li> Objective Caml support. </li> <li> BlitzBasic and PureBasic support. </li> <li> CSS support updated to handle CSS2. </li> <li> C++ lexer is more selective about document comment keywords. </li> <li> AutoIt 3 lexer improved. </li> <li> Lua lexer styles end of line characters on comment and preprocessor lines so that the eolfilled style can be applied to them. </li> <li> NSIS support updated for line continuations, box comments, SectionGroup and PageEx, and with more up-to-date properties. </li> <li> Clarion lexer updated to perform folding and have more styles. </li> <li> SQL lexer gains second set of keywords. </li> <li> Errorlist lexer recognises Borland Delphi error messages. </li> <li> Method added for determining number of visual lines occupied by a document line due to wrapping. </li> <li> Sticky caret mode does not modify the preferred caret x position when typing and may be useful for typing columns of text. </li> <li> Dwell end notification sent when scroll occurs. </li> <li> On GTK+, Scintilla requisition height is screen height rather than large fixed value. </li> <li> Case insensitive autocompletion prefers exact case match. </li> <li> SCI_PARADOWN and SCI_PARAUP treat lines containing only white space as empty and handle text hidden by folding. </li> <li> Scintilla on Windows supports WM_PRINTCLIENT although there are some limitations. </li> <li> SCN_AUTOCSELECTION notification sent when user selects from autoselection list. </li> <li> SciTE's standard properties file sets buffers to 10, uses Pango fonts on GTK+ and has dropped several languages to make the menu fit on screen. </li> <li> SciTE's encoding cookie detection loosened so that common XML files will load in UTF-8 if that is their declared encoding. </li> <li> SciTE on GTK+ changes menus and toolbars to not be detachable unless turned on with a property. Menus no longer tear off. The toolbar may be set to use the default theme icons rather than SciTE's set. Changed key for View | End of Line because of a conflict. Language menu can contain more items. </li> <li> SciTE on GTK+ 2.x allows the height and width of the file open file chooser to be set, for the show hidden files check box to be set from an option and for it to be opened in the directory of the current file explicitly. Enter key works in save chooser. </li> <li> Scintilla lexers should no longer see bits in style bytes that are outside the set they modify so should be able to correctly lex documents where the container has used indicators. </li> <li> SciTE no longer asks to save before performing a revert. </li> <li> SciTE director interface adds a reloadproperties command to reload properties from files. </li> <li> Allow build on CYGWIN platform. </li> <li> Allow use from LccWin compiler. </li> <li> SCI_COLOURISE for SCLEX_CONTAINER causes a SCN_STYLENEEDED notification. </li> <li> Bugs fixed in lexing of HTML/ASP/JScript. </li> <li> Fix for folding becoming confused. </li> <li> On Windows, fixes for Japanese Input Method Editor and for 8 bit Katakana characters. </li> <li> Fixed buffer size bug avoided when typing long words by making buffer bigger. </li> <li> Undo after automatic indentation more sensible. </li> <li> SciTE menus on GTK+ uses Shift and Ctrl rather than old style abbreviations. </li> <li> SciTE full screen mode on Windows calculates size more correctly. </li> <li> SciTE on Windows menus work better with skinning applications. </li> <li> Searching bugs fixed. </li> <li> Colours reallocated when changing image using SCI_REGISTERIMAGE. </li> <li> Caret stays visible when Enter held down. </li> <li> Undo of automatic indentation more reasonable. </li> <li> High processor usage fixed in background wrapping under some circumstances. </li> <li> Crashing bug fixed on AMD64. </li> <li> SciTE crashing bug fixed when position.height or position.width not set. </li> <li> Crashing bug on GTK+ fixed when setting cursor and window is NULL. </li> <li> Crashing bug on GTK+ preedit window fixed. </li> <li> SciTE crashing bug fixed in incremental search on Windows ME. </li> <li> SciTE on Windows has a optional find and replace dialogs that can search through all buffers and search within a particular style number. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite162.zip?download">Release 1.62</a> </h3> <ul> <li> Released on 31 October 2004. </li> <li> Lexer added for ASN.1. </li> <li> Lexer added for VHDL. </li> <li> On Windows, an invisible system caret is used to allow screen readers to determine where the caret is. The visible caret is still drawn by the painting code. </li> <li> On GTK+, Scintilla has methods to read the target as UTF-8 and to convert a string from UTF-8 to the document encoding. This eases integration with containers that use the UTF-8 encoding which is the API encoding for GTK+ 2. </li> <li> SciTE on GTK+2 and Windows NT/2000/XP allows search and replace of Unicode text. </li> <li> SciTE calltips allow setting the characters used to start and end parameter lists and to separate parameters. </li> <li> FindColumn method converts a line and column into a position, taking into account tabs and multi-byte characters. </li> <li> On Windows, when Scintilla copies text to the clipboard as Unicode, it avoids adding an ANSI copy as the system will automatically convert as required in a context-sensitive manner. </li> <li> SciTE indent.auto setting automatically determines indent.size and use.tabs from document contents. </li> <li> SciTE defines a CurrentMessage property that holds the most recently selected output pane message. </li> <li> SciTE Lua scripting enhanced with <ul> <li>A Lua table called 'buffer' is associated with each buffer and can be used to maintain buffer-specific state.</li> <li>A 'scite' object allows interaction with the application such as opening files from script.</li> <li>Dynamic properties can be reset by assigning nil to a given key in the props table.</li> <li>An 'OnClear' event fires whenever properties and extension scripts are about to be reloaded.</li> <li>On Windows, loadlib is enabled and can be used to access Lua binary modules / DLLs.</li></ul> </li> <li> SciTE Find in Files on Windows can be used in a modeless way and gains a '..' button to move up to the parent directory. It is also wider so that longer paths can be seen. </li> <li> Close buttons added to dialogs in SciTE on Windows. </li> <li> SciTE on GTK+ 2 has a "hidden files" check box in file open dialog. </li> <li> SciTE use.monospaced setting removed. More information in the <a href="SciTEFAQ.html">FAQ</a>. </li> <li> APDL lexer updated with more lexical classes </li> <li> AutoIt3 lexer updated. </li> <li> Ada lexer fixed to support non-ASCII text. </li> <li> Cpp lexer now only matches exactly three slashes as starting a doc-comment so that lines of slashes are seen as a normal comment. Line ending characters are appear in default style on preprocessor and single line comment lines. </li> <li> CSS lexer updated to support CSS2 including second set of keywords. </li> <li> Errorlist lexer now understands Java stack trace lines. </li> <li> SciTE's handling of HTML Tidy messages jumps to column as well as line indicated. </li> <li> Lisp lexer allows multiline strings. </li> <li> Lua lexer treats .. as an operator when between identifiers. </li> <li> PHP lexer handles 'e' in numerical literals. </li> <li> PowerBasic lexer updated for macros and optimised. </li> <li> Properties file folder changed to leave lines before a header at the base level and thus avoid a vertical line when using connected folding symbols. </li> <li> GTK+ on Windows version uses Alt for rectangular selection to be compatible with platform convention. </li> <li> SciTE abbreviations file moved from system directory to user directory so each user can have separate abbreviations. </li> <li> SciTE on GTK+ has improved .desktop file and make install support that may lead to better integration with system shell. </li> <li> Disabling of themed background drawing on GTK+ extended to all cases. </li> <li> SciTE date formatting on Windows performed with the user setting rather than the system setting. </li> <li> GTK+ 2 redraw while scrolling fixed. </li> <li> Recursive property definitions are safer, avoiding expansion when detected. </li> <li> SciTE thread synchronization for scripts no longer uses HWND_MESSAGE so is compatible with older versions of Windows. Other Lua scripting bugs fixed. </li> <li> SciTE on Windows localisation of menu accelerators changed to be compatible with alternative UI themes. </li> <li> SciTE on Windows full screen mode now fits better when menu different height to title bar height. </li> <li> SC_MARK_EMPTY marker is now invisible and does not change the background colour. </li> <li> Bug fixed in HTML lexer to allow use of <?xml in strings in scripts without triggering xml mode. </li> <li> Bug fixed in SciTE abbreviation expansion that could break indentation or crash. </li> <li> Bug fixed when searching for a whole word string that ends one character before end of document. </li> <li> Drawing bug fixed when indicators drawn on wrapped lines. </li> <li> Bug fixed when double clicking a hotspot. </li> <li> Bug fixed where autocompletion would remove typed text if no match found. </li> <li> Bug fixed where display does not scroll when inserting in long wrapped line. </li> <li> Bug fixed where SCI_MARKERDELETEALL would only remove one of the markers on a line that contained multiple markers with the same number. </li> <li> Bug fixed where markers would move when converting line endings. </li> <li> Bug fixed where SCI_LINEENDWRAP would move too far when line ends are visible. </li> <li> Bugs fixed where calltips with unicode or other non-ASCII text would display incorrectly. </li> <li> Bug fixed in determining if at save point after undoing from save point and then performing changes. </li> <li> Bug fixed on GTK+ using unsupported code pages where extraneous text could be drawn. </li> <li> Bug fixed in drag and drop code on Windows where dragging from SciTE to Firefox could hang both applications. </li> <li> Crashing bug fixed on GTK+ when no font allocation succeeds. </li> <li> Crashing bug fixed when autocompleting word longer than 1000 characters. </li> <li> SciTE crashing bug fixed when both Find and Replace dialogs shown by disallowing this situation. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite161.zip?download">Release 1.61</a> </h3> <ul> <li> Released on 29 May 2004. </li> <li> Improvements to selection handling on GTK+. </li> <li> SciTE on GTK+ 2.4 uses the improved file chooser which allows file extension filters, multiple selection, and remembers favourite directories. </li> <li> SciTE Load Session and Save Session commands available on GTK+. </li> <li> SciTE lists Lua Startup Script in Options menu when loaded. </li> <li> In SciTE, OnUserListSelection can be implemented in Lua. </li> <li> SciTE on Windows has a context menu on the file tabs. </li> <li> SQL lexer allows '#' comments and optionally '\' quoting inside strings. </li> <li> Mssql lexer improved. </li> <li> AutoIt3 lexer updated. </li> <li> Perl lexer recognises regular expression use better. </li> <li> Errorlist lexer understands Lua tracebacks and copes with findstr output for file names that end with digits. </li> <li> Drawing of lines on GTK+ improved and made more like Windows without final point. </li> <li> SciTE on GTK+ uses a high resolution window icon. </li> <li> SciTE can be set to warn before loading files larger than a particular size. </li> <li> SciTE Lua scripting bugs fixed included a crashing bug when using an undefined function name that would go before first actual name. </li> <li> SciTE bug fixed where a modified buffer was not saved if it was the last buffer and was not current when the New command used. </li> <li> SciTE monofont mode no longer affects line numbers. </li> <li> Crashing bug in SciTE avoided by not allowing both the Find and Replace dialogs to be visible at one time. </li> <li> Crashing bug in SciTE fixed when Lua scripts were being run concurrently. </li> <li> Bug fixed that caused incorrect line number width in SciTE. </li> <li> PHP folding bug fixed. </li> <li> Regression fixed when setting word characters to not include some of the standard word characters. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite160.zip?download">Release 1.60</a> </h3> <ul> <li> Released on 1 May 2004. </li> <li> SciTE can be scripted using the Lua programming language. </li> <li> command.mode is a better way to specify tool command options in SciTE. </li> <li> Continuation markers can be displayed so that you can see which lines are wrapped. </li> <li> Lexer for Gui4Cli language. </li> <li> Lexer for Kix language. </li> <li> Lexer for Specman E language. </li> <li> Lexer for AutoIt3 language. </li> <li> Lexer for APDL language. </li> <li> Lexer for Bash language. Also reasonable for other Unix shells. </li> <li> SciTE can load lexers implemented in external shared libraries. </li> <li> Perl treats "." not as part of an identifier and interprets '/' and '->' correctly in more circumstances. </li> <li> PHP recognises variables within strings. </li> <li> NSIS has properties "nsis.uservars" and "nsis.ignorecase". </li> <li> MSSQL lexer adds keyword list for operators and stored procedures, defines '(', ')', and ',' as operators and changes some other details. </li> <li> Input method preedit window on GTK+ 2 may support some Asian languages. </li> <li> Platform interface adds an extra platform-specific flag to Font::Create. Used on wxWidgets to choose antialiased text display but may be used for any task that a platform needs. </li> <li> OnBeforeSave method added to Extension interface. </li> <li> Scintilla methods that return strings can be called with a NULL pointer to find out how long the string should be. </li> <li> Visual Studio .NET project file now in VS .NET 2003 format so can not be used directly in VS .NET 2002. </li> <li> Scintilla can be built with GTK+ 2 on Windows. </li> <li> Updated RPM spec for SciTE on GTK+. </li> <li> GTK+ makefile for SciTE allows selection of destination directory, creates destination directories and sets file modes and owners better. </li> <li> Tab indents now go to next tab multiple rather than add tab size. </li> <li> SciTE abbreviations now use the longest possible match rather than the shortest. </li> <li> Autocompletion does not remove prefix when actioned with no choice selected. </li> <li> Autocompletion cancels when moving beyond the start position, not at the start position. </li> <li> SciTE now shows only calltips for functions that match exactly, not those that match as a prefix. </li> <li> SciTE can repair box comment sections where some lines were added without the box comment middle line prefix. </li> <li> Alt+ works in user.shortcuts on Windows. </li> <li> SciTE on GTK+ enables replace in selection for rectangular selections. </li> <li> Key bindings for command.shortcut implemented in a way that doesn't break when the menus are localised. </li> <li> Drawing of background on GTK+ faster as theme drawing disabled. </li> <li> On GTK+, calltips are moved back onto the screen if they extend beyond the screen bounds. </li> <li> On Windows, the Scintilla object is destroyed on WM_NCDESTROY rather than WM_DESTROY which arrives earlier. This fixes some problems when Scintilla was subclassed. </li> <li> The zorder switching feature removed due to number of crashing bugs. </li> <li> Code for XPM images made more robust. </li> <li> Bug fixed with primary selection on GTK+. </li> <li> On GTK+ 2, copied or cut text can still be pasted after the Scintilla widget is destroyed. </li> <li> Styling change not visible problem fixed when line was cached. </li> <li> Bug in SciTE on Windows fixed where clipboard commands stopped working. </li> <li> Crashing bugs in display fixed in line layout cache. </li> <li> Crashing bug may be fixed on AMD64 processor on GTK+. </li> <li> Rare hanging crash fixed in Python lexer. </li> <li> Display bugs fixed with DBCS characters on GTK+. </li> <li> Autocompletion lists on GTK+ 2 are not sorted by the ListModel as the contents are sorted correctly by Scintilla. </li> <li> SciTE fixed to not open extra untitled buffers with check.if.already.open. </li> <li> Sizing bug fixed on GTK+ when window resized while unmapped. </li> <li> Text drawing crashing bug fixed on GTK+ with non-Pango fonts and long strings. </li> <li> Fixed some issues if characters are unsigned. </li> <li> Fixes in NSIS support. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite159.zip?download">Release 1.59</a> </h3> <ul> <li> Released on 19 February 2004. </li> <li> SciTE Options and Language menus reduced in length by commenting out some languages. Languages can be enabled by editing the global properties file. </li> <li> Verilog language supported. </li> <li> Lexer for Microsoft dialect of SQL. SciTE properties file available from extras page. </li> <li> Perl lexer disambiguates '/' better. </li> <li> NSIS lexer improved with a lexical class for numbers, option for ignoring case of keywords, and folds only occurring when folding keyword first on line. </li> <li> PowerBasic lexer improved with styles for constants and assembler and folding improvements. </li> <li> On GTK+, input method support only invoked for Asian languages and not European languages as the old European keyboard code works better. </li> <li> Scintilla can be requested to allocate a certain amount and so avoid repeated reallocations and memory inefficiencies. SciTE uses this and so should require less memory. </li> <li> SciTE's "toggle current fold" works when invoked on child line as well as fold header. </li> <li> SciTE output pane scrolling can be set to not scroll back to start after completion of command. </li> <li> SciTE has a $(SessionPath) property. </li> <li> SciTE on Windows can use VK_* codes for keys in user.shortcuts. </li> <li> Stack overwrite bug fixed in SciTE's command to move to the end of a preprocessor conditional. </li> <li> Bug fixed where vertical selection appeared to select a different set of characters then would be used by, for example, a copy. </li> <li> SciTE memory leak fixed in fold state remembering. </li> <li> Bug fixed where changing the style of some text outside the standard StyleNeeded notification would not be visible. </li> <li> On GTK+ 2 g_iconv is used in preference to iconv, as it is provided by GTK+ so should avoid problems finding the iconv library. </li> <li> On GTK+ fixed a style reference count bug. </li> <li> Memory corruption bug fixed with GetSelText. </li> <li> On Windows Scintilla deletes memory on WM_NCDESTROY rather than the earlier WM_DESTROY to avoid problems when the window is subclassed. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite158.zip?download">Release 1.58</a> </h3> <ul> <li> Released on 11 January 2004. </li> <li> Method to discover the currently highlighted element in an autocompletion list. </li> <li> On GTK+, the lexers are now included in the scintilla.a library file. This will require changes to the make files of dependent projects. </li> <li> Octave support added alongside related Matlab language and Matlab support improved. </li> <li> VB lexer gains an unterminated string state and 4 sets of keywords. </li> <li> Ruby lexer handles $' correctly. </li> <li> Error line handling improved for FORTRAN compilers from Absoft and Intel. </li> <li> International input enabled on GTK+ 2 although there is no way to choose an input method. </li> <li> MultiplexExtension in SciTE allows multiple extensions to be used at once. </li> <li> Regular expression replace interprets backslash expressions \a, \b, \f, \n, \r, \t, and \v in the replacement value. </li> <li> SciTE Replace dialog displays number of replacements made when Replace All or Replace in Selection performed. </li> <li> Localisation files may contain a translation.encoding setting which is used on GTK+ 2 to automatically reencode the translation to UTF-8 so it will be the localised text will be displayed correctly. </li> <li> SciTE on GTK+ implements check.if.already.open. </li> <li> Make files for Mac OS X made more robust. </li> <li> Performance improved in SciTE when switching buffers when there is a rectangular selection. </li> <li> Fixed failure to display some text when wrapped. </li> <li> SciTE crashes from Ctrl+Tab buffer cycling fixed. May still be some rare bugs here. </li> <li> Crash fixed when decoding an error message that appears similar to a Borland error message. </li> <li> Fix to auto-scrolling allows containers to implement enhanced double click selection. </li> <li> Hang fixed in idle word wrap. </li> <li> Crash fixed in hotspot display code.. </li> <li> SciTE on Windows Incremental Search no longer moves caret back. </li> <li> SciTE hang fixed when performing a replace with a find string that matched zero length strings such as ".*". </li> <li> SciTE no longer styles the whole file when saving buffer fold state as that was slow. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite157.zip?download">Release 1.57</a> </h3> <ul> <li> Released on 27 November 2003. </li> <li> SciTE remembers folding of each buffer. </li> <li> Lexer for Erlang language. </li> <li> Scintilla allows setting the set of white space characters. </li> <li> Scintilla has 'stuttered' page movement commands to first move to top or bottom within current visible lines before scrolling. </li> <li> Scintilla commands for moving to end of words. </li> <li> Incremental line wrap enabled on Windows. </li> <li> SciTE PDF exporter produces output that is more compliant with reader applications, is smaller and allows more configuration. HTML exporter optimizes size of output files. </li> <li> SciTE defines properties PLAT_WINNT and PLAT_WIN95 on the corresponding platforms. </li> <li> SciTE can adjust the line margin width to fit the largest line number. The line.numbers property is split between line.margin.visible and line.margin.width. </li> <li> SciTE on GTK+ allows user defined menu accelerators. Alt can be included in user.shortcuts. </li> <li> SciTE Language menu can have items commented out. </li> <li> SciTE on Windows Go to dialog allows choosing a column number as well as a line number. </li> <li> SciTE on GTK+ make file uses prefix setting more consistently. </li> <li> Bug fixed that caused word wrapping to fail to display all text. </li> <li> Crashing bug fixed in GTK+ version of Scintilla when using GDK fonts and opening autocompletion. </li> <li> Bug fixed in Scintilla SCI_GETSELTEXT where an extra NUL was included at end of returned string </li> <li> Crashing bug fixed in SciTE z-order switching implementation. </li> <li> Hanging bug fixed in Perl lexer. </li> <li> SciTE crashing bug fixed for using 'case' without argument in style definition. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite156.zip?download">Release 1.56</a> </h3> <ul> <li> Released on 25 October 2003. </li> <li> Rectangular selection can be performed using the keyboard. Greater programmatic control over rectangular selection. This has caused several changes to key bindings. </li> <li> SciTE Replace In Selection works on rectangular selections. </li> <li> Improved lexer for TeX, new lexer for Metapost and other support for these languages. </li> <li> Lexer for PowerBasic. </li> <li> Lexer for Forth. </li> <li> YAML lexer improved to include error styling. </li> <li> Perl lexer improved to correctly handle more cases. </li> <li> Assembler lexer updated to support single-quote strings and fix some problems. </li> <li> SciTE on Windows can switch between buffers in order of use (z-order) rather than static order. </li> <li> SciTE supports adding an extension for "Open Selected Filename". The openpath setting works on GTK+. </li> <li> SciTE can Export as XML. </li> <li> SciTE $(SelHeight) variable gives a more natural result for empty and whole line selections. </li> <li> Fixes to wrapping problems, such as only first display line being visible in some cases. </li> <li> Fixes to hotspot to only highlight when over the hotspot, only use background colour when set and option to limit hotspots to a single line. </li> <li> Small fixes to FORTRAN lexing and folding. </li> <li> SQL lexer treats single quote strings as a separate class to double quote strings.. </li> <li> Scintilla made compatible with expectations of container widget in GTK+ 2.3. </li> <li> Fix to strip out pixmap ID when automatically choosing from an autocompletion list with only one element. </li> <li> SciTE bug fixed where UTF-8 files longer than 128K were gaining more than one BOM. </li> <li> Crashing bug fixed in SciTE on GTK+ where using "Stop Executing" twice leads to all applications exiting. </li> <li> Bug fixed in autocompletion scrolling on GTK+ 2 with a case sensitive list. The ListBox::Sort method is no longer needed or available so platform maintainers should remove it. </li> <li> SciTE check.if.already.open setting removed from GTK+ version as unmaintained. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite155.zip?download">Release 1.55</a> </h3> <ul> <li> Released on 25 September 2003. </li> <li> Fix a crashing bug in indicator display in Scintilla. </li> <li> GTK+ version now defaults to building for GTK+ 2 rather than 1. </li> <li> Mingw make file detects compiler version and avoids options that are cause problems for some versions. </li> <li> Large performance improvement on GTK+ 2 for long lines. </li> <li> Incremental line wrap on GTK+. </li> <li> International text entry works much better on GTK+ with particular improvements for Baltic languages and languages that use 'dead' accents. NUL key events such as those generated by some function keys, ignored. </li> <li> Unicode clipboard support on GTK+. </li> <li> Indicator type INDIC_BOX draws a rectangle around the text. </li> <li> Clarion language support. </li> <li> YAML language support. </li> <li> MPT LOG language support. </li> <li> On Windows, SciTE can switch buffers based on activation order rather than buffer number. </li> <li> SciTE save.on.deactivate saves all buffers rather than just the current buffer. </li> <li> Lua lexer handles non-ASCII characters correctly. </li> <li> Error lexer understands Borland errors with pathnames that contain space. </li> <li> On GTK+ 2, autocompletion uses TreeView rather than deprecated CList. </li> <li> SciTE autocompletion removed when expand abbreviation command used. </li> <li> SciTE calltips support overloaded functions. </li> <li> When Save fails in SciTE, choice offered to Save As. </li> <li> SciTE message boxes on Windows may be moved to front when needed. </li> <li> Indicators drawn correctly on wrapped lines. </li> <li> Regular expression search no longer matches characters with high bit set to characters without high bit set. </li> <li> Hang fixed in backwards search in multi byte character documents. </li> <li> Hang fixed in SciTE Mark All command when wrap around turned off. </li> <li> SciTE Incremental Search no longer uses hot keys on Windows. </li> <li> Calltips draw non-ASCII characters correctly rather than as arrows. </li> <li> SciTE crash fixed when going to an error message with empty file name. </li> <li> Bugs fixed in XPM image handling code. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite154.zip?download">Release 1.54</a> </h3> <ul> <li> Released on 12 August 2003. </li> <li> SciTE on GTK+ 2.x can display a tab bar. </li> <li> SciTE on Windows provides incremental search. </li> <li> Lexer for PostScript. </li> <li> Lexer for the NSIS scripting language. </li> <li> New lexer for POV-Ray Scene Description Language replaces previous implementation. </li> <li> Lexer for the MMIX Assembler language. </li> <li> Lexer for the Scriptol language. </li> <li> Incompatibility: SQL keywords are specified in lower case rather than upper case. SQL lexer allows double quoted strings. </li> <li> Pascal lexer: character constants that start with '#' understood, '@' only allowed within assembler blocks, '$' can be the start of a number, initial '.' in 0..constant not treated as part of a number, and assembler blocks made more distinctive. </li> <li> Lua lexer allows '.' in keywords. Multi-line strings and comments can be folded. </li> <li> CSS lexer handles multiple psuedoclasses. </li> <li> Properties file folder works for INI file format. </li> <li> Hidden indicator style allows the container to mark text within Scintilla without there being any visual effect. </li> <li> SciTE does not prompt to save changes when the buffer is empty and untitled. </li> <li> Modification notifications caused by SCI_INSERTSTYLEDSTRING now include the contents of the insertion. </li> <li> SCI_MARKERDELETEALL deletes all the markers on a line rather than just the first match. </li> <li> Better handling of 'dead' accents on GTK+ 2 for languages that use accented characters. </li> <li> SciTE now uses value of output.vertical.size property. </li> <li> Crash fixed in SciTE autocompletion on long lines. </li> <li> Crash fixed in SciTE comment command on long lines. </li> <li> Bug fixed with backwards regular expression search skipping every second match. </li> <li> Hang fixed with regular expression replace where both target and replacement were empty. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite153.zip?download">Release 1.53</a> </h3> <ul> <li> Released on 16 May 2003. </li> <li> On GTK+ 2, encodings other than ASCII, Latin1, and Unicode are supported for both display and input using iconv. </li> <li> External lexers supported on GTK+/Linux. External lexers must now be explicitly loaded with SCI_LOADLEXERLIBRARY rather than relying upon a naming convention and automatic loading. </li> <li> Support of Lout typesetting language. </li> <li> Support of E-Scripts language used in the POL Ultima Online Emulator. </li> <li> Scrolling and drawing performance on GTK+ enhanced, particularly for GTK+ 2.x with an extra window for the text area avoiding conflicts with the scroll bars. </li> <li> CopyText and CopyRange methods in Scintilla allow container to easily copy to the system clipboard. </li> <li> Line Copy command implemented and bound to Ctrl+Shift+T. </li> <li> Scintilla APIs PositionBefore and PositionAfter can be used to iterate through a document taking into account the encoding and multi-byte characters. </li> <li> C++ folder can fold on the "} else {" line of an if statement by setting fold.at.else property to 1. </li> <li> C++ lexer allows an extra set of keywords. </li> <li> Property names and thus abbreviations may be non-ASCII. </li> <li> Removed attempt to load a file when setting properties that was part of an old scripting experiment. </li> <li> SciTE no longer warns about a file not existing when opening properties files from the Options menu as there is a good chance the user wants to create one. </li> <li> Bug fixed with brace recognition in multi-byte encoded files where a partial character matched a brace byte. </li> <li> More protection against infinite loops or recursion with recursive property definitions. </li> <li> On Windows, cursor will no longer disappear over margins in custom builds when cursor resource not present. The Windows default cursor is displayed instead. </li> <li> load.on.activate fixed in SciTE as was broken in 1.52. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite152.zip?download">Release 1.52</a> </h3> <ul> <li> Released on 17 April 2003. </li> <li> Pango font support on GTK+ 2. Unicode input improved on GTK+ 2. </li> <li> Hotspot style implemented in Scintilla. </li> <li> Small up and down arrows can be displayed in calltips and the container is notified when the mouse is clicked on a calltip. Normal and selected calltip text colours can be set. </li> <li> POSIX compatibility flag in Scintilla regular expression search interprets bare ( and ) as tagged sections. </li> <li> Error message lexer tightened to yield fewer false matches. Recognition of Lahey and Intel FORTRAN error formats. </li> <li> Scintilla keyboard commands for moving to start and end of screen lines rather than document lines, unless already there where these keys move to the start or end of the document line. </li> <li> Line joining command. </li> <li> Lexer for POV-Ray. </li> <li> Calltips on Windows are no longer clipped by the parent window. </li> <li> Autocompletion lists are cancelled when focus leaves their parent window. </li> <li> Move to next/previous empty line delimited paragraph key commands. </li> <li> SciTE hang fixed with recursive property definitions by placing limit on number of substitutions performed. </li> <li> SciTE Export as PDF reenabled and works. </li> <li> Added loadsession: command line command to SciTE. </li> <li> SciTE option to quit application when last document closed. </li> <li> SciTE option to ask user if it is OK to reload a file that has been modified outside SciTE. </li> <li> SciTE option to automatically save before running particular command tools or to ask user or to not save. </li> <li> SciTE on Windows 9x will write a Ctrl+Z to the process input pipe before closing the pipe when running tool commands that take input. </li> <li> Added a manifest resource to SciTE on Windows to enable Windows XP themed UI. </li> <li> SciTE calltips handle nested calls and other situations better. </li> <li> CSS lexer improved. </li> <li> Interface to platform layer changed - Surface initialisation now requires a WindowID parameter. </li> <li> Bug fixed with drawing or measuring long pieces of text on Windows 9x by truncating the pieces. </li> <li> Bug fixed with SciTE on GTK+ where a user shortcut for a visible character inserted the character as well as executing the command. </li> <li> Bug fixed where primary selection on GTK+ was reset by Scintilla during creation. </li> <li> Bug fixed where SciTE would close immediately on startup when using save.session. </li> <li> Crash fixed when entering '\' in LaTeX file. </li> <li> Hang fixed when '#' last character in VB file. </li> <li> Crash fixed in error message lexer. </li> <li> Crash fixed when searching for long regular expressions. </li> <li> Pressing return when nothing selected in user list sends notification with empty text rather than random text. </li> <li> Mouse debouncing disabled on Windows as it interfered with some mouse utilities. </li> <li> Bug fixed where overstrike mode inserted before rather than replaced last character in document. </li> <li> Bug fixed with syntax highlighting of Japanese text. </li> <li> Bug fixed in split lines function. </li> <li> Cosmetic fix to SciTE tab bar on Windows when window resized. Focus sticks to either pane more consistently. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite151.zip?download">Release 1.51</a> </h3> <ul> <li> Released on 16 February 2003. </li> <li> Two phase drawing avoids cutting off text that overlaps runs by drawing all the backgrounds of a line then drawing all the text transparently. Single phase drawing is an option. </li> <li> Scintilla method to split lines at a particular width by adding new line characters. </li> <li> The character used in autocompletion lists to separate the text from the image number can be changed. </li> <li> The scrollbar range will automatically expand when the caret is moved beyond the current range. The scroll bar is updated when SCI_SETXOFFSET is called. </li> <li> Mouse cursors on GTK+ improved to be consistent with other applications and the Windows version. </li> <li> Horizontal scrollbar on GTK+ now disappears in wrapped mode. </li> <li> Scintilla on GTK+ 2: mouse wheel scrolling, cursor over scrollbars, focus, and syntax highlighting now work. gtk_selection_notify avoided for compatibility with GTK+ 2.2. </li> <li> Fold margin colours can now be set. </li> <li> SciTE can be built for GTK+ 2. </li> <li> SciTE can optionally preserve the undo history over an automatic file reload. </li> <li> Tags can optionally be case insensitive in XML and HTML. </li> <li> SciTE on Windows handles input to tool commands in a way that should avoid deadlock. Output from tools can be used to replace the selection. </li> <li> SciTE on GTK+ automatically substitutes '|' for '/' in menu items as '/' is used to define the menu hierarchy. </li> <li> Optional buffer number in SciTE title bar. </li> <li> Crash fixed in SciTE brace matching. </li> <li> Bug fixed where automatic scrolling past end of document flipped back to the beginning. </li> <li> Bug fixed where wrapping caused text to disappear. </li> <li> Bug fixed on Windows where images in autocompletion lists were shown on the wrong item. </li> <li> Crash fixed due to memory bug in autocompletion lists on Windows. </li> <li> Crash fixed when double clicking some error messages. </li> <li> Bug fixed in word part movement where sometimes no movement would occur. </li> <li> Bug fixed on Windows NT where long text runs were truncated by treating NT differently to 9x where there is a limitation. </li> <li> Text in not-changeable style works better but there remain some cases where it is still possible to delete text protected this way. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite150.zip?download">Release 1.50</a> </h3> <ul> <li> Released on 24 January 2003. </li> <li> Autocompletion lists may have a per-item pixmap. </li> <li> Autocompletion lists allow Unicode text on Windows. </li> <li> Scintilla documentation rewritten. </li> <li> Additional DBCS encoding support in Scintilla on GTK+ primarily aimed at Japanese EUC encoding. </li> <li> CSS (Cascading Style Sheets) lexer added. </li> <li> diff lexer understands some more formats. </li> <li> Fold box feature is an alternative way to show the structure of code. </li> <li> Avenue lexer supports multiple keyword lists. </li> <li> The caret may now be made invisible by setting the caret width to 0. </li> <li> Python folder attaches comments before blocks to the next block rather than the previous block. </li> <li> SciTE openpath property on Windows searches a path for files that are the subject of the Open Selected Filename command. </li> <li> The localisation file name can be changed with the locale.properties property. </li> <li> On Windows, SciTE can pipe the result of a string expression into a command line tool. </li> <li> On Windows, SciTE's Find dialog has a Mark All button. </li> <li> On Windows, there is an Insert Abbreviation command that allows a choice from the defined abbreviations and inserts the selection into the abbreviation at the position of a '|'. </li> <li> Minor fixes to Fortran lexer. </li> <li> fold.html.preprocessor decides whether to fold <? and ?>. Minor improvements to PHP folding. </li> <li> Maximum number of keyword lists allowed increased from 6 to 9. </li> <li> Duplicate line command added with default assignment to Ctrl+D. </li> <li> SciTE sets $(Replacements) to the number of replacements made by the Replace All command. $(CurrentWord) is set to the word before the caret if the caret is at the end of a word. </li> <li> Opening a SciTE session now loads files in remembered order, sets the current file as remembered, and moves the caret to the remembered line. </li> <li> Bugs fixed with printing on Windows where line wrapping was causing some text to not print. </li> <li> Bug fixed with Korean Input Method Editor on Windows. </li> <li> Bugs fixed with line wrap which would sometimes choose different break positions after switching focus away and back. </li> <li> Bug fixed where wheel scrolling had no effect on GTK+ after opening a fold. </li> <li> Bug fixed with file paths containing non-ASCII characters on Windows. </li> <li> Crash fixed with printing on Windows after defining pixmap marker. </li> <li> Crash fixed in makefile lexer when first character on line was '='. </li> <li> Bug fixed where local properties were not always being applied. </li> <li> Ctrl+Keypad* fold command works on GTK+. </li> <li> Hangs fixed in SciTE's Replace All command when replacing regular expressions '^' or '$'. </li> <li> SciTE monospace setting behaves more sensibly. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite149.zip?download">Release 1.49</a> </h3> <ul> <li> Released on 1 November 2002. </li> <li> Unicode supported on GTK+. To perform well, this added a font cache to GTK+ and to make that safe, a mutex is used. The mutex requires the application to link in the threading library by evaluating `glib-config --libs gthread`. A Unicode locale should also be set up by a call like setlocale(LC_CTYPE, "en_US.UTF-8"). scintilla_release_resources function added to release mutex. </li> <li> FORTRAN and assembler lexers added along with other support for these languages in SciTE. </li> <li> Ada lexer improved handling of based numbers, identifier validity and attributes distinguished from character literals. </li> <li> Lua lexer handles block comments and a deep level of nesting for literal strings and block comments. </li> <li> Errorlist lexer recognises PHP error messages. </li> <li> Variant of the C++ lexer with case insensitive keywords called cppnocase. Whitespace in preprocessor text handled more correctly. </li> <li> Folder added for Perl. </li> <li> Compilation with GCC 3.2 supported. </li> <li> Markers can be pixmaps. </li> <li> Lines are wrapped when printing. Bug fixed which printed line numbers in different styles. </li> <li> Text can be appended to end with AppendText method. </li> <li> ChooseCaretX method added. </li> <li> Vertical scroll bar can be turned off with SetVScrollBar method. </li> <li> SciTE Save All command saves all buffers. </li> <li> SciTE localisation compares keys case insensitively to make translations more flexible. </li> <li> SciTE detects a utf-8 coding cookie "coding: utf-8" in first two lines and goes into Unicode mode. </li> <li> SciTE key bindings are definable. </li> <li> SciTE Find in Files dialog can display directory browser to choose directory to search. </li> <li> SciTE enabling of undo and redo toolbar buttons improved. </li> <li> SciTE on Windows file type filters in open dialog sorted. </li> <li> Fixed crashing bug when using automatic tag closing in XML or HTML. </li> <li> Fixed bug on Windows causing very long (>64K) lines to not display. </li> <li> Fixed bug in backwards regular expression searching. </li> <li> Fixed bug in calltips where wrong argument was highlighted. </li> <li> Fixed bug in tab timmy feature when file has line feed line endings. </li> <li> Fixed bug in compiling without INCLUDE_DEPRECATED_FEATURES defined. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite148.zip?download">Release 1.48</a> </h3> <ul> <li> Released on 9 September 2002. </li> <li> Improved Pascal lexer with context sensitive keywords and separate folder which handles //{ and //} folding comments and {$region} and {$end} folding directives. The "case" statement now folds correctly. </li> <li> C++ lexer correctly handles comments on preprocessor lines. </li> <li> New commands for moving to beginning and end of display lines when in line wrap mode. Key bindings added for these commands. </li> <li> New marker symbols that look like ">>>" and "..." which can be used for interactive shell prompts for Python. </li> <li> The foreground and background colours of visible whitespace can be chosen independent of the colours chosen for the lexical class of that whitespace. </li> <li> Per line data optimised by using an exponential allocation scheme. </li> <li> SciTE API file loading optimised. </li> <li> SciTE for GTK+ subsystem 2 documented. The exit status of commands is decoded into more understandable fields. </li> <li> SciTE find dialog remembers previous find string when there is no selection. Find in Selection button disabled when selection is rectangular as command did not work. </li> <li> Shift+Enter made equivalent to Enter to avoid users having to let go of the shift key when typing. Avoids the possibility of entering single carriage returns in a file that contains CR+LF line ends. </li> <li> Autocompletion does not immediately disappear when the length parameter to SCI_AUTOCSHOW is 0. </li> <li> SciTE focuses on the editor pane when File | New executed and when the output pane is closed with F8. Double clicking on a non-highlighted output pane line selects the word under the cursor rather than seeking the next highlighted line. </li> <li> SciTE director interface implements an "askproperty" command. </li> <li> SciTE's Export as LaTeX output improved. </li> <li> Better choice of autocompletion displaying above the caret rather then below when that is more sensible. </li> <li> Bug fixed where context menu would not be completely visible if invoked when cursor near bottom or left of screen. </li> <li> Crashing bug fixed when displaying long strings on GTK+ caused failure of X server by displaying long text in segments. </li> <li> Crashing bug fixed on GTK+ when a Scintilla window was removed from its parent but was still the selection owner. </li> <li> Bug fixed on Windows in Unicode mode where not all characters on a line were displayed when that line contained some characters not in ASCII. </li> <li> Crashing bug fixed in SciTE on Windows with clearing output while running command. </li> <li> Bug fixed in SciTE for GTK+ with command completion not detected when no output was produced by the command. </li> <li> Bug fixed in SciTE for Windows where menus were not shown translated. </li> <li> Bug fixed where words failed to display in line wrapping mode with visible line ends. </li> <li> Bug fixed in SciTE where files opened from a session file were not closed. </li> <li> Cosmetic flicker fixed when using Ctrl+Up and Ctrl+Down with some caret policies. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite147.zip?download">Release 1.47</a> </h3> <ul> <li> Released on 1 August 2002. </li> <li> Support for GTK+ 2 in Scintilla. International input methods not supported on GTK+2. </li> <li> Line wrapping performance improved greatly. </li> <li> New caret policy implementation that treats horizontal and vertical positioning equivalently and independently. Old caret policy methods deprecated and not all options work correctly with old methods. </li> <li> Extra fold points for C, C++, Java, ... for fold comments //{ .. //} and #if / #ifdef .. #endif and the #region .. #endregion feature of C#. </li> <li> Scintilla method to find the height in pixels of a line. Currently returns the same result for every line as all lines are same height. </li> <li> Separate make file, scintilla_vc6.mak, for Scintilla to use Visual C++ version 6 since main makefile now assumes VS .NET. VS .NET project files available for combined Scintilla and SciTE in scite/boundscheck. </li> <li> SciTE automatically recognises Unicode files based on their Byte Order Marks and switches to Unicode mode. On Windows, where SciTE supports Unicode display, this allows display of non European characters. The file is saved back into the same character encoding unless the user decides to switch using the File | Encoding menu. </li> <li> Handling of character input changed so that a fillup character, typically '(' displays a calltip when an autocompletion list was being displayed. </li> <li> Multiline strings lexed better for C++ and Lua. </li> <li> Regular expressions in JavaScript within hypertext files are lexed better. </li> <li> On Windows, Scintilla exports a function called Scintilla_DirectFunction that can be used the same as the function returned by GetDirectFunction. </li> <li> Scintilla converts line endings of text obtained from the clipboard to the current default line endings. </li> <li> New SciTE property ensure.final.line.end can ensure that saved files always end with a new line as this is required by some tools. The ensure.consistent.line.ends property ensures all line ends are the current default when saving files. The strip.trailing.spaces property now works on the buffer so the buffer in memory and the file on disk are the same after a save is performed. </li> <li> The SciTE expand abbreviation command again allows '|' characters in expansions to be quoted by using '||'. </li> <li> SciTE on Windows can send data to the find tool through standard input rather than using a command line argument to avoid problems with quoting command line arguments. </li> <li> The Stop Executing command in SciTE on Windows improved to send a Ctrl+Z character to the tool. Better messages when stopping a tool. </li> <li> Autocompletion can automatically "fill up" when one of a set of characters is type with the autocomplete.<lexer>.fillups property. </li> <li> New predefined properties in SciTE, SelectionStartColumn, SelectionStartLine, SelectionEndColumn, SelectionEndLine can be used to integrate with other applications. </li> <li> Environment variables are available as properties in SciTE. </li> <li> SciTE on Windows keeps status line more current. </li> <li> Abbreviations work in SciTE on Linux when first opened. </li> <li> File saving fixed in SciTE to ensure files are not closed when they can not be saved because of file permissions. Also fixed a problem with buffers that caused files to not be saved. </li> <li> SciTE bug fixed where monospace mode not remembered when saving files. Some searching options now remembered when switching files. </li> <li> SciTE on Linux now waits on child termination when it shuts a child down to avoid zombies. </li> <li> SciTE on Linux has a Print menu command that defaults to invoking a2ps. </li> <li> Fixed incorrect highlighting of indentation guides in SciTE for Python. </li> <li> Crash fixed in Scintilla when calling GetText for 0 characters. </li> <li> Exporting as LaTeX improved when processing backslashes and tabs and setting up font. </li> <li> Crash fixed in SciTE when exporting or copying as RTF. </li> <li> SciTE session loading fixed to handle more than 10 files in session. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite146.zip?download">Release 1.46</a> </h3> <ul> <li> Released on 10 May 2002. </li> <li> Set of lexers compiled into Scintilla can now be changed by adding and removing lexer source files from scintilla/src and running LexGen.py. </li> <li> SCN_ZOOM notification provided by Scintilla when user changes zoom level. Method to determine width of strings in pixels so that elements can be sized relative to text size. SciTE changed to keep line number column displaying a given number of characters. </li> <li> The logical width of the document used to determine scroll bar range can be set. </li> <li> Setting to allow vertical scrolling to display last line at top rather than bottom of window. </li> <li> Read-only mode improved to avoid changing the selection in most cases when a modification is attempted. Drag and drop cursors display correctly for read-only in some cases. </li> <li> Visual C++ options in make files changed to suit Visual Studio .NET. </li> <li> Scintilla.iface includes feature types for enumerations and lexers. </li> <li> Lua lexer improves handling of literal strings and copes with nested literal strings. </li> <li> Diff lexer changed to treat lines starting with "***" similarly to "---". Symbolic names defined for lexical classes. </li> <li> nncrontab lexer improved. </li> <li> Turkish fonts (iso8859-9) supported on GTK+. </li> <li> Automatic close tag feature for XML and HTML in SciTE. </li> <li> Automatic indentation in SciTE improved. </li> <li> Maximum number of buffers available in SciTE increased. May be up to 100 although other restrictions on menu length limit the real maximum. </li> <li> Save a Copy command added to SciTE. </li> <li> Export as TeX command added to SciTE. </li> <li> Export as HTML command in SciTE respects Use Monospaced Font and background colour settings. </li> <li> Compilation problem on Solaris fixed. </li> <li> Order of files displayed for SciTE's previous and next menu and key commands are now consistent. </li> <li> Saving of MRU in recent file changed so files open when SciTE quit are remembered. </li> <li> More variants of ctags tags handled by Open Selected Filename in SciTE. </li> <li> JavaScript embedded in XML highlighted again. </li> <li> SciTE status bar updated after changing parameters in case they are being displayed in status bar. </li> <li> Crash fixed when handling some multi-byte languages. </li> <li> Crash fixed when replacing end of line characters. </li> <li> Bug in SciTE fixed in multiple buffer mode where automatic loading turned on could lead to losing file contents. </li> <li> Bug in SciTE on GTK+ fixed where dismissing dialogs with close box led to those dialogs never being shown again. </li> <li> Bug in SciTE on Windows fixed where position.tile with default positions led to SciTE being positioned off-screen. </li> <li> Bug fixed in read-only mode, clearing all deletes contraction state data leading to it not being synchronized with text. </li> <li> Crash fixed in SciTE on Windows when tab bar displayed. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite145.zip?download">Release 1.45</a> </h3> <ul> <li> Released on 15 March 2002. </li> <li> Line layout cache implemented to improve performance by maintaining the positioning of characters on lines. Can be set to cache nothing, the line with the caret, the visible page or the whole document. </li> <li> Support, including a new lexer, added for Matlab programs. </li> <li> Lua folder supports folding {} ranges and compact mode. Lua lexer styles floating point numbers in number style instead of setting the '.' in operator style. Up to 6 sets of keywords. Better support for [[ although only works well when all on one line. </li> <li> Python lexer improved to handle floating point numbers that contain negative exponents and that start with '.'. </li> <li> When performing a rectangular paste, the caret now remains at the insertion point. </li> <li> On Windows with a wheel mouse, page-at-a-time mode is recognised. </li> <li> Read-only mode added to SciTE with a property to initialise it and another property, $(ReadOnly) available to show this mode in the status bar. </li> <li> SciTE status bar can show the number of lines in the selection with the $(SelHeight) property. </li> <li> SciTE's "Export as HTML" command uses the current character set to produce correct output for non-Western-European character sets, such as Russian. </li> <li> SciTE's "Export as RTF" fixed to produce correct output when file contains '\'. </li> <li> SciTE goto command accepts a column as well as a line. If given a column, it selects the word at that column. </li> <li> SciTE's Build, Compile and Go commands are now disabled if no action has been assigned to them. </li> <li> The Refresh button in the status bar has been removed from SciTE on Windows. </li> <li> Bug fixed in line wrap mode where cursor up or down command did not work. </li> <li> Some styling bugs fixed that were due to a compilation problem with gcc and inline functions with same name but different code. </li> <li> The way that lexers loop over text was changed to avoid accessing beyond the end or setting beyond the end. May fix some bugs and make the code safer but may also cause new bugs. </li> <li> Bug fixed in HTML lexer's handling of SGML. </li> <li> Bug fixed on GTK+/X where lines wider than 32767 pixels did not display. </li> <li> SciTE bug fixed with file name generation for standard property files. </li> <li> SciTE bug fixed with Open Selected Filename command when used with file name and line number combination. </li> <li> In SciTE, indentation and tab settings stored with buffers so maintained correctly as buffers selected. The properties used to initialise these settings can now be set separately for different file patterns. </li> <li> Thread safety improved on Windows with a critical section protecting the font cache and initialisation of globals performed within Scintilla_RegisterClasses. New Scintilla_ReleaseResources call provided to allow explicit freeing of resources when statically bound into another application. Resources automatically freed in DLL version. The window classes are now unregistered as part of resource freeing which fixes bugs that occurred in some containers such as Internet Explorer. </li> <li> 'make install' fixed on Solaris. </li> <li> Bug fixed that could lead to a file being opened twice in SciTE. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite144.zip?download">Release 1.44</a> </h3> <ul> <li> Released on 4 February 2002. </li> <li> Crashing bug fixed in Editor::Paint. </li> <li> Lua lexer no longer treats '.' as a word character and handles 6 keyword sets. </li> <li> WordStartPosition and WordEndPosition take an onlyWordCharacters argument. </li> <li> SciTE option for simplified automatic indentation which repeats the indentation of the previous line. </li> <li> Compilation fix on Alpha because of 64 bit. </li> <li> Compilation fix for static linking. </li> <li> Limited maximum line length handled to 8000 characters as previous value of 16000 was causing stack exhaustion crashes for some. </li> <li> When whole document line selected, only the last display line gets the extra selected rectangle at the right hand side rather than every display line. </li> <li> Caret disappearing bug fixed for the case that the caret was not on the first display line of a document line. </li> <li> SciTE bug fixed where untitled buffer containing text was sometimes deleted without chance to save. </li> <li> SciTE bug fixed where use.monospaced not working with multiple buffers. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite143.zip?download">Release 1.43</a> </h3> <ul> <li> Released on 19 January 2002. </li> <li> Line wrapping robustness and performance improved in Scintilla. </li> <li> Line wrapping option added to SciTE for both edit and output panes. </li> <li> Static linking on Windows handles cursor resource better. Documentation of static linking improved. </li> <li> Autocompletion has an option to delete any word characters after the caret upon selecting an item. </li> <li> FOX version identified by PLAT_FOX in Platform.h. </li> <li> Calltips in SciTE use the calltip.<lexer>.word.characters setting to correctly find calltips for functions that include characters like '$' which is not normally considered a word character. </li> <li> SciTE has a command to show help on itself which gets hooked up to displaying SciTEDoc.html. </li> <li> SciTE option calltip.<lexer>.end.definition to display help text on a second line of calltip. </li> <li> Fixed the handling of the Buffers menu on GTK+ to ensure current buffer indicated and no warnings occur. Changed some menu items on GTK+ version to be same as Windows version. </li> <li> use.monospaced property for SciTE determines initial state of Use Monospaced Font setting. </li> <li> The SciTE Complete Symbol command now works when there are no word characters before the caret, even though it is slow to display the whole set of symbols. </li> <li> Function names removed from SciTE's list of PHP keywords. The full list of predefined functions is available from another web site mentioned on the Extras page. </li> <li> Crashing bug at startup on GTK+ for some configurations fixed. </li> <li> Crashing bug on GTK+ on 64 bit platforms fixed. </li> <li> Compilation problem with some compilers fixed in GTK+. </li> <li> Japanese text entry improved on Windows 9x. </li> <li> SciTE recent files directory problem on Windows when HOME and SciTE_HOME environment variables not set is now the directory of the executable. </li> <li> Session files no longer include untitled buffers. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite142.zip?download">Release 1.42</a> </h3> <ul> <li> Released on 24 December 2001. </li> <li> Better localisation support including context menus and most messages. Translations of the SciTE user interface available for Bulgarian, French, German, Italian, Russian, and Turkish. </li> <li> Can specify a character to use to indicate control characters rather than having them displayed as mnemonics. </li> <li> Scintilla key command for backspace that will not delete line end characters. </li> <li> Scintilla method to find start and end of words. </li> <li> SciTE on GTK+ now supports the load.on.activate and save.on.deactivate properties in an equivalent way to the Windows version. </li> <li> The output pane of SciTE on Windows is now interactive so command line utilities that prompt for input or confirmation can be used. </li> <li> SciTE on Windows can choose directory for a "Find in Files" command like the GTK+ version could. </li> <li> SciTE can now load a set of API files rather than just one file. </li> <li> ElapsedTime class added to Platform for accurate measurement of durations. Used for debugging and for showing the user how long commands take in SciTE. </li> <li> Baan lexer added. </li> <li> In C++ lexer, document comment keywords no longer have to be at the start of the line. </li> <li> PHP lexer changed to match keywords case insensitively. </li> <li> More shell keywords added. </li> <li> SciTE support for VoiceXML added to xml.properties. </li> <li> In SciTE the selection is not copied to the find field of the Search and Replace dialogs if it contains end of line characters. </li> <li> SciTE on Windows has a menu item to decide whether to respond to other instances which are performing their check.if.already.open check. </li> <li> SciTE accelerator key for Box Comment command changed to avoid problems in non-English locales. </li> <li> SciTE context menu includes Close command for the editor pane and Hide command for the output pane. </li> <li> output: command added to SciTE director interface to add text to the output pane. The director interface can execute commands (such as tool commands with subsystem set to 3) by sending a macro:run message. </li> <li> SciTE on GTK+ will defer to the Window Manager for position if position.left or position.top not set and for size if position.width or position.height not set. </li> <li> SciTE on Windows has a position.tile property to place a second instance to the right of the first. </li> <li> Scintilla on Windows again supports EM_GETSEL and EM_SETSEL. </li> <li> Problem fixed in Scintilla on Windows where control ID is no longer cached as it could be changed by external code. </li> <li> Problems fixed in SciTE on Windows when finding any other open instances at start up when check.if.already.open is true. </li> <li> Bugs fixed in SciTE where command strings were not always having variables evaluated. </li> <li> Bugs fixed with displaying partial double-byte and Unicode characters in rectangular selections and at the edge when edge mode is EDGE_BACKGROUND. Column numbers reported by GetColumn treat multiple byte characters as one column rather than counting bytes. </li> <li> Bug fixed with caret movement over folded lines. </li> <li> Another bug fixed with tracking selection in secondary views when performing modifications. </li> <li> Horizontal scrolling and display of long lines optimised. </li> <li> Cursor setting in Scintilla on GTK+ optimised. </li> <li> Experimental changeable style attribute. Set to false to make text read-only. Currently only stops caret from being within not-changeable text and does not yet stop deleting a range that contains not-changeable text. Can be used from SciTE by adding notchangeable to style entries. </li> <li> Experimental line wrapping. Currently has performance and appearence problems. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite141.zip?download">Release 1.41</a> </h3> <ul> <li> Released on 6 November 2001. </li> <li> Changed Platform.h to not include platform headers. This lessens likelihood and impact of name clashes from system headers and also speeds up compilation. Renamed DrawText to DrawTextNoClip to avoid name clash. </li> <li> Changed way word functions work to treat a sequence of punctuation as a word. This is more sensible and also more compatible with other editors. </li> <li> Cursor changes over the margins and selection on GTK+ platform. </li> <li> SC_MARK_BACKGROUND is a marker that only changes the line's background colour. </li> <li> Enhanced Visual Basic lexer handles character date and octal literals, and bracketed keywords for VB.NET. There are two VB lexers, vb and vbscript with type indication characters like ! and $ allowed at the end of identifiers in vb but not vbscript. Lexer states now separate from those used for C++ and names start with SCE_B. </li> <li> Lexer added for Bullant language. </li> <li> The horizontal scroll position, xOffset, is now exposed through the API. </li> <li> The SCN_POSCHANGED notification is deprecated as it was causing confusion. Use SCN_UPDATEUI instead. </li> <li> Compilation problems fixed for some versions of gcc. </li> <li> Support for WM_GETTEXT restored on Windows. </li> <li> Double clicking on an autocompletion list entry works on GTK+. </li> <li> Bug fixed with case insensitive sorts for autocompletion lists. </li> <li> Bug fixed with tracking selection in secondary views when performing modifications. </li> <li> SciTE's abbreviation expansion feature will now indent expansions to the current indentation level if indent.automatic is on. </li> <li> SciTE allows setting up of parameters to commands from a dialog and can also show this dialog automatically to prompt for arguments when running a command. </li> <li> SciTE's Language menu (formerly Options | Use Lexer) is now defined by the menu.language property rather than being hardcoded. </li> <li> The user interface of SciTE can be localised to a particular language by editing a locale.properties file. </li> <li> On Windows, SciTE will try to move to the front when opening a new file from the shell and using check.if.already.open. </li> <li> SciTE can display the file name and directory in the title bar in the form "file @ directory" when title.full.path=2. </li> <li> The SciTE time.commands property reports the time taken by a command as well as its status when completed. </li> <li> The SciTE find.files property is now a list separated by '|' characters and this list is added into the Files pull down of the Find in Files dialog. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite140.zip?download">Release 1.40</a> </h3> <ul> <li> Released on 23 September 2001. </li> <li> Removal of emulation of Win32 RichEdit control in core of Scintilla. <em>This change may be incompatible with existing client code.</em> Some emulation still done in Windows platform layer. </li> <li> SGML support in the HTML/XML lexer. </li> <li> SciTE's "Stop Executing" command will terminate GUI programs on Windows NT and Windows 2000. </li> <li> StyleContext class helps construct lexers that are simple and accurate. Used in the C++, Eiffel, and Python lexers. </li> <li> Clipboard operations in GTK+ version convert between platform '\n' line endings and currently chosen line endings. </li> <li> Any character in range 0..255 can be used as a marker. This can be used to support numbered bookmarks, for example. </li> <li> The default scripting language for ASP can be set. </li> <li> New lexer and other support for crontab files used with the nncron scheduler. </li> <li> Folding of Python improved. </li> <li> The ` character is treated as a Python operator. </li> <li> Line continuations ("\" at end of line) handled inside Python strings. </li> <li> More consistent handling of line continuation ('\' at end of line) in C++ lexer. This fixes macro definitions that span more than one line. </li> <li> C++ lexer can understand Doxygen keywords in doc comments. </li> <li> SciTE on Windows allows choosing to open the "open" dialog on the directory of the current file rather than in the default directory. </li> <li> SciTE on Windows handles command line arguments in "check.if.already.open" correctly when the current directory of the new instance is different to the already open instance of SciTE. </li> <li> "cwd" command (change working directory) defined for SciTE director interface. </li> <li> SciTE "Export As HTML" produces better, more compliant, and shorter files. </li> <li> SciTE on Windows allows several options for determining default file name for exported files. </li> <li> Automatic indentation of Python in SciTE fixed. </li> <li> Exported HTML can support folding. </li> <li> Bug fixed in SCI_GETTEXT macro command of director interface. </li> <li> Cursor leak fixed on GTK+. </li> <li> During SciTE shutdown, "identity" messages are no longer sent over the director interface. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite139.zip?download">Release 1.39</a> </h3> <ul> <li> Released on 22 August 2001. </li> <li> Windows version requires msvcrt.dll to be available so will not work on original Windows 95 version 1. The msvcrt.dll file is installed by almost everything including Internet Explorer so should be available. </li> <li> Flattened tree control style folding margin. The SciTE fold.plus option is now fold.symbols and has more values for the new styles. </li> <li> Mouse dwell events are generated when the user holds the mouse steady over Scintilla. </li> <li> PositionFromPointClose is like PositionFromPoint but returns INVALID_POSITION when point outside window or after end of line. </li> <li> Input of Hungarian and Russian characters in GTK+ version works by truncating input to 8 bits if in the range of normal characters. </li> <li> Better choices for font descriptors on GTK+ for most character sets. </li> <li> GTK+ Scintilla is destroyed upon receiving destroy signal rather than destroy_event signal. </li> <li> Style setting that force upper or lower case text. </li> <li> Case-insensitive autocompletion lists work correctly. </li> <li> Keywords can be prefix based so ^GTK_ will treat all words that start with GTK_ as keywords. </li> <li> Horizontal scrolling can be jumpy rather than gradual. </li> <li> GetSelText places a '\0' in the buffer if the selection is empty.. </li> <li> EnsureVisible split into two methods EnsureVisible which will not scroll to show the line and EnsureVisibleEnforcePolicy which may scroll. </li> <li> Python folder has options to fold multi-line comments and triple quoted strings. </li> <li> C++ lexer handles keywords before '.' like "this.x" in Java as keywords. Compact folding mode option chooses whether blank lines after a structure are folded with that structure. Second set of keywords with separate style supported. </li> <li> Ruby lexer handles multi-line comments. </li> <li> VB has folder. </li> <li> PHP lexer has an operator style, handles "<?" and "?>" inside strings and some comments. </li> <li> TCL lexer which is just an alias for the C++ lexer so does not really understand TCL syntax. </li> <li> Error lines lexer has styles for Lua error messages and .NET stack traces. </li> <li> Makefile lexer has a target style. </li> <li> Lua lexer handles some [[]] string literals. </li> <li> HTML and XML lexer have a SCE_H_SGML state for tags that start with "<!". </li> <li> Fixed Scintilla bugs with folding. When modifications were performed near folded regions sometimes no unfolding occurred when it should have. Deleting a fold causing character sometimes failed to update fold information correctly. </li> <li> Better support for Scintilla on GTK+ for Win32 including separate PLAT_GTK_WIN32 definition and correct handling of rectangular selection with clipboard operations. </li> <li> SciTE has a Tools | Switch Pane (Ctrl+F6) command to switch focus between edit and output panes. </li> <li> SciTE option output.scroll allows automatic scrolling of output pane to be turned off. </li> <li> Commands can be typed into the SciTE output pane similar to a shell window. </li> <li> SciTE properties magnification and output magnification set initial zoom levels. </li> <li> Option for SciTE comment block command to place comments at start of line. </li> <li> SciTE for Win32 has an option to minimize to the tray rather than the task bar. </li> <li> Close button on SciTE tool bar for Win32. </li> <li> SciTE compiles with GCC 3.0. </li> <li> SciTE's automatic indentation of C++ handles braces without preceding keyword correctly. </li> <li> Bug fixed with GetLine method writing past the end of where it should. </li> <li> Bug fixed with mouse drag automatic scrolling when some lines were folded. </li> <li> Bug fixed because caret XEven setting was inverted. </li> <li> Bug fixed where caret was initially visible even though window was not focussed. </li> <li> Bug fixed where some file names could end with "\\" which caused slow downs on Windows 9x. </li> <li> On Win32, SciTE Replace dialog starts with focus on replacement text. </li> <li> SciTE Go to dialog displays correct current line. </li> <li> Fixed bug with SciTE opening multiple files at once. </li> <li> Fixed bug with Unicode key values reported to container truncated. </li> <li> Fixed bug with unnecessary save point notifications. </li> <li> Fixed bugs with indenting and unindenting at start of line. </li> <li> Monospace Font setting behaves more consistently. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite138.zip?download">Release 1.38</a> </h3> <ul> <li> Released on 23 May 2001. </li> <li> Loadable lexer plugins on Windows. </li> <li> Ruby lexer and support. </li> <li> Lisp lexer and support. </li> <li> Eiffel lexer and support. </li> <li> Modes for better handling of Tab and BackSpace keys within indentation. Mode to avoid autocompletion list cancelling when there are no viable matches. </li> <li> ReplaceTarget replaced with two calls ReplaceTarget (which is incompatible with previous ReplaceTarget) and ReplaceTargetRE. Both of these calls have a count first parameter which allows using strings containing nulls. SearchInTarget and SetSearchFlags functions allow specifying a search in several simple steps which helps some clients which can not create structs or pointers easily. </li> <li> Asian language input through an Input Method Editor works on Windows 2000. </li> <li> On Windows, control characters can be entered through use of the numeric keypad in conjunction with the Alt key. </li> <li> Document memory allocation changed to grow exponentially which reduced time to load a 30 Megabyte file from 1000 seconds to 25. Change means more memory may be used. </li> <li> Word part movement keys now handled in Scintilla rather than SciTE. </li> <li> Regular expression '^' and '$' work more often allowing insertion of text at start or end of line with a replace command. Backslash quoted control characters \a, \b, \f, \t, and \v recognised within sets. </li> <li> Session files for SciTE. </li> <li> Export as PDF command hidden in SciTE as it often failed. Code still present so can be turned on by those willing to cope. </li> <li> Bug fixed in HTML lexer handling % before > as end ASP even when no start ASP encountered. Bug fixed when scripts ended with a quoted string and end tag was not seen. </li> <li> Bug fixed on Windows where context menu key caused menu to appear in corner of screen rather than within window. </li> <li> Bug fixed in SciTE's Replace All command not processing whole file when replace string longer than search string. </li> <li> Bug fixed in SciTE's MRU list repeating entries if Ctrl+Tab used when all entries filled. </li> <li> ConvertEOLs call documentation fixed. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite137.zip?download">Release 1.37</a> </h3> <ul> <li> Released on 17 April 2001. </li> <li> Bug fixed with scroll bars being invisible on GTK+ 1.2.9. </li> <li> Scintilla and SciTE support find and replace using simple regular expressions with tagged expressions. SciTE supports C '\' escapes in the Find and Replace dialogs. Replace in Selection available in SciTE. </li> <li> Scintilla has a 'target' feature for replacing code rapidly without causing display updates. </li> <li> Scintilla and SciTE on GTK+ support file dropping from file managers such as Nautilus and gmc. Files or other URIs dropped on Scintilla result in a URIDropped notification. </li> <li> Lexers may have separate Lex and Fold functions. </li> <li> Lexer infrastructure improved to allow for plug in lexers and for referring to lexers by name rather than by ID. </li> <li> Ada lexer and support added. </li> <li> Option in both Scintilla and SciTE to treat both left and right margin as equally important when repositioning visible area in response to caret movement. Default is to prefer visible area positioning which minimises the horizontal scroll position thus favouring the left margin. </li> <li> Caret line highlighting. </li> <li> Commands to delete from the caret to the end of line and from the caret to the beginning of line. </li> <li> SciTE has commands for inserting and removing block comments and for inserting stream comments. </li> <li> SciTE Director interface uses C++ '\' escapes to send control characters. </li> <li> SciTE Director interface adds more commands including support for macros. </li> <li> SciTE has menu options for recording and playing macros which are visible when used with a companion program that supports these features. </li> <li> SciTE has an Expand Abbreviation command. Abbreviations are stored in a global abbrev.properties file. </li> <li> SciTE has a Full Screen command to switch between a normal window size and using the full screen. On Windows, the menu bar can be turned off when in full screen mode. </li> <li> SciTE has a Use monospaced font command to switch between the normal set of fonts and one size of a particular fixed width font. </li> <li> SciTE's use of tabs can be controlled for particular file names as well as globally. </li> <li> The contents of SciTE's status bar can be defined by a property and include variables. On Windows, several status bar definitions can be active with a click on the status bar cycling through them. </li> <li> Copy as RTF command in SciTE on Windows to allow pasting styled text into word processors. </li> <li> SciTE can allow the use of non-alphabetic characters in Complete Symbol lists and can automatically display this autocompletion list when a trigger character such as '.' is typed. Complete word can be set to pop up when the user is typing a word and there is only one matching word in the document. </li> <li> SciTE lists the imported properties files on a menu to allow rapid access to them. </li> <li> SciTE on GTK+ improvements to handling accelerator keys and focus in dialogs. Message boxes respond to key presses without the Alt key as they have no text entries to accept normal keystrokes. </li> <li> SciTE on GTK+ sets the application icon. </li> <li> SciTE allows setting the colours used to indicate the current error line. </li> <li> Variables within PHP strings have own style. Keyword list updated. </li> <li> Keyword list for Lua updated for Lua 4.0. </li> <li> Bug fixed in rectangular selection where rectangle still appeared selected after using cursor keys to move caret. </li> <li> Bug fixed in C++ lexer when deleting a '{' controlling a folded range led to that range becoming permanently invisible. </li> <li> Bug fixed in Batch lexer where comments were not recognised. </li> <li> Bug fixed with undo actions coalescing into steps incorrectly. </li> <li> Bug fixed with Scintilla on GTK+ positioning scroll bars 1 pixel over the Scintilla window leading to their sides being chopped off. </li> <li> Bugs fixed in SciTE when doing some actions led to the start or end of the file being displayed rather than the current location. </li> <li> Appearance of calltips fixed to look like document text including any zoom factor. Positioned to be outside current line even when multiple fonts and sizes used. </li> <li> Bug fixed in Scintilla macro support where typing Enter caused both a newline command and newline character insertion to be recorded. </li> <li> Bug fixed in SciTE on GTK+ where focus was moving between widgets incorrectly. </li> <li> Bug fixed with fold symbols sometimes not updating when the text changed. </li> <li> Bugs fixed in SciTE's handling of folding commands. </li> <li> Deprecated undo collection enumeration removed from API. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite136.zip?download">Release 1.36</a> </h3> <ul> <li> Released on 1 March 2001. </li> <li> Scintilla supports GTK+ on Win32. </li> <li> Some untested work on making Scintilla and SciTE 64 bit compatible. For users on GTK+ this requires including Scintilla.h before ScintillaWidget.h. </li> <li> HTML lexer allows folding HTML. </li> <li> New lexer for Avenue files which are used in the ESRI ArcView GIS. </li> <li> DOS Batch file lexer has states for '@', external commands, variables and operators. </li> <li> C++ lexer can fold comments of /* .. */ form. </li> <li> Better disabling of pop up menu items in Scintilla when in read-only mode. </li> <li> Starting to move to Doxygen compatible commenting. </li> <li> Director interface on Windows enables another application to control SciTE. </li> <li> Opening SciTE on Windows 9x sped up greatly for some cases. </li> <li> The command.build.directory property allows SciTE to run the build command in a different directory to the source files. </li> <li> SciTE on Windows allows setting foreground and background colours for printed headers and footers. </li> <li> Bug fixed in finding calltips in SciTE which led to no calltips for some identifiers. </li> <li> Documentation added for lexers and for the extension and director interfaces. </li> <li> SciTE menus rearranged with new View menu taking over some of the items that were under the Options menu. Clear All Bookmarks command added. </li> <li> Clear Output command in SciTE. </li> <li> SciTE on Windows gains an Always On Top command. </li> <li> Bug fixed in SciTE with attempts to define properties recursively. </li> <li> Bug fixed in SciTE properties where only one level of substitution was done. </li> <li> Bug fixed in SciTE properties where extensions were not being matched in a case insensitive manner. </li> <li> Bug fixed in SciTE on Windows where the Go to dialog displays the correct line number. </li> <li> In SciTE, if fold.on.open set then switching buffers also performs fold. </li> <li> Bug fixed in Scintilla where ensuring a line was visible in the presence of folding operated on the document line instead of the visible line. </li> <li> SciTE command line processing modified to operate on arguments in order and in two phases. First any arguments before the first file name are processed, then the UI is opened, then the remaining arguments are processed. Actions defined for the Director interface (currently only "open") may also be used on the command line. For example, "SciTE -open:x.txt" will start SciTE and open x.txt. </li> <li> Numbered menu items SciTE's Buffers menu and the Most Recently Used portion of the File menu go from 1..0 rather than 0..9. </li> <li> The tab bar in SciTE for Windows has numbers. The tab.hide.one option hides the tab bar until there is more than one buffer open. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite135.zip?download">Release 1.35</a> </h3> <ul> <li> Released on 29 January 2001. </li> <li> Rewritten and simplified widget code for the GTK+ version to enhance solidity and make more fully compliant with platform norms. This includes more normal handling of keystrokes so they are forwarded to containers correctly. </li> <li> User defined lists can be shown. </li> <li> Many fixes to the Perl lexer. </li> <li> Pascal lexer handles comments more correctly. </li> <li> C/C++/Java/JavaScipt lexer has a state for line doc comments. </li> <li> Error output lexer understands Sun CC messages. </li> <li> Make file lexer has variable, preprocessor, and operator states. </li> <li> Wider area given to an italics character that is at the end of a line to prevent it being cut off. </li> <li> Call to move the caret inside the currently visible area. </li> <li> Paste Rectangular will space fill on the left hand side of the pasted text as needed to ensure it is kept rectangular. </li> <li> Cut and Paste Rectangular does nothing in read-only mode. </li> <li> Undo batching changed so that a paste followed by typing creates two undo actions.. </li> <li> A "visibility policy" setting for Scintilla determines which range of lines are displayed when a particular line is moved to. Also exposed as a property in SciTE. </li> <li> SciTE command line allows property settings. </li> <li> SciTE has a View Output command to hide or show the output pane. </li> <li> SciTE's Edit menu has been split in two with searching commands moved to a new Search menu. Find Previous and Previous Bookmark are in the Search menu. </li> <li> SciTE on Windows has options for setting print margins, headers and footers. </li> <li> SciTE on Windows has tooltips for toolbar. </li> <li> SciTE on GTK+ has properties for setting size of file selector. </li> <li> Visual and audio cues in SciTE on Windows enhanced. </li> <li> Fixed performance problem in SciTE for GTK+ by dropping the extra 3D effect on the content windows. </li> <li> Fixed problem in SciTE where choosing a specific lexer then meant that no lexer was chosen when files opened. </li> <li> Default selection colour changed to be visible on low colour displays. </li> <li> Fixed problems with automatically reloading changed documents in SciTE on Windows. </li> <li> Fixed problem with uppercase file extensions in SciTE. </li> <li> Fixed some problems when using characters >= 128, some of which were being incorrectly treated as spaces. </li> <li> Fixed handling multiple line tags, non-inline scripts, and XML end tags /> in HTML/XML lexer. </li> <li> Bookmarks in SciTE no longer disappear when switching between buffers. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite134.zip?download">Release 1.34</a> </h3> <ul> <li> Released on 28 November 2000. </li> <li> Pascal lexer. </li> <li> Export as PDF in SciTE. </li> <li> Support for the OpenVMS operating system in SciTE. </li> <li> SciTE for GTK+ can check for another instance of SciTE editing a file and switch to it rather than open a second instance on one file. </li> <li> Fixes to quoting and here documents in the Perl lexer. </li> <li> SciTE on Windows can give extra visual and audio cues when a warning is shown or find restarts from beginning of file. </li> <li> Open Selected Filename command in SciTE. Also understands some warning message formats. </li> <li> Wider area for line numbers when printing. </li> <li> Better scrolling performance on GTK+. </li> <li> Fixed problem where rectangles with negative coordinates were invalidated leading to trouble with platforms that use unsigned coordinates. </li> <li> GTK+ Scintilla uses more compliant signalling code so that keyboard events should propagate to containers. </li> <li> Bug fixed with opening full or partial paths. </li> <li> Improved handling of paths in error messages in SciTE. </li> <li> Better handling of F6 in SciTE. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite133.zip?download">Release 1.33</a> </h3> <ul> <li> Released on 6 November 2000. </li> <li> XIM support for the GTK+ version of Scintilla ensures that more non-English characters can be typed. </li> <li> Caret may be 1, 2, or 3 pixels wide. </li> <li> Cursor may be switched to wait image during lengthy processing. </li> <li> Scintilla's internal focus flag is exposed for clients where focus is handled in complex ways. </li> <li> Error status defined for Scintilla to hold indication that an operation failed and the reason for that failure. No detection yet implemented but clients may start using the interface so as to be ready for when it does. </li> <li> Context sensitive help in SciTE. </li> <li> CurrentWord property available in SciTE holding the value of the word the caret is within or near. </li> <li> Apache CONF file lexer. </li> <li> Changes to Python lexer to allow 'as' as a context sensitive keyword and the string forms starting with u, r, and ur to be recognised. </li> <li> SCN_POSCHANGED notification now working and SCN_PAINTED notification added. </li> <li> Word part movement commands for cursoring between the parts of reallyLongCamelIdentifiers and other_ways_of_making_words. </li> <li> When text on only one line is selected, Shift+Tab moves to the previous tab stop. </li> <li> Tab control available for Windows version of SciTE listing all the buffers and making it easy to switch between them. </li> <li> SciTE can be set to automatically determine the line ending type from the contents of a file when it is opened. </li> <li> Dialogs in GTK+ version of SciTE made more modal and have accelerator keys. </li> <li> Find in Files command in GTK+ version of SciTE allows choice of directory. </li> <li> On Windows, multiple files can be opened at once. </li> <li> SciTE source broken up into more files. </li> <li> Scintilla headers made safe for C language, not just C++. </li> <li> New printing modes - force background to white and force default background to white. </li> <li> Automatic unfolding not occurring when Enter pressed at end of line bug fixed. </li> <li> Bugs fixed in line selection. </li> <li> Bug fixed with escapes in PHP strings in the HTML lexer. </li> <li> Bug fixed in SciTE for GTK+ opening files when given full paths. </li> <li> Bug fixed in autocompletion where user backspaces into existing text. </li> <li> Bugs fixed in opening files and ensuring they are saved before running. A case bug also fixed here. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite132.zip?download">Release 1.32</a> </h3> <ul> <li> Released on 8 September 2000. </li> <li> Fixes bugs in complete word and related code. Protection against a bug when receiving a bad argument. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite131.zip?download">Release 1.31</a> </h3> <ul> <li> Released on 6 September 2000. </li> <li> Scintilla is available as a COM control from the scintillactrl module in CVS. </li> <li> Style setting to underline text. Exposed in SciTE as "underlined". </li> <li> Style setting to make text invisible. </li> <li> SciTE has an extensibility interface that can be used to implement features such as a scripting language or remote control. An example use of this is the extlua module available from CVS which allows SciTE to be scripted in Lua. </li> <li> Many minor fixes to all of the lexers. </li> <li> New lexer for diff and patch files. </li> <li> Error message lexer understands Perl error messages. </li> <li> C/C++/Java lexer now supports C#, specifically verbatim strings and @ quoting of identifiers that are the same as keywords. SciTE has a set of keywords for C# and a build command set up for C#. </li> <li> Scintilla property to see whether in overtype or insert state. </li> <li> PosChanged notification fired when caret moved. </li> <li> Comboboxes in dialogs in SciTE on Windows can be horizontally scrolled. </li> <li> Autocompletion and calltips can treat the document as case sensitive or case insensitive. </li> <li> Autocompletion can be set to automatically choose the only element in a single element list. </li> <li> Set of characters that automatically complete an autocompletion list can be set. </li> <li> SciTE command to display calltip - useful when dropped because of editing. </li> <li> SciTE has a Revert command to go back to the last saved version. </li> <li> SciTE has an Export as RTF command. Save as HTML is renamed to Export as HTML and is located on the Export sub menu. </li> <li> SciTE command "Complete Word" searches document for any words starting with characters before caret. </li> <li> SciTE options for changing aspects of the formatting of files exported as HTML or RTF. </li> <li> SciTE "character.set" option for choosing the character set for all fonts. </li> <li> SciTE has a "Toggle all folds" command. </li> <li> The makefiles have changed. The makefile_vc and makefile_bor files in scintilla/win32 and scite/win32 have been merged into scintilla/win32/scintilla.mak and scite/win32/scite.mak. DEBUG may be defined for all make files and this will turn on assertions and for some make files will choose other debugging options. </li> <li> To make debugging easier and allow good use of BoundsChecker there is a Visual C++ project file in scite/boundscheck that builds all of Scintilla and SciTE into one executable. </li> <li> The size of the SciTE output window can be set with the output.horizontal.size and output.vertical.size settings. </li> <li> SciTE status bar indicator for insert or overwrite mode. </li> <li> Performance improvements to autocompletion and calltips. </li> <li> A caret redraw problem when undoing is fixed. </li> <li> Crash with long lines fixed. </li> <li> Bug fixed with merging markers when lines merged. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite130.zip?download">Release 1.30</a> </h3> <ul> <li> Released on 26 July 2000. </li> <li> Much better support for PHP which is now an integral part of the HTML support. </li> <li> Start replacement of Windows-specific APIs with cross platform APIs. In 1.30, the new APIs are introduced but the old APIs are still available. For the GTK+ version, may have to include "WinDefs.h" explicitly to use the old APIs. </li> <li> "if" and "import" statements in SciTE properties files allows modularisation into language-specific properties files and choices based upon platform. This means that SciTE is delivered with 9 language-specific properties files as well as the standard SciTEGlobal.properties file. </li> <li> Much lower resource usage on Windows 9x. </li> <li> "/p" option in SciTE on Windows for printing a file and then exiting. </li> <li> Options for printing with inverted brightness (when the screen is set to use a dark background) and to force black on white printing. </li> <li> Option for printing magnified or miniaturised from screen settings. </li> <li> In SciTE, Ctrl+F3 and Ctrl+Shift+F3 find the selection in the forwards and backwards directions respectively. </li> <li> Auto-completion lists may be set to cancel when the cursor goes before its start position or before the start of string being completed. </li> <li> Auto-completion lists automatically size more sensibly. </li> <li> SCI_CLEARDOCUMENTSTYLE zeroes all style bytes, ensures all lines are shown and deletes all folding information. </li> <li> On Windows, auto-completion lists are visually outdented rather than indented. </li> <li> Close all command in SciTE. </li> <li> On Windows multiple files can be dragged into SciTE. </li> <li> When saving a file, the SciTE option save.deletes.first deletes it before doing the save. This allows saving with a different capitalisation on Windows. </li> <li> When use tabs option is off pressing the tab key inserts spaces. </li> <li> Bug in indicators leading to extra line drawn fixed. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite128.zip?download">Release 1.28</a> </h3> <ul> <li> Released on 27 June 2000. </li> <li> Fixes crash in indentation guides when indent size set to 0. </li> <li> Fixes to installation on GTK+/Linux. User properties file on GTK+ has a dot at front of name: .SciTEUser.properties. Global properties file location configurable at compile time defaulting to $prefix/share/scite. $prefix determined from Gnome if present else its /usr/local and can be overridden by installer. Gnome menu integration performed in make install if Gnome present. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite127.zip?download">Release 1.27</a> </h3> <ul> <li> Released on 23 June 2000. </li> <li> Indentation guides. View whitespace mode may be set to not display whitespace in indentation. </li> <li> Set methods have corresponding gets for UndoCollection, BufferedDraw, CodePage, UsePalette, ReadOnly, CaretFore, and ModEventMask. </li> <li> Caret is continuously on rather than blinking while typing or holding down delete or backspace. And is now always shown if non blinking when focused on GTK+. </li> <li> Bug fixed in SciTE with file extension comparison now done in case insensitive way. </li> <li> Bugs fixed in SciTE's file path handling on Windows. </li> <li> Bug fixed with preprocessor '#' last visible character causing hang. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite126.zip?download">Release 1.26</a> </h3> <ul> <li> Released on 13 June 2000. </li> <li> Support for the Lua language in both Scintilla and SciTE. </li> <li> Multiple buffers may be open in SciTE. </li> <li> Each style may have a character set configured. This may determine the characters that are displayed by the style. </li> <li> In the C++ lexer, lexing of preprocessor source may either treat it all as being in the preprocessor class or only the initial # and preprocessor command word as being in the preprocessor class. </li> <li> Scintilla provides SCI_CREATEDOCUMENT, SCI_ADDREFDOCUMENT, and SCI_RELEASEDOCUMENT to make it easier for a container to deal with multiple documents. </li> <li> GTK+ specific definitions in Scintilla.h were removed to ScintillaWidget.h. All GTK+ clients will need to #include "ScintillaWidget.h". </li> <li> For GTK+, tools can be executed in the background by setting subsystem to 2. </li> <li> Keys in the properties files are now case sensitive. This leads to a performance increase. </li> <li> Menu to choose which lexer to use on a file. </li> <li> Tab size dialog on Windows. </li> <li> File dialogs enlarged on GTK+. </li> <li> Match Brace command bound to Ctrl+E on both platforms with Ctrl+] a synonym on Windows. Ctrl+Shift+E is select to matching brace. Brace matching tries to match to either the inside or the outside, depending on whether the cursor is inside or outside the braces initially. View End of Line bound to Ctrl+Shift+O. </li> <li> The Home key may be bound to move the caret to either the start of the line or the start of the text on the line. </li> <li> Visual C++ project file for SciTE. </li> <li> Bug fixed with current x location after Tab key. </li> <li> Bug fixed with hiding fold margin by setting fold.margin.width to 0. </li> <li> Bugs fixed with file name confusion on Windows when long and short names used, or different capitalisations, or relative paths. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite125.zip?download">Release 1.25</a> </h3> <ul> <li> Released on 9 May 2000. </li> <li> Some Unicode support on Windows. Treats buffer and API as UTF-8 and displays through UCS-2 of Windows. </li> <li> Automatic indentation. Indentation size can be different to tab size. </li> <li> Tool bar. </li> <li> Status bar now on Windows as well as GTK+. </li> <li> Input fields in Find and Replace dialogs now have history on both Windows and GTK+. </li> <li> Auto completion list items may be separated by a chosen character to allow spaces in items. The selected item may be changed through the API. </li> <li> Horizontal scrollbar can be turned off. </li> <li> Property to remove trailing spaces when saving file. </li> <li> On Windows, changed font size calculation to be more compatible with other applications. </li> <li> On GTK+, SciTE's global properties files are looked for in the directory specified in the SCITE_HOME environment variable if it is set. This allows hiding in a dot directory. </li> <li> Keyword lists in SciTE updated for JavaScript to include those destined to be used in the future. IDL includes XPIDL keywords as well as MSIDL keywords. </li> <li> Zoom level can be set and queried through API. </li> <li> New notification sent before insertions and deletions. </li> <li> LaTeX lexer. </li> <li> Fixes to folding including when deletions and additions are performed. </li> <li> Fix for crash with very long lines. </li> <li> Fix to affect all of rectangular selections with deletion and case changing. </li> <li> Removed non-working messages that had been included only for Richedit compatibility. </li> </ul> <h3> <a href="http://www.scintilla.org/scite124.zip">Release 1.24</a> </h3> <ul> <li> Released on 29 March 2000. </li> <li> Added lexing of IDL based on C++ lexer with extra UUID lexical class. </li> <li> Functions and associated keys for Line Delete, Line Cut, Line Transpose, Selection Lower Case and Selection Upper Case. </li> <li> Property setting for SciTE, eol.mode, chooses initial state of line end characters. </li> <li> Fixed bugs in undo history with small almost-contiguous changes being incorrectly coalesced. </li> <li> Fixed bugs with incorrect expansion of ContractionState data structures causing crash. </li> <li> Fixed bugs relating to null fonts. </li> <li> Fixed bugs where recolourisation was not done sometimes when required. </li> <li> Fixed compilation problems with SVector.h. </li> <li> Fixed bad setting of fold points in Python. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/scite123.zip?download">Release 1.23</a> </h3> <ul> <li> Released on 21 March 2000. </li> <li> Directory structure to separate on basis of product (Scintilla, SciTE, DMApp) and environment (Cross-platform, Win32, GTK+). </li> <li> Download packaging to allow download of the source or platform dependent executables. </li> <li> Source code now available from CVS at SourceForge. </li> <li> Very simple Windows-only demonstration application DMApp is available from cvs as dmapp. </li> <li> Lexing functionality may optionally be included in Scintilla rather than be provided by the container. </li> <li> Set of lexers included is determined at link time by defining which of the Lex* object files are linked in. </li> <li> On Windows, the SciLexer.DLL extends Scintilla.DLL with the standard lexers. </li> <li> Enhanced HTML lexer styles embedded VBScript and Python. ASP segments are styled and ASP scripts in JavaScript, VBScript and Python are styled. </li> <li> PLSQL and PHP supported. </li> <li> Maximum number of lexical states extended to 128. </li> <li> Lexers may store per line parse state for multiple line features such as ASP script language choice. </li> <li> Lexing API simplified. </li> <li> Project file for Visual C++. </li> <li> Can now cycle through all recent files with Ctrl+Tab in SciTE. </li> <li> Bookmarks in SciTE. </li> <li> Drag and drop copy works when dragging to the edge of the selection. </li> <li> Fixed bug with value sizes in properties file. </li> <li> Fixed bug with last line in properties file not being used. </li> <li> Bug with multiple views of one document fixed. </li> <li> Keypad now works on GTK+. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/SciTE122.zip?download">Release 1.22</a> </h3> <ul> <li> Released on 27 February 2000. </li> <li> wxWindows platform defined. Implementation for wxWindows will be available separately from main Scintilla distribution. </li> <li> Line folding in Scintilla. </li> <li> SciTE performs syntax directed folding for C/C++/Java/JavaScript and for Python. </li> <li> Optional macro recording support. </li> <li> User properties file (SciTEUser.properties) allows for customisation by the user that is not overwritten with each installation of SciTE. </li> <li> Python lexer detects and highlights inconsistent indentation. </li> <li> Margin API made more orthogonal. SCI_SETMARGINWIDTH and SCI_SETLINENUMBERWIDTH are deprecated in favour of this new API. </li> <li> Margins may be made sensitive to forward mouse click events to container. </li> <li> SQL lexer and styles included. </li> <li> Perl lexer handles regular expressions better. </li> <li> Caret policy determines how closely caret is tracked by visible area. </li> <li> New marker shapes: arrow pointing down, plus and minus. </li> <li> Optionally display full path in title rather than just file name. </li> <li> Container is notified when Scintilla gains or loses focus. </li> <li> SciTE handles focus in a more standard way and applies the main edit commands to the focused pane. </li> <li> Container is notified when Scintilla determines that a line needs to be made visible. </li> <li> Document watchers receive notification when document about to be deleted. </li> <li> Document interface allows access to list of watchers. </li> <li> Line end determined correctly for lines ending with only a '\n'. </li> <li> Search variant that searches form current selection and sets selection. </li> <li> SciTE understands format of diagnostic messages from WScript. </li> <li> SciTE remembers top line of window for each file in MRU list so switching to a recent file is more likely to show the same text as when the file was previously visible. </li> <li> Document reference count now initialised correctly. </li> <li> Setting a null document pointer creates an empty document. </li> <li> WM_GETTEXT can no longer overrun buffer. </li> <li> Polygon drawing bug fixed on GTK+. </li> <li> Java and JavaScript lexers merged into C++ lexer. </li> <li> C++ lexer indicates unterminated strings by colouring the end of the line rather than changing the rest of the file to string style. This is less obtrusive and helps the folding. </li> </ul> <h3> <a href="http://prdownloads.sourceforge.net/scintilla/SciTE121.zip?download">Release 1.21</a> </h3> <ul> <li> Released on 2 February 2000. </li> <li> Blank margins on left and right side of text. </li> <li> SCN_CHECKBRACE renamed SCN_UPDATEUI and made more efficient. </li> <li> SciTE source code refactored into platform independent and platform specific classes. </li> <li> XML and Perl subset lexers in SciTE. </li> <li> Large improvement to lexing speed. </li> <li> A new subsystem, 2, allows use of ShellExec on Windows. </li> <li> Borland compatible makefile. </li> <li> Status bar showing caret position in GTK+ version of SciTE. </li> <li> Bug fixes to selection drawing when part of selection outside window, mouse release over scroll bars, and scroll positioning after deletion. </li> </ul> <h3> <a href="http://www.scintilla.org/SciTE120.zip">Release 1.2</a> </h3> <ul> <li> Released on 21 January 2000. </li> <li> Multiple views of one document. </li> <li> Rectangular selection, cut, copy, paste, drag and drop. </li> <li> Long line indication. </li> <li> Reverse searching </li> <li> Line end conversion. </li> <li> Generic autocompletion and calltips in SciTE. </li> <li> Call tip background colour can be set. </li> <li> SCI_MARKERPREV for moving to a previous marker. </li> <li> Caret kept more within window where possible. </li> </ul> <h3> <a href="http://www.scintilla.org/SciTE115.zip">Release 1.15</a> </h3> <ul> <li> Released on 15 December 1999. </li> <li> Brace highlighting and badlighting (for mismatched braces). </li> <li> Visible line ends. </li> <li> Multiple line call tips. </li> <li> Printing now works from SciTE on Windows. </li> <li> SciTE has a global "*" lexer style that is used as the basis for all the lexers' styles. </li> <li> Fixes some warnings on GTK+ 1.2.6. </li> <li> Better handling of modal dialogs on GTK+. </li> <li> Resize handle drawn on pane splitter in SciTE on GTK+ so it looks more like a regular GTK+ *paned widget. </li> <li> SciTE does not place window origin offscreen if no properties file found on GTK+. </li> <li> File open filter remembered in SciTE on Windows. </li> <li> New mechanism using style numbers 32 to 36 standardises the setting of styles for brace highlighting, brace badlighting, line numbers, control characters and the default style. </li> <li> Old messages SCI_SETFORE .. SCI_SETFONT have been replaced by the default style 32. The old messages are deprecated and will disappear in a future version. </li> </ul> <h3> <a href="http://www.scintilla.org/SciTE114.zip">Release 1.14</a> </h3> <ul> <li> Released on 20 November 1999. </li> <li> Fixes a scrolling bug reported on GTK+. </li> </ul> <h3> <a href="http://www.scintilla.org/SciTE113.zip">Release 1.13</a> </h3> <ul> <li> Released on 18 November 1999. </li> <li> Fixes compilation problems with the mingw32 GCC 2.95.2 on Windows. </li> <li> Control characters are now visible. </li> <li> Performance has improved, particularly for scrolling. </li> <li> Windows RichEdit emulation is more accurate. This may break client code that uses these messages: EM_GETLINE, EM_GETLINECOUNT, EM_EXGETSEL, EM_EXSETSEL, EM_EXLINEFROMCHAR, EM_LINELENGTH, EM_LINEINDEX, EM_CHARFROMPOS, EM_POSFROMCHAR, and EM_GETTEXTRANGE. </li> <li> Menus rearranged and accelerator keys set for all static items. </li> <li> Placement of space indicators in view whitespace mode is more accurate with some fonts. </li> </ul> <h3> <a href="http://www.scintilla.org/SciTE112.zip">Release 1.12</a> </h3> <ul> <li> Released on 9 November 1999. </li> <li> Packaging error in 1.11 meant that the compilation error was not fixed in that release. Linux/GTK+ should compile with GCC 2.95 this time. </li> </ul> <h3> <a href="http://www.scintilla.org/SciTE111.zip">Release 1.11</a> </h3> <ul> <li> Released on 7 November 1999. </li> <li> Fixed a compilation bug in ScintillaGTK.cxx. </li> <li> Added a README file to explain how to build. </li> <li> GTK+/Linux downloads now include documentation. </li> <li> Binary only Sc1.EXE one file download for Windows. </li> </ul> <h3> <a href="http://www.scintilla.org/SciTE110.zip">Release 1.1</a> </h3> <ul> <li> Released on 6 November 1999. </li> <li> Major restructuring for better modularity and platform independence. </li> <li> Inter-application drag and drop. </li> <li> Printing support in Scintilla on Windows. </li> <li> Styles can select colouring to end of line. This can be used when a file contains more than one language to differentiate between the areas in each language. An example is the HTML + JavaScript styling in SciTE. </li> <li> Actions can be grouped in the undo stack, so they will be undone together. This grouping is hierarchical so higher level actions such as replace all can be undone in one go. Call to discover whether there are any actions to redo. </li> <li> The set of characters that define words can be changed. </li> <li> Markers now have identifiers and can be found and deleted by their identifier. The empty marker type can be used to make a marker that is invisible and which is only used to trace where a particular line moves to. </li> <li> Double click notification. </li> <li> HTML styling in SciTE also styles embedded JavaScript. </li> <li> Additional tool commands can be added to SciTE. </li> <li> SciTE option to allow reloading if changed upon application activation and saving on application deactivation. Not yet working on GTK+ version. </li> <li> Entry fields in search dialogs remember last 10 user entries. Not working in all cases in Windows version. </li> <li> SciTE can save a styled copy of the current file in HTML format. As SciTE does not yet support printing, this can be used to print a file by then using a browser to print the HTML file. </li> </ul> <h3> <a href="http://www.scintilla.org/SciTE102.zip">Release 1.02</a> </h3> <ul> <li> Released on 1 October 1999. </li> <li> GTK+ version compiles with GCC 2.95. </li> <li> Properly deleting objects when window destroyed under GTK+. </li> <li> If the selection is not empty backspace deletes the selection. </li> <li> Some X style middle mouse button handling for copying the primary selection to and from Scintilla. Does not work in all cases. </li> <li> HTML styling in SciTE. </li> <li> Stopped dirty flag being set in SciTE when results pane modified. </li> </ul> <h3> <a href="http://www.scintilla.org/SciTE101.zip">Release 1.01</a> </h3> <ul> <li> Released on 28 September 1999. </li> <li> Better DBCS support on Windows including IME. </li> <li> Wheel mouse support for scrolling and zooming on Windows. Zooming with Ctrl+KeypadPlus and Ctrl+KeypadMinus. </li> <li> Performance improvements especially on GTK+. </li> <li> Caret blinking and settable colour on both GTK+ and Windows. </li> <li> Drag and drop within a Scintilla window. On Windows, files can be dragged into SciTE. </li> </ul> <h3> <a href="http://www.scintilla.org/SciTE100.zip">Release 1.0</a> </h3> <ul> <li> Released on 17 May 1999. </li> <li> Changed name of "Tide" to "SciTE" to avoid clash with a TCL based IDE. "SciTE" is a SCIntilla based Text Editor and is Latin meaning something like "understanding in a neat way" and is also an Old English version of the word "shit". </li> <li> There is a SCI_AUTOCSTOPS message for defining a string of characters that will stop autocompletion mode. Autocompletion mode is cancelled when any cursor movement occurs apart from backspace. </li> <li> GTK+ version now splits horizontally as well as vertically and all dialogs cancel when the escape key is pressed. </li> </ul> <h3> <a href="http://www.scintilla.org/Tide92.zip">Beta release 0.93</a> </h3> <ul> <li> Released on 12 May 1999. </li> <li> A bit more robust than 0.92 and supports SCI_MARKERNEXT message. </li> </ul> <h3> <a href="http://www.scintilla.org/Tide92.zip">Beta release 0.92</a> </h3> <ul> <li> Released on 11 May 1999. </li> <li> GTK+ version now contains all features of Windows version with some very small differences. Executing programs works much better now. </li> <li> New palette code to allow more colours to be displayed in 256 colour screen modes. A line number column can be displayed to the left of the selection margin. </li> <li> The code that maps from line numbers to text positions and back has been completely rewritten to be faster, and to allow markers to move with the text. </li> </ul> <h3> <a href="http://www.scintilla.org/Tide91.zip">Beta release 0.91</a> </h3> <ul> <li> Released on 30 April 1999, containing fixes to text measuring to make Scintilla work better with bitmap fonts. Also some small fixes to make compiling work with Visual C++. </li> </ul> <h3> <a href="http://www.scintilla.org/Tide90.zip">Beta release 0.90</a> </h3> <ul> <li> Released on 29 April 1999, containing working GTK+/Linux version. </li> <li> The Java, C++ and Python lexers recognise operators as distinct from default allowing them to be highlighted. </li> </ul> <h3> <a href="http://www.scintilla.org/Tide82.zip">Beta release 0.82</a> </h3> <ul> <li> Released on 1 April 1999, to fix a problem with handling the Enter key in PythonWin. Also fixes some problems with cmd key mapping. </li> </ul> <h3> <a href="http://www.scintilla.org/Tide81.zip">Beta release 0.81</a> </h3> <ul> <li> Released on 30th March 1999, containing bug fixes and a few more features. </li> <li> Static linking supported and Tidy.EXE, a statically linked version of Tide.EXE. Changes to compiler flags in the makefiles to optimise for size. </li> <li> Scintilla supports a 'savepoint' in the undo stack which can be set by the container when the document is saved. Notifications are sent to the container when the savepoint is entered or left, allowing the container to to display a dirty indicator and change its menus. </li> <li> When Scintilla is set to read-only mode, a notification is sent to the container should the user try to edit the document. This can be used to check the document out of a version control system. </li> <li> There is an API for setting the appearance of indicators. </li> <li> The keyboard mapping can be redefined or removed so it can be implemented completely by the container. All of the keyboard commands are now commands which can be sent by the container. </li> <li> A home command like Visual C++ with one hit going to the start of the text on the line and the next going to the left margin is available. I do not personally like this but my fingers have become trained to it by much repetition. </li> <li> SCI_MARKERDELETEALL has an argument in wParam which is the number of the type marker to delete with -1 performing the old action of removing all marker types. </li> <li> Tide now understands both the file name and line numbers in error messages in most cases. </li> <li> Tide remembers the current lines of files in the recently used list. </li> <li> Tide has a Find in Files command. </li> </ul> <h3> Beta release 0.80 </h3> <ul> <li> This was the first public release on 14th March 1999, containing a mostly working Win32 Scintilla DLL and Tide EXE. </li> </ul> <h3> Beta releases of SciTE were called Tide </h3> </body> </html> |
Added doc/ScintillaRelated.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="HTML Tidy, see www.w3.org" /> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title> Scintilla and SciTE Related Sites </title> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5">Scintilla and SciTE</font></a> </td> </tr> </table> <h2> Related Sites </h2> <h3> Ports and Bindings of Scintilla </h3> <p> <a href="http://foicica.com/scinterm/">Scinterm</a> is an implementation of Scintilla for the ncurses platform. </p> <p> <a href="http://www.morphos-team.net/releasenotes/3.0">Scintilla.mcc</a> is a port to MorphOS. </p> <p> <a href="https://metacpan.org/module/Wx::Scintilla">Wx::Scintilla</a> is a Perl Binding for Scintilla on wxWidgets. </p> <p> <a href="http://codebrainz.github.com/GtkScintilla/">GtkScintilla</a> is a GTK+ widget which enables easily adding a powerful source code editor to your applications. Harnessing the abilities of the Scintilla editing component, GtkScintilla adds a familiar GTK+/GObject API, making the widget comfortable to use in these programs, using all the typical GObject conventions. </p> <p> <a href="http://mewsoft.com/cgi-bin/forum/forum.cgi?action=ViewTopic&Topic=1494&Forum=1&Page=1&Period=0a&Lang=English">Editawy</a> is an ActiveX Control wrapper that support all Scintilla functions and additional high level functions. </p> <p> <a href="http://sourceforge.net/projects/jintilla/">Jintilla</a> is a JNI wrapper that allows Scintilla to be used in Java with both SWT and AWT. </p> <p> <a href="http://delphisci.sourceforge.net/">Delphi Scintilla Interface Components</a> is a FREE collection of components that makes it easy to use the Scintilla source code editing control from within Delphi and C++ Builder. </p> <p> <a href="http://wxcode.sourceforge.net/showcomp.php?name=wxStEdit">wxStEdit</a> is a library and sample program that provides extra features over wxStyledTextControl. </p> <p> <a href="http://www.naughter.com/scintilla.html">CScintillaCtrl, CScintillaView & CScintillaDoc</a> are freeware MFC classes to encapsulate Scintilla. </p> <p> <a href="http://sourceforge.net/projects/scide/">ScintillaNet </a> is an encapsulation of Scintilla for use within the .NET framework. </p> <p> <a href="http://www.riverbankcomputing.co.uk/software/qscintilla/intro">QScintilla </a> is a port of Scintilla to the Qt platform. It has a similar license to Qt: GPL for use in free software and commercial for use in close-source applications. </p> <p> <a href="http://www.adapower.com/gwindows/"> GWindows</a> is a Win32 RAD GUI Framework for Ada 95 that includes a binding of Scintilla. </p> <p> <a href="http://scintilla.cvs.sourceforge.net/viewvc/scintilla/ScintillaVB/">ScintillaVB</a> is an ActiveX control written in VB that encapsulates Scintilla. </p> <p> <a href="http://savannah.nongnu.org/projects/fxscintilla/">FXScintilla </a> is a port of Scintilla to the FOX platform. FXRuby includes Ruby bindings for FXScintilla. </p> <p> <a href="http://www.pnotepad.org/scintilla/">Delphi wrapper</a> for Scintilla which is also usable from Borland C++ Builder. </p> <p> The wxStyledTextCtrl editor component in the <a href="http://www.wxwidgets.org/">wxWidgets</a> cross platform toolkit is based on Scintilla.<br /> A Python binding for wxStyledTextCtrl is part of <a href="http://wxpython.org/">wxPython</a>. </p> <p> <a href="http://sourceforge.net/projects/moleskine/">gtkscintilla</a> is an alternative GTK class implementation for scintilla. This implementation acts more like a Gtk+ object, with many methods rather than just scintilla_send_message() and is available as a shared library. This implementation works with GTK 1.x. </p> <p> <a href="http://sourceforge.net/projects/moleskine/">gtkscintilla2</a> is an alternative GTK class implementation for scintilla similar to the above, but for GTK 2.x. </p> <p> <a href="http://sourceforge.net/projects/moleskine/">pygtkscintilla</a> is a Python binding for gtk1.x scintilla that uses gtkscintilla instead of the default GTK class. </p> <p> <a href="http://scintilla.cvs.sourceforge.net/viewvc/scintilla/scintillactrl/">ScintillaCtrl</a> is an unmaintained ActiveX control wrapper for Scintilla. </p> <h3> Projects using Scintilla </h3> <p> <a href="http://www.qgis.org/">Quantum GIS</a> is a user friendly Open Source Geographic Information System (GIS). </p> <p> <a href="https://gitorious.org/qgrinui">QGrinUI</a> searches for a regex within all relevant files in a directory and shows matches using SciTE through the director interface. </p> <p> <a href="http://foicica.com/textadept/">Textadept</a> is a ridiculously extensible cross-platform text editor for programmers written (mostly) in Lua using LPeg to handle the lexers. </p> <p> <a href="http://www.morphos-team.net/releasenotes/3.0">Scribble</a> is a text editor included in MorphOS. </p> <p> <a href="http://mysqlworkbench.org/">MySQL Workbench</a> is a cross-platform, visual database design, sql coding and administration tool. </p> <p> <a href="http://liveditor.com/index.html">LIVEditor</a> is for web front end coders editing html/css/js code. </p> <p> <a href="http://padre.perlide.org/">Padre</a> is a wxWidgets-based Perl IDE. </p> <p> <a href="http://manoscoder.gr/CoderStudio/CoderStudio.asp">CoderStudio</a> is an IDE for Assembly programming similar to Visual Studio 6.0. </p> <p> <a href="http://www.sparxsystems.com/products/ea/index.html">Enterprise Architect</a> is a UML 2.1 analysis and design tool. </p> <p> <a href="https://launchpad.net/codeassistor">The CodeAssistor Editor</a> is a small and simple MacOSX source code editor. </p> <p> <a href="http://www.topwizprogramming.com/freecode_pbeditor.html">PBEditor</a> is a text editor for PowerBuilder. </p> <p> <a href="http://www.cryptool.org/">CrypTool</a> is an application for applying and analyzing cryptographic algorithms. </p> <p> <a href="http://code.google.com/p/fxite/">FXiTe</a> is an advanced cross-platform text editor built with the Fox GUI toolkit and the FXScintilla text widget. </p> <p> <a href="http://www.jabaco.org/">Jabaco</a> is a simple programming language with a Visual Basic like syntax. </p> <p> <a href="http://www.daansystems.com/lispide">LispIDE</a> is a basic Lisp editor for Windows 2000, XP and Vista. </p> <p> <a href="http://www.flexsoft.cc/download.htm">FlexEdit</a> is Free Text/Hex Editor for Windows. </p> <p> <a href="http://www.assembla.com/wiki/show/FileWorkbench">File Workbench:</a> a file manager / text editor environment with Squirrel scripting. </p> <p> <a href="http://kephra.sf.net">Kephra</a> is a free, easy and comfortable cross-platform editor written in Perl. </p> <p> <a href="http://top.gresham-computing.com">TOP</a> is an interface to HP's NonStop servers which run a proprietary OS. </p> <p> <a href="http://universalindent.sourceforge.net/">UniversalIndentGUI</a> is a cross platform GUI for several code formatters, beautifiers and indenters like GreatCode, AStyle (Artistic Styler), GNU Indent, BCPP and so on. </p> <p> <a href="http://scitools.com/products/trackback/product.php">TrackBack</a> watches and backs up every change made in your source code. </p> <p> <a href="http://elementaryreports.com/">Elementary Reports</a> is designed to reduce the time to compose detailed and professional primary school reports. </p> <p> <a href="http://stepaheadsoftware.com/products/vcw/vcw.htm">Visual Classworks</a> Visual class modeling and coding in C++ via 'live' UML style class diagrams. </p> <p> <a href="http://stepaheadsoftware.com/products/javelin/javelin.htm">Javelin</a> Visual Class modeling and coding in Java via 'live' UML style class diagrams. </p> <p> The <a href="http://www.adobe.com/devnet/bridge/">ExtendScript Toolkit</a> is a development and debugging tool for JavaScript scripts included with Adobe CS3 Suites. </p> <p> <a href="http://tortoisesvn.net/">TortoiseSVN</a> is a Windows GUI client for the Subversion source control software. </p> <p> <a href="http://www.geany.org/">Geany</a> is a small and fast GTK2 based IDE, which has only a few dependencies from other packages. </p> <p> <a href="http://www.elliecomputing.com/products/merge_overview.asp">ECMerge</a> is a commercial graphical and batch diff / merge tool for Windows, Linux and Solaris (aiming to target all major platforms). </p> <p> <a href="http://pype.sourceforge.net/">PyPE</a> is an editor written in Python with the wxPython GUI toolkit. </p> <p> <a href="http://home.mweb.co.za/sd/sdonovan/sciboo.html">Sciboo</a> is an editor based on ScintillaNET. </p> <p> <a href="https://sourceforge.net/projects/tsct/">The Scite Config Tool</a> is a graphical user interface for changing SciTE properties files. </p> <p> <a href="http://www.totalcmd.net/plugring/SciLister.html">Scintilla Lister</a> is a plugin for Total Commander allowing viewing all documents with syntax highlighting inside Total Commander. </p> <p> <a href="http://chscite.sourceforge.net">ChSciTE</a> is a free IDE for C/C++ interpreter Ch. It runs cross platform. Ch is for cross-platform scripting, shell programming, 2D/3D plotting, numerical computing, and embedded scripting. </p> <p> <a href="http://codeblocks.org/"> Code::Blocks</a> is an open source, cross platform free C++ IDE. </p> <p> <a href="http://notepad-plus.sourceforge.net/uk/site.htm"> Notepad++</a> is a free source code editor under Windows. </p> <p> <a href="http://gubed.mccabe.nu/"> Gubed</a> is a cross platform program to debug PHP scripts. </p> <p> <a href="http://www.lesser-software.com/lswdnl.htm"> LSW DotNet-Lab</a> is a development environment for the .NET platform. </p> <p> <a href="http://glintercept.nutty.org/"> GLIntercept</a> is an OpenGL function call interceptor that uses SciTE as a run-time shader editor. </p> <p> <a href="http://wxguide.sourceforge.net/indexedit.html"> wyoEditor</a> is "A nice editor with a well designed and consistent look and feel". </p> <p> <a href="http://www.flos-freeware.ch/notepad2.html"> Notepad2</a> is "Yet another Notepad replacement". </p> <p> <a href="http://pycrash.sourceforge.net/index.php?type=3"> PyCrash Viewer</a> can examine crash dumps of Python programs. </p> <p> <a href="http://www.cabletest.com/mpt-wa-software-discovery.shtml"> MPT series Wire Analyzers</a> use Scintilla and SciTE. </p> <p> <a href="http://www.mygenerationsoftware.com">MyGeneration</a> is a .NET based code generator. </p> <p> <a href="http://cssed.sourceforge.net">CSSED</a> is a tiny GTK2 CSS editor. </p> <p> <a href="http://wxghostscript.sourceforge.net/"> IdePS</a> is a free Integrated Development Environment for PostScript </p> <p> <a href="http://cute.sourceforge.net/"> CUTE</a> is a user-friendly source code editor easily extended using Python. </p> <p> <a href="http://www.spaceblue.com/venis/"> Venis IX</a>, the Visual Environment for NSIS (Nullsoft Scriptable Install System). </p> <p> <a href="http://www.die-offenbachs.de/detlev/eric.html">Eric3</a> is a Python IDE written using PyQt and QScintilla. </p> <p> <a href="http://www.bomberstudios.com/sciteflash/">SciTE|Flash</a> is a free Scintilla-based ActionScript editor for Windows. </p> <p> <a href="http://www.computersciencelab.com/CppIde.htm">CPPIDE</a> is part of some commercial high-school oriented programming course software. </p> <p> <a href="http://www.blazingtools.com/is.html">Instant Source</a> is a commercial tool for looking at the HTML on web sites. </p> <p> <a href="http://www.codejoin.com/radon/">RAD.On++</a> is a free C++ Rapid Application Developer for Win32. </p> <p> <a href="http://wxbasic.sourceforge.net/">wxBasic</a> is an open source Basic interpreter that uses the wxWidgets toolkit. A small IDE is under construction. </p> <p> <a href="http://freeride.rubyforge.org/wiki/wiki.pl">FreeRIDE</a> will be a cross-platform IDE for the Ruby programming language. </p> <p> <a href="http://visual-mingw.sourceforge.net/">Visual MinGW</a> is an IDE for the MinGW compiler system.This runs on Windows with gcc. </p> <p> The <a href="http://archaeopteryx.com/wingide">Wing IDE</a> is a complete integrated development environment for the Python programming language. Available on Intel based Linux and Windows and on MacOS X through XDarwin. </p> <p> <a href="http://www.gorlice.net.pl/~rybak/luaide/">LuaIDE</a> is an IDE for Lua on Windows. </p> <p> <a href="http://www.aegisknight.org/sphere/">Sphere</a> is 2D RPG engine with a development environment. </p> <p> <a href="http://gaiacrtn.free.fr/practical-ruby/index.html">Practical Ruby</a> is an IDE for Ruby on Windows. </p> <p> <a href="http://www.gnuenterprise.org/">GNUe</a> is a suite of tools and applications for solving the needs of the enterprise. </p> <p> <a href="http://silvercity.sourceforge.net/">SilverCity</a> is a lexing package that can provide lexical analysis for over 20 programming and markup languages. </p> <p> <a href="http://hapdebugger.sourceforge.net/">HAP Python Remote Debugger</a> is a Python debugger that can run on one Windows machine debugging a Python program running on either the same or another machine. </p> <p> <a href="http://www.rexx.com/~dkuhlman/">pyeditor and wxEditor</a> are scriptable editors implemented in Python. pyeditor is based on GTK+ and the pyscintilla wrapper. wxEditor is based on wxWidgets, wxPython and wxStyledTextControl. </p> <p> <a href="http://sourceforge.net/projects/pycrust/">PyCrust</a> is an interactive Python shell based on wxPython. </p> <p> <a href="http://www.thekompany.com/products/blackadder/">Black Adder</a> is a Qt based development environment for Python and Ruby. </p> <p> <a href="http://www.activestate.com/Products/Komodo/">Komodo</a> is a cross-platform multi-language development environment built as an application of Mozilla. </p> <p> <a href="http://llt.chez-alice.fr/">Filerx</a> is a project manager for SciTE on Windows. Open source and includes an implementation of SciTE's Director interface so will be of interest to others wanting to control SciTE. </p> <p> <a href="http://anjuta.sourceforge.net/">Anjuta</a> is an open source C/C++ IDE for Linux/GNOME. </p> <p> A <a href="http://www.burgaud.com">version of SciTE for Win32</a> enhanced with a tab control to allow easy movement between buffers. Go to the "Goodies" area on this site. </p> <p> <a href="http://www.suneido.com"> Suneido</a> is an integrated application platform currently available for Win32 that includes an object-oriented language, client-server database, and user interface and reporting frameworks. </p> <p> <a href="http://www.allitis.com/agast/home.html"> Agast</a> is an authoring system for adventure games which includes a customised version of SciTE. </p> <p> <a href="http://boa-constructor.sourceforge.net/">Boa Constructor</a> is a RAD GUI Building IDE for the wxWidgets cross platform platform. Written using wxPython with the wxStyledTextCtrl used as its editor. </p> <p> <a href="http://www.python.org/download/windows/">PythonWin</a>, a Win32 IDE for Python, uses Scintilla for both its editing and interactive windows. </p> <h3> Editing Components </h3> <p> <a href="http://www.soft-gems.net/index.php/controls/unicodeeditor-formerly-unicode-syntax-editor">UniCodeEditor</a> is a Unicode aware syntax editor control for Delphi and C++ Builder. </p> <p> <a href="http://projects.gnome.org/gtksourceview/">GtkSourceView</a> is a text widget that extends the standard GTK+ 2.x text widget and improves it by implementing syntax highlighting and other features typical of a source editor. </p> <p> <a href="http://aeditor.rubyforge.org/">AEditor</a> is a free source code editing component implemented in Ruby. </p> <p> <a href="http://www.actiprosoftware.com/Products/DotNet/SyntaxEditor/Default.aspx">SyntaxEditor</a> is a commercial native .Net source code editing component. </p> <p> <a href="http://jedit.sourceforge.net/">jEdit</a> is a good Open Source syntax colouring editor written in and for Java. </p> <p> <a href="http://www.gtk.org/">GTK+</a>, the GIMP Toolkit, contains a rich text editing widget.<br /> <a href="http://gedit.sourceforge.net/">Gedit</a> is an editor for GTK+/GNOME.<br /> <!-- <a href="http://www.daimi.au.dk/~mailund/gtk.html">GtkEditor</a> is a source code editing widget based on the GTK+ text widget.<br /> <a href="http://gide.gdev.net/">gIDE</a> is an IDE based on GTK+.<br /> <a href="http://www.bahnhof.se/~mikeh/linux_software.html">GtkExText</a> is a source code oriented text widget for GTK+. --> </p> <p> <a href="http://www.codeguru.com/">CodeGuru</a> has source code for several Win32 MFC based editors. </p> <a href="http://synedit.sourceforge.net/">SynEdit</a> is a Win32 edit control written in Delphi. <p> <a href="http://www.tetradyne.com/srcvwax.htm">SourceView</a> is a commercial editing component for Win32. </p> <p> <a href="http://www.winmain.com/">CodeMax</a> is another commercial component for Win32. </p> <h3> Documents </h3> <p> <a href="http://www.finseth.com/craft/">The Craft of Text Editing</a> describes how EMACS works, <i>Craig A. Finseth</i> </p> <p> <a href="http://www.cs.cmu.edu/~wjh/papers/byte.html">Data Structures in a Bit-Mapped Text Editor</a>, <i>Wilfred J. Hanson</i>, Byte January 1987 </p> <p> Text Editors: Algorithms and Architectures, <i>Ray Valdés</i>, Dr. Dobbs Journal April 1993 </p> <p> Macintosh User Interface Guidelines and TextEdit chapters of Inside Macintosh </p> <h3> Development Tools </h3> <p> Scintilla and SciTE were developed using the <a href="http://www.mingw.org/">Mingw version of GCC</a>. </p> <p> <a href="http://astyle.sourceforge.net/">AStyle</a> is a source code formatter for C++ and Java code. SciTE has an Indent command defined for .cxx files that uses AStyle. </p> <p> <a href="http://winmerge.org/">WinMerge</a> is an interactive diff / merge for Windows. I prefer code submissions in the form of source files rather than diffs and then run WinMerge over the files to work out how to merge. </p> <p> <a href="http://www.python.org">Python</a> is my favourite programming language. Scintilla was started after I tried to improve the editor built into <a href="http://www.python.org/download/windows/">PythonWin</a>, but was frustrated by the limitations of the Windows Richedit control which PythonWin used. </p> <p> <a href="http://www.cse.yorku.ca/~oz/">regex</a> is a public domain implementation of regular expression pattern matching used in Scintilla. </p> <p> Inspirational coding soundscapes by <a href="http://www.davidbridie.com.au">David Bridie</a>. </p> </body> </html> |
Added doc/ScintillaToDo.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="HTML Tidy, see www.w3.org" /> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title> Scintilla and SciTE To Do </title> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5">Scintilla and SciTE</font></a> </td> </tr> </table> <h2> Bugs and To Do List </h2> <h3> Feedback </h3> <p> Issues can be reported on the <a href="http://sourceforge.net/p/scintilla/bugs/">Bug Tracker</a> and features requested on the <a href="http://sourceforge.net/p/scintilla/feature-requests/">Feature Request Tracker</a>. </p> <h3> Scintilla Bugs </h3> <p> Automatic scrolling when text dragged near edge of window. </p> <h3> Scintilla To Do </h3> <p> Folding for languages that don't have it yet and good folding for languages that inherited poor folding from another languages folding code. </p> <p> Simple pattern based styling. </p> <p> Different height lines based upon tallest text on the line rather than on the tallest style possible. </p> <p> Composition of lexing for mixed languages (such as ASP+ over COBOL) by combining lexers. </p> <p> Stream folding which could be used to fold up the contents of HTML elements. </p> <p> Printing of highlight lines and folding margin. </p> <p> Flow diagrams inside editor similar to GRASP. </p> <p> More lexers for other languages. </p> <h3> SciTE To Do </h3> <p> Good regular expression support through a plugin. </p> <p> Allow file name based selection on all properties rather than just a chosen few. </p> <p> Opening from and saving to FTP servers. </p> <p> Setting to fold away comments upon opening. </p> <p> User defined fold ranges. </p> <p> Silent mode that does not display any message boxes. </p> <h3> Features I am unlikely to do </h3> <p> These are features I don't like or don't think are important enough to work on. Implementations are welcome from others though. </p> <p> Mouse wheel panning (press the mouse wheel and then move the mouse) on Windows. </p> <p> Adding options to the save dialog to save in a particular encoding or with a chosen line ending. </p> <h3> Directions </h3> <p> The main point of this development is Scintilla, and this is where most effort will go. SciTE will get new features, but only when they make my life easier - I am not intending to make it grow up to be a huge full-function IDE like Visual Cafe. The lines I've currently decided not to step over in SciTE are any sort of project facility and any configuration dialogs. SciTE for Windows now has a Director interface for communicating with a separate project manager application. </p> <p> If you are interested in contributing code, do not feel any need to make it cross platform. Just code it for your platform and I'll either reimplement for the other platform or ensure that there is no effect on the other platform. </p> </body> </html> |
Added doc/ScintillaUsage.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="HTML Tidy, see www.w3.org" /> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title> Scintilla Usage Notes </title> <style type="text/css"> SPAN { font-family: Verdana, Arial, Helvetica; font-size: 9pt; } .S0 { color: #808080; font-family: Verdana, Arial, Helvetica; } .S1 { font-family: Comic Sans MS, Times New Roman, Times; color: #007F00; font-size: 8pt; } .S2 { font-family: Comic Sans MS, Times New Roman, Times; color: #007F00; font-size: 8pt; } .S3 { font-family: Verdana, Arial, Helvetica; color: #7F7F7F; } .S4 { font-family: Verdana, Arial, Helvetica; color: #007F7F; } .S5 { color: #00007F; font-weight: bold; font-family: Verdana, Arial, Helvetica; } .S6 { color: #7F007F; font-family: Courier New, Courier; } .S7 { color: #7F007F; font-family: Courier New, Courier; } .S8 { color: #007F7F; } .S9 { color: #7F7F00; } .S10 { font-weight: bold; } </style> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5">Scintilla Usage Notes</font></a> </td> </tr> </table> <h2> Implementing Auto-Indent </h2> <p> The key idea is to use the SCN_CHARADDED notification to add indentation after a newline. </p> <p> The lParam on the notification is a pointer to a SCNotification structure whose ch member specifies the character added. If a newline was added, the previous line can be retrieved and the same indentation can be added to the new line. </p> <p> Here is the relevant portion of code from SciTE: (SciTE.cxx SciTEWindow::CharAdded) </p> <span class='S5'>if</span><span class='S0'> </span> <span class='S10'>(</span><span class='S11'>ch</span><span class='S0'> </span> <span class='S10'>==</span><span class='S0'> </span> <span class='S7'>'\r'</span><span class='S0'> </span> <span class='S10'>||</span><span class='S0'> </span> <span class='S11'>ch</span><span class='S0'> </span> <span class='S10'>==</span><span class='S0'> </span> <span class='S7'>'\n'</span><span class='S10'>)</span><span class='S0'> </span> <span class='S10'>{</span><span class='S0'><br /> </span> <span class='S5'>char</span><span class='S0'> </span> <span class='S11'>linebuf</span><span class='S10'>[</span><span class='S4'>1000</span><span class='S10'>];</span><span class='S0'><br /> </span> <span class='S5'>int</span><span class='S0'> </span> <span class='S11'>curLine</span><span class='S0'> </span> <span class='S10'>=</span><span class='S0'> </span> <span class='S11'>GetCurrentLineNumber</span><span class='S10'>();</span><span class='S0'><br /> </span> <span class='S5'>int</span><span class='S0'> </span> <span class='S11'>lineLength</span><span class='S0'> </span> <span class='S10'> =</span><span class='S0'> </span> <span class='S11'>SendEditor</span><span class='S10'>(</span><span class='S11'>SCI_LINELENGTH</span><span class='S10'>,</span><span class='S0'> </span> <span class='S11'>curLine</span><span class='S10'>);</span><span class='S0'><br /> </span> <span class='S2'> //Platform::DebugPrintf("[CR] %d len = %d\n", curLine, lineLength);</span><span class='S0'><br /> </span> <span class='S5'>if</span><span class='S0'> </span> <span class='S10'>(</span><span class='S11'>curLine</span><span class='S0'> </span> <span class='S10'>></span><span class='S0'> </span> <span class='S4'>0</span><span class='S0'> </span> <span class='S10'>&&</span><span class='S0'> </span> <span class='S11'>lineLength</span><span class='S0'> </span> <span class='S10'> <=</span><span class='S0'> </span> <span class='S4'>2</span><span class='S10'>)</span><span class='S0'> </span> <span class='S10'>{</span><span class='S0'><br /> </span> <span class='S5'>int</span><span class='S0'> </span> <span class='S11'>prevLineLength</span><span class='S0'> </span> <span class='S10'> =</span><span class='S0'> </span> <span class='S11'>SendEditor</span><span class='S10'>(</span><span class='S11'>SCI_LINELENGTH</span><span class='S10'>,</span><span class='S0'> </span> <span class='S11'>curLine</span><span class='S0'> </span> <span class='S10'>-</span><span class='S0'> </span> <span class='S4'>1</span><span class='S10'>);</span><span class='S0'><br /> </span> <span class='S5'>if</span><span class='S0'> </span> <span class='S10'>(</span><span class='S11'>prevLineLength</span><span class='S0'> </span> <span class='S10'><</span><span class='S0'> </span> <span class='S5'>sizeof</span><span class='S10'>(</span><span class='S11'>linebuf</span><span class='S10'>))</span><span class='S0'> </span> <span class='S10'>{</span><span class='S0'><br /> </span> <span class='S11'>WORD</span><span class='S0'> </span> <span class='S11'>buflen</span><span class='S0'> </span> <span class='S10'>=</span><span class='S0'> </span> <span class='S5'>sizeof</span><span class='S10'>(</span><span class='S11'>linebuf</span><span class='S10'>);</span><span class='S0'><br /> </span> <span class='S11'>memcpy</span><span class='S10'>(</span><span class='S11'>linebuf</span><span class='S10'>,</span><span class='S0'> </span> <span class='S10'>&</span><span class='S11'>buflen</span><span class='S10'>,</span><span class='S0'> </span> <span class='S5'>sizeof</span><span class='S10'>(</span><span class='S11'>buflen</span><span class='S10'>));</span><span class='S0'><br /> </span> <span class='S11'> SendEditor</span><span class='S10'>(</span><span class='S11'>EM_GETLINE</span><span class='S10'>,</span><span class='S0'> </span> <span class='S11'>curLine</span><span class='S0'> </span> <span class='S10'>-</span><span class='S0'> </span> <span class='S4'>1</span><span class='S10'>,</span><span class='S0'><br /> </span> <span class='S5'>reinterpret_cast</span><span class='S10'><</span><span class='S11'>LPARAM</span><span class='S10'>>(</span><span class='S5'>static_cast</span><span class='S10'><</span><span class='S5'>char</span><span class='S0'> </span> <span class='S10'>*>(</span><span class='S11'>linebuf</span><span class='S10'>)));</span><span class='S0'><br /> </span> <span class='S11'>linebuf</span><span class='S10'>[</span><span class='S11'>prevLineLength</span><span class='S10'>]</span><span class='S0'> </span> <span class='S10'>=</span><span class='S0'> </span> <span class='S7'>'\0'</span><span class='S10'>;</span><span class='S0'><br /> </span> <span class='S5'>for</span><span class='S0'> </span> <span class='S10'>(</span><span class='S5'>int</span><span class='S0'> </span> <span class='S11'>pos</span><span class='S0'> </span> <span class='S10'>=</span><span class='S0'> </span> <span class='S4'>0</span><span class='S10'>;</span><span class='S0'> </span> <span class='S11'>linebuf</span><span class='S10'>[</span><span class='S11'>pos</span><span class='S10'>];</span><span class='S0'> </span> <span class='S11'>pos</span><span class='S10'>++)</span><span class='S0'> </span> <span class='S10'>{</span><span class='S0'><br /> </span> <span class='S5'>if</span><span class='S0'> </span> <span class='S10'>(</span><span class='S11'>linebuf</span><span class='S10'>[</span><span class='S11'>pos</span><span class='S10'>]</span><span class='S0'> </span> <span class='S10'>!=</span><span class='S0'> </span> <span class='S7'>' '</span><span class='S0'> </span> <span class='S10'>&&</span><span class='S0'> </span> <span class='S11'> linebuf</span><span class='S10'>[</span><span class='S11'>pos</span><span class='S10'>]</span><span class='S0'> </span> <span class='S10'>!=</span><span class='S0'> </span> <span class='S7'>'\t'</span><span class='S10'>)</span><span class='S0'><br /> </span> <span class='S11'>linebuf</span><span class='S10'>[</span><span class='S11'>pos</span><span class='S10'>]</span><span class='S0'> </span> <span class='S10'>=</span><span class='S0'> </span> <span class='S7'>'\0'</span><span class='S10'>;</span><span class='S0'><br /> </span> <span class='S10'>}</span><span class='S0'><br /> </span> <span class='S11'> SendEditor</span><span class='S10'>(</span><span class='S11'>EM_REPLACESEL</span><span class='S10'>,</span><span class='S0'> </span> <span class='S4'>0</span><span class='S10'>,</span><span class='S0'> </span> <span class='S5'> reinterpret_cast</span><span class='S10'><</span><span class='S11'>LPARAM</span><span class='S10'>>(</span><span class='S5'>static_cast</span><span class='S10'><</span><span class='S5'>char</span><span class='S0'> </span> <span class='S10'>*>(</span><span class='S11'>linebuf</span><span class='S10'>)));</span><span class='S0'><br /> </span> <span class='S10'>}</span><span class='S0'><br /> </span> <span class='S10'>}</span><br /> <p style="margin-bottom: 0in"> Of course, fancier handling could be implemented. For example, if the previous line was the start of a control construct, the next line could be automatically indented one tab further. (Assuming that is your indenting style.) </p> <h2> Implementing Syntax Styling </h2> <p> Syntax styling is handled by the SCN_STYLENEEDED notification. Scintilla keeps track of the end of the styled text - this is retrieved with SCI_GETENDSTYLED. In response to the SCN_STYLENEEDED notification, you should apply styles to the text from ENDSTYLED to the position specified by the notification. </p> <p> Here is the relevant portion of code from SciTE: (SciTE.cxx) </p> <span class='S5'>void</span><span class='S0'> </span> <span class='S11'> SciTEWindow</span><span class='S10'>::</span><span class='S11'>Notify</span><span class='S10'>(</span><span class='S11'>SCNotification</span><span class='S0'> </span> <span class='S10'>*</span><span class='S11'>notification</span><span class='S10'>)</span><span class='S0'> </span> <span class='S10'>{</span><span class='S0'><br /> </span> <span class='S5'>switch</span><span class='S0'> </span> <span class='S10'>(</span><span class='S11'>notification</span><span class='S10'>-></span><span class='S11'>nmhdr.code</span><span class='S10'>)</span><span class='S0'> </span> <span class='S10'>{</span><span class='S0'><br /> </span> <span class='S5'>case</span><span class='S0'> </span> <span class='S11'>SCN_STYLENEEDED</span><span class='S10'>:</span><span class='S0'> </span> <span class='S10'>{</span><span class='S0'><br /> </span> <span class='S5'>if</span><span class='S0'> </span> <span class='S10'>(</span><span class='S11'>notification</span><span class='S10'>-></span><span class='S11'>nmhdr.idFrom</span><span class='S0'> </span> <span class='S10'>==</span><span class='S0'> </span> <span class='S11'>IDM_SRCWIN</span><span class='S10'>)</span><span class='S0'> </span> <span class='S10'>{</span><span class='S0'><br /> </span> <span class='S5'>int</span><span class='S0'> </span> <span class='S11'> endStyled</span><span class='S0'> </span> <span class='S10'>=</span><span class='S0'> </span> <span class='S11'>SendEditor</span><span class='S10'>(</span><span class='S11'>SCI_GETENDSTYLED</span><span class='S10'>);</span><span class='S0'><br /> </span> <span class='S5'>int</span><span class='S0'> </span> <span class='S11'> lineEndStyled</span><span class='S0'> </span> <span class='S10'>=</span><span class='S0'> </span> <span class='S11'>SendEditor</span><span class='S10'>(</span><span class='S11'>EM_LINEFROMCHAR</span><span class='S10'>,</span><span class='S0'> </span> <span class='S11'>endStyled</span><span class='S10'>);</span><span class='S0'><br /> </span> <span class='S11'>endStyled</span><span class='S0'> </span> <span class='S10'> =</span><span class='S0'> </span> <span class='S11'>SendEditor</span><span class='S10'>(</span><span class='S11'>EM_LINEINDEX</span><span class='S10'>,</span><span class='S0'> </span> <span class='S11'>lineEndStyled</span><span class='S10'>);</span><span class='S0'><br /> </span> <span class='S11'>Colourise</span><span class='S10'>(</span><span class='S11'>endStyled</span><span class='S10'>,</span><span class='S0'> </span> <span class='S11'>notification</span><span class='S10'>-></span><span class='S11'>position</span><span class='S10'>);</span><br /> <p> Colourize(start, end) retrieves the specified range of text and then calls ColourizeDoc in keywords.cxx. It starts the process by calling: </p> <span class='S11'>SendMessage</span><span class='S10'>(</span><span class='S11'>hwnd</span><span class='S10'>,</span><span class='S0'> </span> <span class='S11'>SCI_STARTSTYLING</span><span class='S10'>,</span><span class='S0'> </span> <span class='S11'>startPos</span><span class='S10'>,</span><span class='S0'> </span> <span class='S4'>31</span><span class='S10'>);</span><br /> <p> and then for each token of the text, calling: </p> <span class='S11'>SendMessage</span><span class='S10'>(</span><span class='S11'>hwnd</span><span class='S10'>,</span><span class='S0'> </span> <span class='S11'>SCI_SETSTYLING</span><span class='S10'>,</span><span class='S0'> </span> <span class='S11'>length</span><span class='S10'>,</span><span class='S0'> </span> <span class='S11'>style</span><span class='S10'>);</span><br /> <p> where style is a number from 0 to 31 whose appearance has been defined using the SCI_STYLESET... messages. </p> <h2> Implementing Calltips </h2> <p> Again, the SCN_CHARADDED notification is used to catch when an opening parenthesis is added. The preceding word can then be retrieved from the current line: </p> <span class='S5'>char</span><span class='S0'> </span> <span class='S11'>linebuf</span><span class='S10'>[</span><span class='S4'>1000</span><span class='S10'>];</span><span class='S0'><br /> </span> <span class='S5'>int</span><span class='S0'> </span> <span class='S11'>current</span><span class='S0'> </span> <span class='S10'>=</span><span class='S0'> </span> <span class='S11'>SendEditor</span><span class='S10'>(</span><span class='S11'>SCI_GETCURLINE</span><span class='S10'>,</span><span class='S0'> </span> <span class='S5'>sizeof</span><span class='S10'>(</span><span class='S11'>linebuf</span><span class='S10'>),</span><span class='S0'><br /> </span> <span class='S5'> reinterpret_cast</span><span class='S10'><</span><span class='S11'>LPARAM</span><span class='S10'>>(</span><span class='S5'>static_cast</span><span class='S10'><</span><span class='S5'>char</span><span class='S0'> </span> <span class='S10'>*>(</span><span class='S11'>linebuf</span><span class='S10'>)));</span><span class='S0'><br /> </span> <span class='S5'>int</span><span class='S0'> </span> <span class='S11'>pos</span><span class='S0'> </span> <span class='S10'>=</span><span class='S0'> </span> <span class='S11'>SendEditor</span><span class='S10'>(</span><span class='S11'>SCI_GETCURRENTPOS</span><span class='S10'>);</span><span class='S0'><br /> <br /> </span> <span class='S5'>int</span><span class='S0'> </span> <span class='S11'>startword</span><span class='S0'> </span> <span class='S10'>=</span><span class='S0'> </span> <span class='S11'>current</span><span class='S0'> </span> <span class='S10'>-</span><span class='S0'> </span> <span class='S4'>1</span><span class='S10'>;</span><span class='S0'><br /> </span> <span class='S5'>while</span><span class='S0'> </span> <span class='S10'>(</span><span class='S11'>startword</span><span class='S0'> </span> <span class='S10'>></span><span class='S0'> </span> <span class='S4'>0</span><span class='S0'> </span> <span class='S10'>&&</span><span class='S0'> </span> <span class='S11'>isalpha</span><span class='S10'>(</span><span class='S11'>linebuf</span><span class='S10'>[</span><span class='S11'>startword</span><span class='S0'> </span> <span class='S10'>-</span><span class='S0'> </span> <span class='S4'>1</span><span class='S10'>]))</span><span class='S0'><br /> </span> <span class='S11'> startword</span><span class='S10'>--;</span><span class='S0'><br /> </span> <span class='S11'>linebuf</span><span class='S10'>[</span><span class='S11'>current</span><span class='S0'> </span> <span class='S10'>-</span><span class='S0'> </span> <span class='S4'>1</span><span class='S10'>]</span><span class='S0'> </span> <span class='S10'>=</span><span class='S0'> </span> <span class='S7'>'\0'</span><span class='S10'>;</span><span class='S0'><br /> </span> <span class='S5'>char</span><span class='S10'>*</span><span class='S0'> </span> <span class='S11'>word</span><span class='S0'> </span> <span class='S10'>=</span><span class='S0'> </span> <span class='S11'>linebuf</span><span class='S0'> </span> <span class='S10'>+</span><span class='S0'> </span> <span class='S11'>startword</span><span class='S10'>;</span><br /> <p> Then if a calltip is available it can be displayed. The calltip appears immediately below the position specified. The calltip can be multiple lines separated by newlines (\n). </p> <span class='S11'>pos</span><span class='S0'> </span> <span class='S10'>=</span><span class='S0'> </span> <span class='S11'>SendMessage</span><span class='S10'>(</span><span class='S11'>hwnd</span><span class='S10'>,</span><span class='S0'> </span> <span class='S11'>SCI_GETCURRENTPOS</span><span class='S10'>,</span><span class='S0'> </span> <span class='S4'>0</span><span class='S10'>,</span><span class='S0'> </span> <span class='S4'>0</span><span class='S10'>);</span><span class='S0'><br /> </span> <span class='S11'>SendMessageText</span><span class='S10'>(</span><span class='S11'>hwnd</span><span class='S10'>,</span><span class='S0'> </span> <span class='S11'>SCI_CALLTIPSHOW</span><span class='S10'>,</span><span class='S0'> </span> <span class='S11'>pos</span><span class='S0'> </span> <span class='S10'>-</span><span class='S0'> </span> <span class='S11'>wordLen</span><span class='S0'> </span> <span class='S10'>-</span><span class='S0'> </span> <span class='S4'>1</span><span class='S10'>,</span><span class='S0'> </span> <span class='S11'>calltip</span><span class='S10'>);</span><br /> <p> The calltip can be removed when a closing parenthesis is entered: </p> <span class='S5'>if</span><span class='S0'> </span> <span class='S10'>(</span><span class='S11'>SendMessage</span><span class='S10'>(</span><span class='S11'>hwnd</span><span class='S10'>,</span><span class='S0'> </span> <span class='S11'>SCI_CALLTIPACTIVE</span><span class='S10'>,</span><span class='S0'> </span> <span class='S4'>0</span><span class='S10'>,</span><span class='S0'> </span> <span class='S4'>0</span><span class='S10'>))</span><span class='S0'><br /> </span> <span class='S11'> SendMessage</span><span class='S10'>(</span><span class='S11'>hwnd</span><span class='S10'>,</span><span class='S0'> </span> <span class='S11'> SCI_CALLTIPCANCEL</span><span class='S10'>,</span><span class='S0'> </span> <span class='S4'>0</span><span class='S10'>,</span><span class='S0'> </span> <span class='S4'> 0</span><span class='S10'>);</span><br /> <p> Obviously, it is up the application to look after supplying the appropriate calltip text. </p> <p> SciTE goes one step further, counting the commas between arguments and highlighting the corresponding part of the calltip. This code is in ContinueCallTip. </p> <p> <i>Page contributed by Andrew McKinlay.</i> </p> </body> </html> |
Added doc/ScriptLexer.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>SciTE Script Lexer</title> <meta name="Generator" content="SciTE - www.Scintilla.org" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <style type="text/css"> .S0 { color: #FF0000; } .S2 { font-family: 'Comic Sans MS'; color: #007F00; font-size: 9pt; } .S4 { color: #007F7F; } .S5 { color: #00007F; font-weight: bold; } .S6 { color: #7F007F; } .S10 { color: #000000; } .S14 { color: #00007F; background: #F5F5FF; text-decoration: inherit; } .Z0 { color: #7f007f; font-weight: bold; } .Z1 { color: #000000; } .Z2 { color: #000080; font-weight: bold; } .Z3 { color: #008000; font-family: 'Georgia'; font-size: 9pt; font-style:italic; } span { font-family: 'Verdana'; color: #000000; font-size: 10pt; } .example { color: #008000; font-weight: bold; } DIV.example { background: #F7FCF7; border: 1px solid #C0D7C0; margin: 0.3em 3em; padding: 0.3em 0.6em; font-size: 80%; } DIV.highlighted { background: #F7FCF7; border: 1px solid #C0D7C0; margin: 0.3em 3em; padding: 0.3em 0.6em; font-size: 80%; } table { border: 1px solid #1F1F1F; border-collapse: collapse; } td { border: 1px solid #1F1F1F; padding: 1px 5px 1px 5px; } th { border: 1px solid #1F1F1F; padding: 1px 5px 1px 5px; } </style> </head> <body bgcolor="#FFFFFF"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td> <img src="SciTEIco.png" border="3" height="64" width="64" alt="Scintilla icon" /> </td> <td> <a href="index.html" style="color:white;text-decoration:none"><font size="5"> SciTE Script Lexer</font></a> </td> </tr> </table> <h3> Warning </h3> <p>This feature is being developed and is not stable. The API may change in the future.</p> <h3> Writing lexers in Lua </h3> <p>A lexer may be written as a script in the Lua language instead of in C++. This is a little simpler and allows lexers to be developed without using a C++ compiler.</p> <p>A script lexer is attached by setting the file lexer to be a name that starts with "script_". Styles and other properties can then be assigned using this name. For example,</p> <div class="example"> lexer.*.zog=script_zog<br/> style.script_zog.0=fore:#7f007f,bold<br/> style.script_zog.1=fore:#000000<br/> style.script_zog.2=fore:#000080,bold<br/> style.script_zog.3=fore:#008000,font:Georgia,italics,size:9 </div> <p>Then the lexer is implemented in Lua similar to this:</p> <div class="highlighted"> <span><span class="S2">-- -*- coding: utf-8 -*-</span><br /> <br /> <span class="S5">function</span><span class="S0"> </span>OnStyle<span class="S10">(</span>styler<span class="S10">)</span><br /> <span class="S0"> </span>S_DEFAULT<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><br /> <span class="S0"> </span>S_IDENTIFIER<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">1</span><br /> <span class="S0"> </span>S_KEYWORD<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">2</span><br /> <span class="S0"> </span>S_UNICODECOMMENT<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">3</span><br /> <span class="S0"> </span>identifierCharacters<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S6">"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"</span><br /> <br /> <span class="S0"> </span>styler<span class="S10">:</span>StartStyling<span class="S10">(</span>styler.startPos<span class="S10">,</span><span class="S0"> </span>styler.lengthDoc<span class="S10">,</span><span class="S0"> </span>styler.initStyle<span class="S10">)</span><br /> <span class="S0"> </span><span class="S5">while</span><span class="S0"> </span>styler<span class="S10">:</span>More<span class="S10">()</span><span class="S0"> </span><span class="S5">do</span><br /> <br /> <span class="S0"> </span><span class="S2">-- Exit state if needed</span><br /> <span class="S0"> </span><span class="S5">if</span><span class="S0"> </span>styler<span class="S10">:</span>State<span class="S10">()</span><span class="S0"> </span><span class="S10">==</span><span class="S0"> </span>S_IDENTIFIER<span class="S0"> </span><span class="S5">then</span><br /> <span class="S0"> </span><span class="S5">if</span><span class="S0"> </span><span class="S5">not</span><span class="S0"> </span>identifierCharacters<span class="S10">:</span>find<span class="S10">(</span>styler<span class="S10">:</span>Current<span class="S10">(),</span><span class="S0"> </span><span class="S4">1</span><span class="S10">,</span><span class="S0"> </span><span class="S5">true</span><span class="S10">)</span><span class="S0"> </span><span class="S5">then</span><br /> <span class="S0"> </span>identifier<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span>styler<span class="S10">:</span>Token<span class="S10">()</span><br /> <span class="S0"> </span><span class="S5">if</span><span class="S0"> </span>identifier<span class="S0"> </span><span class="S10">==</span><span class="S0"> </span><span class="S6">"if"</span><span class="S0"> </span><span class="S5">or</span><span class="S0"> </span>identifier<span class="S0"> </span><span class="S10">==</span><span class="S0"> </span><span class="S6">"end"</span><span class="S0"> </span><span class="S5">then</span><br /> <span class="S0"> </span>styler<span class="S10">:</span>ChangeState<span class="S10">(</span>S_KEYWORD<span class="S10">)</span><br /> <span class="S0"> </span><span class="S5">end</span><br /> <span class="S0"> </span>styler<span class="S10">:</span>SetState<span class="S10">(</span>S_DEFAULT<span class="S10">)</span><br /> <span class="S0"> </span><span class="S5">end</span><br /> <span class="S0"> </span><span class="S5">elseif</span><span class="S0"> </span>styler<span class="S10">:</span>State<span class="S10">()</span><span class="S0"> </span><span class="S10">==</span><span class="S0"> </span>S_UNICODECOMMENT<span class="S0"> </span><span class="S5">then</span><br /> <span class="S0"> </span><span class="S5">if</span><span class="S0"> </span>styler<span class="S10">:</span>Match<span class="S10">(</span><span class="S6">"»"</span><span class="S10">)</span><span class="S0"> </span><span class="S5">then</span><br /> <span class="S0"> </span>styler<span class="S10">:</span>ForwardSetState<span class="S10">(</span>S_DEFAULT<span class="S10">)</span><br /> <span class="S0"> </span><span class="S5">end</span><br /> <span class="S0"> </span><span class="S5">end</span><br /> <br /> <span class="S0"> </span><span class="S2">-- Enter state if needed</span><br /> <span class="S0"> </span><span class="S5">if</span><span class="S0"> </span>styler<span class="S10">:</span>State<span class="S10">()</span><span class="S0"> </span><span class="S10">==</span><span class="S0"> </span>S_DEFAULT<span class="S0"> </span><span class="S5">then</span><br /> <span class="S0"> </span><span class="S5">if</span><span class="S0"> </span>styler<span class="S10">:</span>Match<span class="S10">(</span><span class="S6">"«"</span><span class="S10">)</span><span class="S0"> </span><span class="S5">then</span><br /> <span class="S0"> </span>styler<span class="S10">:</span>SetState<span class="S10">(</span>S_UNICODECOMMENT<span class="S10">)</span><br /> <span class="S0"> </span><span class="S5">elseif</span><span class="S0"> </span>identifierCharacters<span class="S10">:</span>find<span class="S10">(</span>styler<span class="S10">:</span>Current<span class="S10">(),</span><span class="S0"> </span><span class="S4">1</span><span class="S10">,</span><span class="S0"> </span><span class="S5">true</span><span class="S10">)</span><span class="S0"> </span><span class="S5">then</span><br /> <span class="S0"> </span>styler<span class="S10">:</span>SetState<span class="S10">(</span>S_IDENTIFIER<span class="S10">)</span><br /> <span class="S0"> </span><span class="S5">end</span><br /> <span class="S0"> </span><span class="S5">end</span><br /> <br /> <span class="S0"> </span>styler<span class="S10">:</span>Forward<span class="S10">()</span><br /> <span class="S0"> </span><span class="S5">end</span><br /> <span class="S0"> </span>styler<span class="S10">:</span>EndStyling<span class="S10">()</span><br /> <span class="S5">end</span><br /> <span class="S0"></span></span> </div> <p> The result looks like </p> <div class="highlighted"> <span><span class="Z1">proc</span><span class="Z0"> </span><span class="Z1">clip</span><span class="Z0">(</span><span class="Z1">int</span><span class="Z0"> </span><span class="Z1">a</span><span class="Z0">)</span><br /> <span class="Z3">« Clip into the positive zone »</span><br /> <span class="Z2">if</span><span class="Z0"> (</span><span class="Z1">a</span><span class="Z0"> > 0) </span><span class="Z1">a</span><br /> <span class="Z0">0</span><br /> <span class="Z2">end</span></span> </div> <br /> <h3>Code Structure</h3> <h4>Document Loop</h4> <p>The lexer loops through the part of the document indicated assigning a style to each character.</p> <div class="highlighted"> <span>styler:StartStyling<span class="S10">(</span>styler.startPos<span class="S10">,</span><span class="S0"> </span>styler.lengthDoc<span class="S10">,</span><span class="S0"> </span>styler.initStyle<span class="S10"><span class="S10">)</span><br /> <span class="S5">while</span><span class="S0"> </span>styler:More<span class="S10">()</span><span class="S0"> </span><span class="S5">do</span><br /> <span class="S0"> </span><span class="S2">-- Code that examines the text and sets lexical states</span><br /> <span class="S0"> </span>styler:Forward<span class="S10">()</span><br /> <span class="S5">end</span><br /> styler:EndStyling<span class="S10">()</span><br /> </span></div> <p>There are many different ways to structure the code that examines the text and sets lexical states. A structure that has proven useful in C++ lexers is to write two blocks of code as shown in the example. The first block checks if the current state should end and if so sets the state to the default 0. The second block is responsible for detecting whether a new state should be entered from the default state. This structure means everything is dealt with as switching from or to the default state and avoids having to consider many combinations of states.</p> <h4>Encodings</h4> <p>The styler iterates over whole characters rather than bytes. Thus if the document is encoded in UTF-8, styler:Current() may be a multibyte string. If the script is also encoded in UTF-8, then it is easy to check against Unicode characters with code like</p> <div class="highlighted"> <span><span class="S5">if</span><span class="S0"> </span>styler:Current<span class="S10">()</span><span class="S0"> </span><span class="S10">==</span><span class="S0"> </span><span class="S6">"«"</span><span class="S5"> then</span><br /> </span></div> <p>If using an encoding like Latin-1 and the script is also encoded in the same encoding then literals can be used as above.</p> <p>If the language can be encoded in different ways then more complex code may be needed along with encoding-specific code.</p> <h4>Checking Before</h4> <p>Sometimes a lexer needs to see some information earlier in the file, perhaps a declaration changes the syntax or the particular form of quote at the start of a string must be matched at its end. Since the standard loop only goes forward from the starting position, different calls must be used like CharAt and StyleAt. These use byte positions and do not treat multi-byte characters as single entities.</p> <h4>Performance</h4> <p>The lexer above can lex approximately 90K per second on a 2.4 GHz Athlon 64. For most situations, this will feel completely fluid.</p> <p>More complex lexers will be slower. If a lexer is so slow that the application becomes unresponsive then the lexer can choose to split up each request. It can do so by deciding upon a range of whole lines and using this range as the arguments to StartStyling. This allows the user's keystrokes and mouse moves to be processed. The lexer will automatically be called again to lex more of the document.</p> <br /> <h3>API</h3> <p>The API of the styler object passed to OnStyle:</p> <table cellpadding="0" cellspacing="0" border="1" summary="Command line escape sequences"> <thead> <tr><th>Name</th><th>Explanation</th></tr> </thead> <tr><td>StartStyling(startPos, length, initStyle)</td> <td>Start setting styles from startPos for length with initial style initStyle</td></tr> <tr><td>EndStyling()</td> <td>Styling has been completed so tidy up</td></tr> <tr><td>More() → boolean</td> <td>Are there any more characters to process</td></tr> <tr><td>Forward()</td> <td>Move forward one character</td></tr> <tr><td>Position() → integer</td> <td>What is the position in the document of the current character</td></tr> <tr><td>AtLineStart() → boolean</td> <td>Is the current character the first on a line</td></tr> <tr><td>AtLineEnd() → boolean</td> <td>Is the current character the last on a line</td></tr> <tr><td>State() → integer</td> <td>The current lexical state value</td></tr> <tr><td>SetState(state)</td> <td>Set the style of the current token to the current state and then change the state to the argument</td></tr> <tr><td>ForwardSetState(state)</td> <td>Combination of moving forward and setting the state. Useful when the current character is a token terminator like " for a string.</td></tr> <tr><td>ChangeState(state)</td> <td>Change the current state so that the state of the current token will be set to the argument</td></tr> <tr><td>Current() → string</td> <td>The current character</td></tr> <tr><td>Next() → string</td> <td>The next character</td></tr> <tr><td>Previous() → string</td> <td>The previous character</td></tr> <tr><td>Token() → string</td> <td>The current token</td></tr> <tr><td>Match(string) → boolean</td> <td>Is the text from the current position the same as the argument?</td></tr> <tr><td>Line(position) → integer</td> <td>Convert a byte position into a line number</td></tr> <tr><td>CharAt(position) → integer</td> <td>Unsigned byte value at argument</td></tr> <tr><td>StyleAt(position) → integer</td> <td>Style value at argument</td></tr> <tr><td>LevelAt(line) → integer</td> <td>Fold level for a line</td></tr> <tr><td>SetLevelAt(line, level)</td> <td>Set the fold level for a line</td></tr> <tr><td>LineState(line) → integer</td> <td>State value for a line</td></tr> <tr><td>SetLineState(line, state)</td> <td>Set state value for a line. This can be used to store extra information from lexing, such as a current language mode, so that there is no need to look back in the document.</td></tr> <tr><td>startPos : integer</td> <td>Start of the range to be lexed</td></tr> <tr><td>lengthDoc : integer</td> <td>Length of the range to be lexed</td></tr> <tr><td>initStyle : integer</td> <td>Starting style</td></tr> <tr><td>language : string</td> <td>Name of the language. Allows implementation of multiple languages with one OnStyle function.</td></tr> </table> <br /> <h3> A line-oriented example. </h3> <p>This example is for a line-oriented language as is sometimes used for configuration files. It uses low level direct calls instead of the StartStyling/More/Forward/EndStyling calls.</p> <div class="highlighted"> <span><span class="S2">-- A line oriented lexer - style the line according to the first character</span><br /> <span class="S5">function</span><span class="S0"> </span>OnStyle<span class="S10">(</span>styler<span class="S10">)</span><br /> <span class="S0"> </span>lineStart<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span>editor<span class="S10">:</span>LineFromPosition<span class="S10">(</span>styler.startPos<span class="S10">)</span><br /> <span class="S0"> </span>lineEnd<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span>editor<span class="S10">:</span>LineFromPosition<span class="S10">(</span>styler.startPos<span class="S0"> </span><span class="S10">+</span><span class="S0"> </span>styler.lengthDoc<span class="S10">)</span><br /> <span class="S0"> </span>editor<span class="S10">:</span>StartStyling<span class="S10">(</span>styler.startPos<span class="S10">,</span><span class="S0"> </span><span class="S4">31</span><span class="S10">)</span><br /> <span class="S0"> </span><span class="S5">for</span><span class="S0"> </span>line<span class="S10">=</span>lineStart<span class="S10">,</span>lineEnd<span class="S10">,</span><span class="S4">1</span><span class="S0"> </span><span class="S5">do</span><br /> <span class="S0"> </span>lengthLine<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span>editor<span class="S10">:</span>PositionFromLine<span class="S10">(</span>line<span class="S10">+</span><span class="S4">1</span><span class="S10">)</span><span class="S0"> </span><span class="S10">-</span><span class="S0"> </span>editor<span class="S10">:</span>PositionFromLine<span class="S10">(</span>line<span class="S10">)</span><br /> <span class="S0"> </span>lineText<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span>editor<span class="S10">:</span>GetLine<span class="S10">(</span>line<span class="S10">)</span><br /> <span class="S0"> </span>first<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S14">string.sub</span><span class="S10">(</span>lineText<span class="S10">,</span><span class="S4">1</span><span class="S10">,</span><span class="S4">1</span><span class="S10">)</span><br /> <span class="S0"> </span>style<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">0</span><br /> <span class="S0"> </span><span class="S5">if</span><span class="S0"> </span>first<span class="S0"> </span><span class="S10">==</span><span class="S0"> </span><span class="S6">"+"</span><span class="S0"> </span><span class="S5">then</span><br /> <span class="S0"> </span>style<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">1</span><br /> <span class="S0"> </span><span class="S5">elseif</span><span class="S0"> </span>first<span class="S0"> </span><span class="S10">==</span><span class="S0"> </span><span class="S6">" "</span><span class="S0"> </span><span class="S5">or</span><span class="S0"> </span>first<span class="S0"> </span><span class="S10">==</span><span class="S0"> </span><span class="S6">"\t"</span><span class="S0"> </span><span class="S5">then</span><br /> <span class="S0"> </span>style<span class="S0"> </span><span class="S10">=</span><span class="S0"> </span><span class="S4">2</span><br /> <span class="S0"> </span><span class="S5">end</span><br /> <span class="S0"> </span>editor<span class="S10">:</span>SetStyling<span class="S10">(</span>lengthLine<span class="S10">,</span><span class="S0"> </span>style<span class="S10">)</span><br /> <span class="S0"> </span><span class="S5">end</span><br /> <span class="S5">end</span><br /> <span class="S0"></span></span> </div> </body> </html> |
Added doc/Steps.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type"><title>How to use the Scintilla Edit Control in windows?</title></head><body bgcolor="#ffffff"> <p><h2>How to use the Scintilla Edit Control in windows?</h2> <p> This should be a little step by step explanation how to use Scintilla in the windows environment. </p> </p> <p><h2>How to create Scintilla Edit Control?</h2> <p> First of all, load the Scintilla DLL with something like: </p> <pre> hmod = LoadLibrary("SciLexer.DLL"); if (hmod==NULL) { MessageBox(hwndParent, "The Scintilla DLL could not be loaded.", "Error loading Scintilla", MB_OK | MB_ICONERROR); } </pre> <p> If the DLL was loaded successfully, then the DLL has registered (yes, by itself) a new window class. The new class called "Scintilla" is the new scintilla edit control. </p> <p> Now you can use this new control just like any other windows control. </p> <pre> hwndScintilla = CreateWindowEx(0, "Scintilla","", WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_CLIPCHILDREN, 10,10,500,400,hwndParent,(HMENU)GuiID, hInstance,NULL); </pre> <p> Note the new window class name: "Scintilla". By reaching this point you actually included a Scintilla Edit Control to your windows program. </p> </p> <p><h2>How to control the Scintilla Edit Control?</h2> <p> You can control Scintilla by sending commands to the Edit Control. There a 2 ways of doing this. A simple and fast way. </p> <p><h3>The simple way to control Scintilla</h3> <p> The simple way is just like with any other windows control. You can send messages to the Scintilla Edit Control and receive notifications from the control. (Note that the notifications are sent to the parent window of the Scintilla Edit Control.) </p> <p> The Scintilla Edit Control knows a special message for each command. To send commands to the Scintilla Edit Control you can use the SendMessage function. </p> <pre> SendMessage(hwndScintilla,sci_command,wparam,lparam); </pre> <p> like: </p> <pre> SendMessage(hwndScintilla,SCI_CREATEDOCUMENT, 0, 0); </pre> <p> Some of the commands will return a value and unused parameters should be set to NULL. </p> </p> <p><h3>The fast way to control Scintilla</h3> <p> The fast way of controlling the Scintilla Edit Control is to call message handling function by yourself. You can retrieve a pointer to the message handling function of the Scintilla Edit Control and call it directly to execute a command. This way is much more faster than the SendMessage() way. </p> <p> 1st you have to use the SCI_GETDIRECTFUNCTION and SCI_GETDIRECTPOINTER commands to retrieve the pointer to the function and a pointer which must be the first parameter when calling the retrieved function pointer. You have to do this with the SendMessage way :) </p> <p> The whole thing has to look like this: </p> <pre> int (*fn)(void*,int,int,int); void * ptr; int canundo; fn = (int (__cdecl *)(void *,int,int,int))SendMessage( hwndScintilla,SCI_GETDIRECTFUNCTION,0,0); ptr = (void *)SendMessage(hwndScintilla,SCI_GETDIRECTPOINTER,0,0); canundo = fn(ptr,SCI_CANUNDO,0,0); </pre> <p> with "fn" as the function pointer to the message handling function of the Scintilla Control and "ptr" as the pointer that must be used as 1st parameter. The next parameters are the Scintilla Command with its two (optional) parameters. </p> </p> <p><h3>How will I receive notifications?</h3> <p> Whenever an event occurs where Scintilla wants to inform you about something, the Scintilla Edit Control will send notification to the parent window. This is done by a WM_NOTITY message. When receiving that message, you have to look in the xxx struct for the actual message. </p> <p> So in Scintillas parent window message handling function you have to include some code like this: </p> <pre> NMHDR *lpnmhdr; [...] case WM_NOTIFY: lpnmhdr = (LPNMHDR) lParam; if(lpnmhdr->hwndFrom==hwndScintilla) { switch(lpnmhdr->code) { case SCN_CHARADDED: /* Hey, Scintilla just told me that a new */ /* character was added to the Edit Control.*/ /* Now i do something cool with that char. */ break; } } break; </pre> </p> </p> <p> <i>Page contributed by Holger Schmidt.</i> </p> </body></html> |
Added doc/annotations.png.
cannot compute difference between binary files
Added doc/demo.png.
cannot compute difference between binary files
Added doc/index.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="HTML Tidy, see www.w3.org" /> <meta name="generator" content="SciTE" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" /> <meta name="Description" content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." /> <meta name="Date.Modified" content="20130330" /> <style type="text/css"> #versionlist { margin: 0; padding: .5em; list-style-type: none; color: #FFCC99; background: #000000; } #versionlist li { margin-bottom: .5em; } #menu { margin: 0; padding: .5em 0; list-style-type: none; font-size: larger; background: #CCCCCC; } #menu li { margin: 0; padding: 0 .5em; display: inline; } </style> <script type="text/javascript"> function IsRemote() { var loc = '' + window.location; return loc.indexOf('http:') != -1; } </script> <title> Scintilla and SciTE </title> </head> <body bgcolor="#FFFFFF" text="#000000"> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td width="256"> <img src="SciWord.jpg" height="78" width="256" alt="Scintilla" /> </td> <td width="40%" align="left"> <font color="#FFCC99" size="4"> A free source code editing component for Win32 and GTK+</font> </td> <td width="40%" align="right"> <font color="#FFCC99" size="3"> Release version 3.3.0<br /> Site last modified March 30 2013</font> </td> <td width="20%"> </td> </tr> </table> <table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <tr> <td width="100%" style="background: url(http://www.scintilla.org/SciBreak.jpg) no-repeat;height:150px;"> </td> </tr> </table> <ul id="versionlist"> <li>Version 3.3.0 implements overlay scrollers and kinetic scrolling on Cocoa. Performance improved on GTK+ and Cocoa by performing more work in high-priority idle tasks.</li> <li>Version 3.2.5 SCI_ALLOCATEEXTENDEDSTYLES introduced so that different uses of extended styles can cooperate. Unicode line ends and substyles are added as provisional features which means they may change before becoming permanent.</li> </ul> <ul id="menu"> <li id="remote1"><a href="http://www.scintilla.org/SciTEImage.html">Screenshot</a></li> <li id="remote2"><a href="http://www.scintilla.org/ScintillaDownload.html">Download</a></li> <li><a href="http://www.scintilla.org/ScintillaDoc.html">Documentation</a></li> <li><a href="http://www.scintilla.org/ScintillaToDo.html">Bugs</a></li> <li id="remote3"><a href="http://www.scintilla.org/SciTE.html">SciTE</a></li> <li><a href="http://www.scintilla.org/ScintillaHistory.html">History</a></li> <li><a href="http://www.scintilla.org/ScintillaRelated.html">Related</a></li> </ul> <script type="text/javascript" language="JavaScript"><!-- if (!IsRemote()) { //if NOT remote... document.getElementById('remote1').style.display='none'; document.getElementById('remote2').style.display='none'; document.getElementById('remote3').style.display='none'; } //--></script> <p> <a href="http://www.scintilla.org/ScintillaDoc.html">Scintilla</a> is a free source code editing component. It comes with complete source code and a <a href="http://www.scintilla.org/License.txt">license</a> that permits use in any free project or commercial product. </p> <p> As well as features found in standard text editing components, Scintilla includes features especially useful when editing and debugging source code. These include support for syntax styling, error indicators, code completion and call tips. The selection margin can contain markers like those used in debuggers to indicate breakpoints and the current line. Styling choices are more open than with many editors, allowing the use of proportional fonts, bold and italics, multiple foreground and background colours and multiple fonts. </p> <p> <a href="http://www.scintilla.org/SciTE.html">SciTE</a> is a SCIntilla based Text Editor. Originally built to demonstrate Scintilla, it has grown to be a generally useful editor with facilities for building and running programs. It is best used for jobs with simple configurations - I use it for building test and demonstration programs as well as SciTE and Scintilla, themselves. </p> <p> Development of Scintilla started as an effort to improve the text editor in PythonWin. After being frustrated by problems in the Richedit control used by PythonWin, it looked like the best way forward was to write a new edit control. The biggest problem with Richedit and other similar controls is that they treat styling changes as important persistent changes to the document so they are saved into the undo stack and set the document's dirty flag. For source code, styling should not be persisted as it can be mechanically recreated. </p> <p> Scintilla and SciTE are currently available for Intel Win32 and Linux compatible operating systems with GTK+. They have been run on Windows XP, Windows 7, and on Ubuntu 10.10 with GTK+ 2.20. <a href="http://www.scintilla.org/SciTEImage.html">Here is a screenshot of SciTE.</a><br /> </p> <p> You can <a href="http://www.scintilla.org/ScintillaDownload.html">download Scintilla.</a> </p> <p> The source code can be downloaded via Mercurial at the Source Forge <a href="https://sourceforge.net/project/?group_id=2439">Scintilla project page</a>. </p> <p> <a href="http://www.scintilla.org/ScintillaRelated.html">Related sites.</a> </p> <p> <a href="http://www.scintilla.org/ScintillaToDo.html">Bugs and To Do list.</a> </p> <p> <a href="http://www.scintilla.org/ScintillaHistory.html">History and contribution credits.</a> </p> <p> <a href="http://www.scintilla.org/Icons.html">Icons that can be used with Scintilla.</a> </p> <p> Questions and comments about Scintilla should be directed to the <a href="http://groups.google.com/group/scintilla-interest">scintilla-interest</a> mailing list, which is for discussion of Scintilla and related projects, their bugs and future features. This is a low traffic list, averaging less than 50 messages per week. To avoid spam, only list members can write to the list. New versions of Scintilla are announced on scintilla-interest and may also be received by SourceForge members by clicking on the Monitor column icon for "scintilla" on <a href="https://sourceforge.net/project/showfiles.php?group_id=2439">the downloads page</a>. Messages sent to my personal email address that could have been sent to the list may receive no response. <br /> </p> There is a <a href="https://sourceforge.net/project/?group_id=2439">Scintilla project page</a> hosted on <script type="text/javascript" language="JavaScript"> <!-- if (IsRemote()) { document.write('<a href="http://sourceforge.net/projects/scintilla">'); document.write('<img src="http://sflogo.sourceforge.net/sflogo.php?group_id=2439&type=8" width="80" height="15" alt="Get Scintilla at SourceForge.net. Fast, secure and Free Open Source software downloads" /></a> '); } else { document.write('<a href="http://sourceforge.net/projects/scintilla">SourceForge<\/a>'); } //--> </script> <noscript> <a href="http://sourceforge.net/projects/scintilla"> <img src="http://sflogo.sourceforge.net/sflogo.php?group_id=2439&type=8" width="80" height="15" alt="Get Scintilla at SourceForge.net. Fast, secure and Free Open Source software downloads" /></a> </noscript> </body> </html> |
Added doc/scite.1.
> > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
.TH SCITE 1 "2001 February 26" .SH NAME SciTE \- a programmers text editor .SH SYNOPSIS .br .B SciTE [file ..] .SH DESCRIPTION .B SciTE is a graphical GTK+ based editor. It has support for indenting, highlighting, and shortcuts in a myriad of languages and can be extended by editing object-oriented configuration files. .PP Support is included for Java, C, C++, C#, Shell, Apache. .SH ON-LINE HELP Type Alt-H or Click the Help Pulldown menu. .SH AUTHOR Most of .B SciTE was made by Neil Hodgson, with a lot of help from others. See Help .br .SH BUGS Probably. |
Added doc/styledmargin.png.
cannot compute difference between binary files
Added gtk/Converter.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
// Scintilla source code edit control // Converter.h - Encapsulation of iconv // Copyright 2004 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. typedef GIConv ConverterHandle; const ConverterHandle iconvhBad = (ConverterHandle)(-1); // Since various versions of iconv can not agree on whether the src argument // is char ** or const char ** provide a templatised adaptor. template<typename T> size_t iconv_adaptor(size_t(*f_iconv)(ConverterHandle, T, size_t *, char **, size_t *), ConverterHandle cd, char** src, size_t *srcleft, char **dst, size_t *dstleft) { return f_iconv(cd, (T)src, srcleft, dst, dstleft); } /** * Encapsulate iconv safely and avoid iconv_adaptor complexity in client code. */ class Converter { ConverterHandle iconvh; void OpenHandle(const char *fullDestination, const char *charSetSource) { iconvh = g_iconv_open(fullDestination, charSetSource); } bool Succeeded() const { return iconvh != iconvhBad; } public: Converter() { iconvh = iconvhBad; } Converter(const char *charSetDestination, const char *charSetSource, bool transliterations) { iconvh = iconvhBad; Open(charSetDestination, charSetSource, transliterations); } ~Converter() { Close(); } operator bool() const { return Succeeded(); } void Open(const char *charSetDestination, const char *charSetSource, bool transliterations=true) { Close(); if (*charSetSource) { // Try allowing approximate transliterations if (transliterations) { char fullDest[200]; strcpy(fullDest, charSetDestination); strcat(fullDest, "//TRANSLIT"); OpenHandle(fullDest, charSetSource); } if (!Succeeded()) { // Transliterations failed so try basic name OpenHandle(charSetDestination, charSetSource); } } } void Close() { if (Succeeded()) { g_iconv_close(iconvh); iconvh = iconvhBad; } } size_t Convert(char** src, size_t *srcleft, char **dst, size_t *dstleft) const { if (!Succeeded()) { return (size_t)(-1); } else { return iconv_adaptor(g_iconv, iconvh, src, srcleft, dst, dstleft); } } }; |
Added gtk/PlatGTK.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 |
// Scintilla source code edit control // PlatGTK.cxx - implementation of platform facilities on GTK+/Linux // Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <string.h> #include <stdio.h> #include <stdlib.h> #include <stddef.h> #include <math.h> #include <vector> #include <map> #include <glib.h> #include <gmodule.h> #include <gdk/gdk.h> #include <gtk/gtk.h> #include <gdk/gdkkeysyms.h> #include "Platform.h" #include "Scintilla.h" #include "ScintillaWidget.h" #include "UniConversion.h" #include "XPM.h" #if defined(__clang__) // Clang 3.0 incorrectly displays sentinel warnings. Fixed by clang 3.1. #pragma GCC diagnostic ignored "-Wsentinel" #endif /* GLIB must be compiled with thread support, otherwise we will bail on trying to use locks, and that could lead to problems for someone. `glib-config --libs gthread` needs to be used to get the glib libraries for linking, otherwise g_thread_init will fail */ #define USE_LOCK defined(G_THREADS_ENABLED) && !defined(G_THREADS_IMPL_NONE) #include "Converter.h" #if GTK_CHECK_VERSION(2,20,0) #define IS_WIDGET_FOCUSSED(w) (gtk_widget_has_focus(GTK_WIDGET(w))) #else #define IS_WIDGET_FOCUSSED(w) (GTK_WIDGET_HAS_FOCUS(w)) #endif // The Pango version guard for pango_units_from_double and pango_units_to_double // is more complex than simply implementing these here. static int pangoUnitsFromDouble(double d) { return static_cast<int>(d * PANGO_SCALE + 0.5); } static double doubleFromPangoUnits(int pu) { return static_cast<double>(pu) / PANGO_SCALE; } static cairo_surface_t *CreateSimilarSurface(GdkWindow *window, cairo_content_t content, int width, int height) { #if GTK_CHECK_VERSION(2,22,0) return gdk_window_create_similar_surface(window, content, width, height); #else cairo_surface_t *window_surface, *surface; g_return_val_if_fail(GDK_IS_WINDOW(window), NULL); window_surface = GDK_DRAWABLE_GET_CLASS(window)->ref_cairo_surface(window); surface = cairo_surface_create_similar(window_surface, content, width, height); cairo_surface_destroy(window_surface); return surface; #endif } static GdkWindow *WindowFromWidget(GtkWidget *w) { #if GTK_CHECK_VERSION(3,0,0) return gtk_widget_get_window(w); #else return w->window; #endif } #ifdef _MSC_VER // Ignore unreferenced local functions in GTK+ headers #pragma warning(disable: 4505) #endif #ifdef SCI_NAMESPACE using namespace Scintilla; #endif enum encodingType { singleByte, UTF8, dbcs}; struct LOGFONT { int size; int weight; bool italic; int characterSet; char faceName[300]; }; #if USE_LOCK static GMutex *fontMutex = NULL; static void InitializeGLIBThreads() { #if !GLIB_CHECK_VERSION(2,31,0) if (!g_thread_supported()) { g_thread_init(NULL); } #endif } #endif static void FontMutexAllocate() { #if USE_LOCK if (!fontMutex) { InitializeGLIBThreads(); #if GLIB_CHECK_VERSION(2,31,0) fontMutex = g_new(GMutex, 1); g_mutex_init(fontMutex); #else fontMutex = g_mutex_new(); #endif } #endif } static void FontMutexFree() { #if USE_LOCK if (fontMutex) { #if GLIB_CHECK_VERSION(2,31,0) g_mutex_clear(fontMutex); g_free(fontMutex); #else g_mutex_free(fontMutex); #endif fontMutex = NULL; } #endif } static void FontMutexLock() { #if USE_LOCK g_mutex_lock(fontMutex); #endif } static void FontMutexUnlock() { #if USE_LOCK if (fontMutex) { g_mutex_unlock(fontMutex); } #endif } // Holds a PangoFontDescription*. class FontHandle { XYPOSITION width[128]; encodingType et; public: int ascent; PangoFontDescription *pfd; int characterSet; FontHandle() : et(singleByte), ascent(0), pfd(0), characterSet(-1) { ResetWidths(et); } FontHandle(PangoFontDescription *pfd_, int characterSet_) { et = singleByte; ascent = 0; pfd = pfd_; characterSet = characterSet_; ResetWidths(et); } ~FontHandle() { if (pfd) pango_font_description_free(pfd); pfd = 0; } void ResetWidths(encodingType et_) { et = et_; for (int i=0; i<=127; i++) { width[i] = 0; } } XYPOSITION CharWidth(unsigned char ch, encodingType et_) { XYPOSITION w = 0; FontMutexLock(); if ((ch <= 127) && (et == et_)) { w = width[ch]; } FontMutexUnlock(); return w; } void SetCharWidth(unsigned char ch, XYPOSITION w, encodingType et_) { if (ch <= 127) { FontMutexLock(); if (et != et_) { ResetWidths(et_); } width[ch] = w; FontMutexUnlock(); } } }; // X has a 16 bit coordinate space, so stop drawing here to avoid wrapping static const int maxCoordinate = 32000; static FontHandle *PFont(Font &f) { return reinterpret_cast<FontHandle *>(f.GetID()); } static GtkWidget *PWidget(WindowID wid) { return reinterpret_cast<GtkWidget *>(wid); } Point Point::FromLong(long lpoint) { return Point( Platform::LowShortFromLong(lpoint), Platform::HighShortFromLong(lpoint)); } static void SetLogFont(LOGFONT &lf, const char *faceName, int characterSet, float size, int weight, bool italic) { memset(&lf, 0, sizeof(lf)); lf.size = size; lf.weight = weight; lf.italic = italic; lf.characterSet = characterSet; strncpy(lf.faceName, faceName, sizeof(lf.faceName) - 1); } /** * Create a hash from the parameters for a font to allow easy checking for identity. * If one font is the same as another, its hash will be the same, but if the hash is the * same then they may still be different. */ static int HashFont(const FontParameters &fp) { return static_cast<int>(fp.size+0.5) ^ (fp.characterSet << 10) ^ ((fp.weight / 100) << 12) ^ (fp.italic ? 0x20000000 : 0) ^ fp.faceName[0]; } class FontCached : Font { FontCached *next; int usage; LOGFONT lf; int hash; FontCached(const FontParameters &fp); ~FontCached() {} bool SameAs(const FontParameters &fp); virtual void Release(); static FontID CreateNewFont(const FontParameters &fp); static FontCached *first; public: static FontID FindOrCreate(const FontParameters &fp); static void ReleaseId(FontID fid_); }; FontCached *FontCached::first = 0; FontCached::FontCached(const FontParameters &fp) : next(0), usage(0), hash(0) { ::SetLogFont(lf, fp.faceName, fp.characterSet, fp.size, fp.weight, fp.italic); hash = HashFont(fp); fid = CreateNewFont(fp); usage = 1; } bool FontCached::SameAs(const FontParameters &fp) { return lf.size == fp.size && lf.weight == fp.weight && lf.italic == fp.italic && lf.characterSet == fp.characterSet && 0 == strcmp(lf.faceName, fp.faceName); } void FontCached::Release() { if (fid) delete PFont(*this); fid = 0; } FontID FontCached::FindOrCreate(const FontParameters &fp) { FontID ret = 0; FontMutexLock(); int hashFind = HashFont(fp); for (FontCached *cur = first; cur; cur = cur->next) { if ((cur->hash == hashFind) && cur->SameAs(fp)) { cur->usage++; ret = cur->fid; } } if (ret == 0) { FontCached *fc = new FontCached(fp); if (fc) { fc->next = first; first = fc; ret = fc->fid; } } FontMutexUnlock(); return ret; } void FontCached::ReleaseId(FontID fid_) { FontMutexLock(); FontCached **pcur = &first; for (FontCached *cur = first; cur; cur = cur->next) { if (cur->fid == fid_) { cur->usage--; if (cur->usage == 0) { *pcur = cur->next; cur->Release(); cur->next = 0; delete cur; } break; } pcur = &cur->next; } FontMutexUnlock(); } FontID FontCached::CreateNewFont(const FontParameters &fp) { PangoFontDescription *pfd = pango_font_description_new(); if (pfd) { pango_font_description_set_family(pfd, (fp.faceName[0] == '!') ? fp.faceName+1 : fp.faceName); pango_font_description_set_size(pfd, pangoUnitsFromDouble(fp.size)); pango_font_description_set_weight(pfd, static_cast<PangoWeight>(fp.weight)); pango_font_description_set_style(pfd, fp.italic ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL); return new FontHandle(pfd, fp.characterSet); } return new FontHandle(); } Font::Font() : fid(0) {} Font::~Font() {} void Font::Create(const FontParameters &fp) { Release(); fid = FontCached::FindOrCreate(fp); } void Font::Release() { if (fid) FontCached::ReleaseId(fid); fid = 0; } // Required on OS X #ifdef SCI_NAMESPACE namespace Scintilla { #endif // SurfaceID is a cairo_t* class SurfaceImpl : public Surface { encodingType et; cairo_t *context; cairo_surface_t *psurf; int x; int y; bool inited; bool createdGC; PangoContext *pcontext; PangoLayout *layout; Converter conv; int characterSet; void SetConverter(int characterSet_); public: SurfaceImpl(); virtual ~SurfaceImpl(); void Init(WindowID wid); void Init(SurfaceID sid, WindowID wid); void InitPixMap(int width, int height, Surface *surface_, WindowID wid); void Release(); bool Initialised(); void PenColour(ColourDesired fore); int LogPixelsY(); int DeviceHeightFont(int points); void MoveTo(int x_, int y_); void LineTo(int x_, int y_); void Polygon(Point *pts, int npts, ColourDesired fore, ColourDesired back); void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back); void FillRectangle(PRectangle rc, ColourDesired back); void FillRectangle(PRectangle rc, Surface &surfacePattern); void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back); void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, ColourDesired outline, int alphaOutline, int flags); void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage); void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back); void Copy(PRectangle rc, Point from, Surface &surfaceSource); void DrawTextBase(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore); void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back); void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back); void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore); void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions); XYPOSITION WidthText(Font &font_, const char *s, int len); XYPOSITION WidthChar(Font &font_, char ch); XYPOSITION Ascent(Font &font_); XYPOSITION Descent(Font &font_); XYPOSITION InternalLeading(Font &font_); XYPOSITION ExternalLeading(Font &font_); XYPOSITION Height(Font &font_); XYPOSITION AverageCharWidth(Font &font_); void SetClip(PRectangle rc); void FlushCachedState(); void SetUnicodeMode(bool unicodeMode_); void SetDBCSMode(int codePage); }; #ifdef SCI_NAMESPACE } #endif const char *CharacterSetID(int characterSet) { switch (characterSet) { case SC_CHARSET_ANSI: return ""; case SC_CHARSET_DEFAULT: return "ISO-8859-1"; case SC_CHARSET_BALTIC: return "ISO-8859-13"; case SC_CHARSET_CHINESEBIG5: return "BIG-5"; case SC_CHARSET_EASTEUROPE: return "ISO-8859-2"; case SC_CHARSET_GB2312: return "CP936"; case SC_CHARSET_GREEK: return "ISO-8859-7"; case SC_CHARSET_HANGUL: return "CP949"; case SC_CHARSET_MAC: return "MACINTOSH"; case SC_CHARSET_OEM: return "ASCII"; case SC_CHARSET_RUSSIAN: return "KOI8-R"; case SC_CHARSET_CYRILLIC: return "CP1251"; case SC_CHARSET_SHIFTJIS: return "SHIFT-JIS"; case SC_CHARSET_SYMBOL: return ""; case SC_CHARSET_TURKISH: return "ISO-8859-9"; case SC_CHARSET_JOHAB: return "CP1361"; case SC_CHARSET_HEBREW: return "ISO-8859-8"; case SC_CHARSET_ARABIC: return "ISO-8859-6"; case SC_CHARSET_VIETNAMESE: return ""; case SC_CHARSET_THAI: return "ISO-8859-11"; case SC_CHARSET_8859_15: return "ISO-8859-15"; default: return ""; } } void SurfaceImpl::SetConverter(int characterSet_) { if (characterSet != characterSet_) { characterSet = characterSet_; conv.Open("UTF-8", CharacterSetID(characterSet), false); } } SurfaceImpl::SurfaceImpl() : et(singleByte), context(0), psurf(0), x(0), y(0), inited(false), createdGC(false) , pcontext(0), layout(0), characterSet(-1) { } SurfaceImpl::~SurfaceImpl() { Release(); } void SurfaceImpl::Release() { et = singleByte; if (createdGC) { createdGC = false; cairo_destroy(context); } context = 0; if (psurf) cairo_surface_destroy(psurf); psurf = 0; if (layout) g_object_unref(layout); layout = 0; if (pcontext) g_object_unref(pcontext); pcontext = 0; conv.Close(); characterSet = -1; x = 0; y = 0; inited = false; createdGC = false; } bool SurfaceImpl::Initialised() { return inited; } void SurfaceImpl::Init(WindowID wid) { Release(); PLATFORM_ASSERT(wid); #if GTK_CHECK_VERSION(3,0,0) GdkWindow *drawable_ = gtk_widget_get_window(PWidget(wid)); #else GdkDrawable *drawable_ = GDK_DRAWABLE(PWidget(wid)->window); #endif if (drawable_) { context = gdk_cairo_create(drawable_); PLATFORM_ASSERT(context); } else { // Shouldn't happen with valid window but may when calls made before // window completely allocated and mapped. psurf = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 1, 1); context = cairo_create(psurf); } createdGC = true; pcontext = gtk_widget_create_pango_context(PWidget(wid)); PLATFORM_ASSERT(pcontext); layout = pango_layout_new(pcontext); PLATFORM_ASSERT(layout); inited = true; } void SurfaceImpl::Init(SurfaceID sid, WindowID wid) { PLATFORM_ASSERT(sid); Release(); PLATFORM_ASSERT(wid); context = cairo_reference(reinterpret_cast<cairo_t *>(sid)); pcontext = gtk_widget_create_pango_context(PWidget(wid)); // update the Pango context in case sid isn't the widget's surface pango_cairo_update_context(context, pcontext); layout = pango_layout_new(pcontext); cairo_set_line_width(context, 1); createdGC = true; inited = true; } void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID wid) { PLATFORM_ASSERT(surface_); Release(); SurfaceImpl *surfImpl = static_cast<SurfaceImpl *>(surface_); PLATFORM_ASSERT(wid); context = cairo_reference(surfImpl->context); pcontext = gtk_widget_create_pango_context(PWidget(wid)); // update the Pango context in case surface_ isn't the widget's surface pango_cairo_update_context(context, pcontext); PLATFORM_ASSERT(pcontext); layout = pango_layout_new(pcontext); PLATFORM_ASSERT(layout); if (height > 0 && width > 0) psurf = CreateSimilarSurface( WindowFromWidget(PWidget(wid)), CAIRO_CONTENT_COLOR_ALPHA, width, height); cairo_destroy(context); context = cairo_create(psurf); cairo_rectangle(context, 0, 0, width, height); cairo_set_source_rgb(context, 1.0, 0, 0); cairo_fill(context); // This produces sharp drawing more similar to GDK: //cairo_set_antialias(context, CAIRO_ANTIALIAS_NONE); cairo_set_line_width(context, 1); createdGC = true; inited = true; } void SurfaceImpl::PenColour(ColourDesired fore) { if (context) { ColourDesired cdFore(fore.AsLong()); cairo_set_source_rgb(context, cdFore.GetRed() / 255.0, cdFore.GetGreen() / 255.0, cdFore.GetBlue() / 255.0); } } int SurfaceImpl::LogPixelsY() { return 72; } int SurfaceImpl::DeviceHeightFont(int points) { int logPix = LogPixelsY(); return (points * logPix + logPix / 2) / 72; } void SurfaceImpl::MoveTo(int x_, int y_) { x = x_; y = y_; } static int Delta(int difference) { if (difference < 0) return -1; else if (difference > 0) return 1; else return 0; } void SurfaceImpl::LineTo(int x_, int y_) { // cairo_line_to draws the end position, unlike Win32 or GDK with GDK_CAP_NOT_LAST. // For simple cases, move back one pixel from end. if (context) { int xDiff = x_ - x; int xDelta = Delta(xDiff); int yDiff = y_ - y; int yDelta = Delta(yDiff); if ((xDiff == 0) || (yDiff == 0)) { // Horizontal or vertical lines can be more precisely drawn as a filled rectangle int xEnd = x_ - xDelta; int left = Platform::Minimum(x, xEnd); int width = abs(x - xEnd) + 1; int yEnd = y_ - yDelta; int top = Platform::Minimum(y, yEnd); int height = abs(y - yEnd) + 1; cairo_rectangle(context, left, top, width, height); cairo_fill(context); } else if ((abs(xDiff) == abs(yDiff))) { // 45 degree slope cairo_move_to(context, x + 0.5, y + 0.5); cairo_line_to(context, x_ + 0.5 - xDelta, y_ + 0.5 - yDelta); } else { // Line has a different slope so difficult to avoid last pixel cairo_move_to(context, x + 0.5, y + 0.5); cairo_line_to(context, x_ + 0.5, y_ + 0.5); } cairo_stroke(context); } x = x_; y = y_; } void SurfaceImpl::Polygon(Point *pts, int npts, ColourDesired fore, ColourDesired back) { PenColour(back); cairo_move_to(context, pts[0].x + 0.5, pts[0].y + 0.5); for (int i = 1;i < npts;i++) { cairo_line_to(context, pts[i].x + 0.5, pts[i].y + 0.5); } cairo_close_path(context); cairo_fill_preserve(context); PenColour(fore); cairo_stroke(context); } void SurfaceImpl::RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) { if (context) { cairo_rectangle(context, rc.left + 0.5, rc.top + 0.5, rc.right - rc.left - 1, rc.bottom - rc.top - 1); PenColour(back); cairo_fill_preserve(context); PenColour(fore); cairo_stroke(context); } } void SurfaceImpl::FillRectangle(PRectangle rc, ColourDesired back) { PenColour(back); if (context && (rc.left < maxCoordinate)) { // Protect against out of range rc.left = lround(rc.left); rc.right = lround(rc.right); cairo_rectangle(context, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); cairo_fill(context); } } void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) { SurfaceImpl &surfi = static_cast<SurfaceImpl &>(surfacePattern); bool canDraw = surfi.psurf; if (canDraw) { // Tile pattern over rectangle // Currently assumes 8x8 pattern int widthPat = 8; int heightPat = 8; for (int xTile = rc.left; xTile < rc.right; xTile += widthPat) { int widthx = (xTile + widthPat > rc.right) ? rc.right - xTile : widthPat; for (int yTile = rc.top; yTile < rc.bottom; yTile += heightPat) { int heighty = (yTile + heightPat > rc.bottom) ? rc.bottom - yTile : heightPat; cairo_set_source_surface(context, surfi.psurf, xTile, yTile); cairo_rectangle(context, xTile, yTile, widthx, heighty); cairo_fill(context); } } } else { // Something is wrong so try to show anyway // Shows up black because colour not allocated FillRectangle(rc, ColourDesired(0)); } } void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back) { if (((rc.right - rc.left) > 4) && ((rc.bottom - rc.top) > 4)) { // Approximate a round rect with some cut off corners Point pts[] = { Point(rc.left + 2, rc.top), Point(rc.right - 2, rc.top), Point(rc.right, rc.top + 2), Point(rc.right, rc.bottom - 2), Point(rc.right - 2, rc.bottom), Point(rc.left + 2, rc.bottom), Point(rc.left, rc.bottom - 2), Point(rc.left, rc.top + 2), }; Polygon(pts, sizeof(pts) / sizeof(pts[0]), fore, back); } else { RectangleDraw(rc, fore, back); } } static void PathRoundRectangle(cairo_t *context, double left, double top, double width, double height, int radius) { double degrees = M_PI / 180.0; #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 2, 0) cairo_new_sub_path(context); #else // First arc is in the top-right corner and starts from a point on the top line cairo_move_to(context, left + width - radius, top); #endif cairo_arc(context, left + width - radius, top + radius, radius, -90 * degrees, 0 * degrees); cairo_arc(context, left + width - radius, top + height - radius, radius, 0 * degrees, 90 * degrees); cairo_arc(context, left + radius, top + height - radius, radius, 90 * degrees, 180 * degrees); cairo_arc(context, left + radius, top + radius, radius, 180 * degrees, 270 * degrees); cairo_close_path(context); } void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, ColourDesired outline, int alphaOutline, int flags) { if (context && rc.Width() > 0) { ColourDesired cdFill(fill.AsLong()); cairo_set_source_rgba(context, cdFill.GetRed() / 255.0, cdFill.GetGreen() / 255.0, cdFill.GetBlue() / 255.0, alphaFill / 255.0); if (cornerSize > 0) PathRoundRectangle(context, rc.left + 1.0, rc.top + 1.0, rc.right - rc.left - 2.0, rc.bottom - rc.top - 2.0, cornerSize); else cairo_rectangle(context, rc.left + 1.0, rc.top + 1.0, rc.right - rc.left - 2.0, rc.bottom - rc.top - 2.0); cairo_fill(context); ColourDesired cdOutline(outline.AsLong()); cairo_set_source_rgba(context, cdOutline.GetRed() / 255.0, cdOutline.GetGreen() / 255.0, cdOutline.GetBlue() / 255.0, alphaOutline / 255.0); if (cornerSize > 0) PathRoundRectangle(context, rc.left + 0.5, rc.top + 0.5, rc.right - rc.left - 1, rc.bottom - rc.top - 1, cornerSize); else cairo_rectangle(context, rc.left + 0.5, rc.top + 0.5, rc.right - rc.left - 1, rc.bottom - rc.top - 1); cairo_stroke(context); } } void SurfaceImpl::DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) { if (rc.Width() > width) rc.left += (rc.Width() - width) / 2; rc.right = rc.left + width; if (rc.Height() > height) rc.top += (rc.Height() - height) / 2; rc.bottom = rc.top + height; #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,6,0) int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); #else int stride = width * 4; #endif int ucs = stride * height; std::vector<unsigned char> image(ucs); for (int y=0; y<height; y++) { for (int x=0; x<width; x++) { unsigned char *pixel = &image[0] + y*stride + x * 4; unsigned char alpha = pixelsImage[3]; pixel[2] = (*pixelsImage++) * alpha / 255; pixel[1] = (*pixelsImage++) * alpha / 255; pixel[0] = (*pixelsImage++) * alpha / 255; pixel[3] = *pixelsImage++; } } cairo_surface_t *psurf = cairo_image_surface_create_for_data(&image[0], CAIRO_FORMAT_ARGB32, width, height, stride); cairo_set_source_surface(context, psurf, rc.left, rc.top); cairo_rectangle(context, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top); cairo_fill(context); cairo_surface_destroy(psurf); } void SurfaceImpl::Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) { PenColour(back); cairo_arc(context, (rc.left + rc.right) / 2 + 0.5, (rc.top + rc.bottom) / 2 + 0.5, Platform::Minimum(rc.Width(), rc.Height()) / 2, 0, 2*M_PI); cairo_fill_preserve(context); PenColour(fore); cairo_stroke(context); } void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) { SurfaceImpl &surfi = static_cast<SurfaceImpl &>(surfaceSource); bool canDraw = surfi.psurf; if (canDraw) { cairo_set_source_surface(context, surfi.psurf, rc.left - from.x, rc.top - from.y); cairo_rectangle(context, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top); cairo_fill(context); } } char *UTF8FromLatin1(const char *s, int &len) { char *utfForm = new char[len*2+1]; size_t lenU = 0; for (int i=0;i<len;i++) { unsigned int uch = static_cast<unsigned char>(s[i]); if (uch < 0x80) { utfForm[lenU++] = uch; } else { utfForm[lenU++] = static_cast<char>(0xC0 | (uch >> 6)); utfForm[lenU++] = static_cast<char>(0x80 | (uch & 0x3f)); } } utfForm[lenU] = '\0'; len = lenU; return utfForm; } static char *UTF8FromIconv(const Converter &conv, const char *s, int &len) { if (conv) { char *utfForm = new char[len*3+1]; char *pin = const_cast<char *>(s); size_t inLeft = len; char *pout = utfForm; size_t outLeft = len*3+1; size_t conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft); if (conversions != ((size_t)(-1))) { *pout = '\0'; len = pout - utfForm; return utfForm; } delete []utfForm; } return 0; } // Work out how many bytes are in a character by trying to convert using iconv, // returning the first length that succeeds. static size_t MultiByteLenFromIconv(const Converter &conv, const char *s, size_t len) { for (size_t lenMB=1; (lenMB<4) && (lenMB <= len); lenMB++) { char wcForm[2]; char *pin = const_cast<char *>(s); size_t inLeft = lenMB; char *pout = wcForm; size_t outLeft = 2; size_t conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft); if (conversions != ((size_t)(-1))) { return lenMB; } } return 1; } static size_t UTF8CharLength(const char *s) { const unsigned char *us = reinterpret_cast<const unsigned char *>(s); unsigned char ch = *us; if (ch < 0x80) { return 1; } else if (ch < 0x80 + 0x40 + 0x20) { return 2; } else { return 3; } } void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore) { PenColour(fore); if (context) { XYPOSITION xText = rc.left; if (PFont(font_)->pfd) { char *utfForm = 0; if (et == UTF8) { pango_layout_set_text(layout, s, len); } else { if (!utfForm) { SetConverter(PFont(font_)->characterSet); utfForm = UTF8FromIconv(conv, s, len); } if (!utfForm) { // iconv failed so treat as Latin1 utfForm = UTF8FromLatin1(s, len); } pango_layout_set_text(layout, utfForm, len); } pango_layout_set_font_description(layout, PFont(font_)->pfd); pango_cairo_update_layout(context, layout); #ifdef PANGO_VERSION PangoLayoutLine *pll = pango_layout_get_line_readonly(layout,0); #else PangoLayoutLine *pll = pango_layout_get_line(layout,0); #endif cairo_move_to(context, xText, ybase); pango_cairo_show_layout_line(context, pll); delete []utfForm; } } } void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) { FillRectangle(rc, back); DrawTextBase(rc, font_, ybase, s, len, fore); } // On GTK+, exactly same as DrawTextNoClip void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) { FillRectangle(rc, back); DrawTextBase(rc, font_, ybase, s, len, fore); } void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore) { // Avoid drawing spaces in transparent mode for (int i=0;i<len;i++) { if (s[i] != ' ') { DrawTextBase(rc, font_, ybase, s, len, fore); return; } } } class ClusterIterator { PangoLayoutIter *iter; PangoRectangle pos; int lenPositions; public: bool finished; XYPOSITION positionStart; XYPOSITION position; XYPOSITION distance; int curIndex; ClusterIterator(PangoLayout *layout, int len) : lenPositions(len), finished(false), positionStart(0), position(0), distance(0), curIndex(0) { iter = pango_layout_get_iter(layout); pango_layout_iter_get_cluster_extents(iter, NULL, &pos); } ~ClusterIterator() { pango_layout_iter_free(iter); } void Next() { positionStart = position; if (pango_layout_iter_next_cluster(iter)) { pango_layout_iter_get_cluster_extents(iter, NULL, &pos); position = doubleFromPangoUnits(pos.x); curIndex = pango_layout_iter_get_index(iter); } else { finished = true; position = doubleFromPangoUnits(pos.x + pos.width); curIndex = lenPositions; } distance = position - positionStart; } }; void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) { if (font_.GetID()) { const int lenPositions = len; if (PFont(font_)->pfd) { if (len == 1) { int width = PFont(font_)->CharWidth(*s, et); if (width) { positions[0] = width; return; } } pango_layout_set_font_description(layout, PFont(font_)->pfd); if (et == UTF8) { // Simple and direct as UTF-8 is native Pango encoding int i = 0; pango_layout_set_text(layout, s, len); ClusterIterator iti(layout, lenPositions); while (!iti.finished) { iti.Next(); int places = iti.curIndex - i; while (i < iti.curIndex) { // Evenly distribute space among bytes of this cluster. // Would be better to find number of characters and then // divide evenly between characters with each byte of a character // being at the same position. positions[i] = iti.position - (iti.curIndex - 1 - i) * iti.distance / places; i++; } } PLATFORM_ASSERT(i == lenPositions); } else { int positionsCalculated = 0; if (et == dbcs) { SetConverter(PFont(font_)->characterSet); char *utfForm = UTF8FromIconv(conv, s, len); if (utfForm) { // Convert to UTF-8 so can ask Pango for widths, then // Loop through UTF-8 and DBCS forms, taking account of different // character byte lengths. Converter convMeasure("UCS-2", CharacterSetID(characterSet), false); pango_layout_set_text(layout, utfForm, strlen(utfForm)); int i = 0; int clusterStart = 0; ClusterIterator iti(layout, strlen(utfForm)); while (!iti.finished) { iti.Next(); int clusterEnd = iti.curIndex; int places = g_utf8_strlen(utfForm + clusterStart, clusterEnd - clusterStart); int place = 1; while (clusterStart < clusterEnd) { size_t lenChar = MultiByteLenFromIconv(convMeasure, s+i, len-i); while (lenChar--) { positions[i++] = iti.position - (places - place) * iti.distance / places; positionsCalculated++; } clusterStart += UTF8CharLength(utfForm+clusterStart); place++; } } delete []utfForm; PLATFORM_ASSERT(i == lenPositions); } } if (positionsCalculated < 1 ) { // Either Latin1 or DBCS conversion failed so treat as Latin1. SetConverter(PFont(font_)->characterSet); char *utfForm = UTF8FromIconv(conv, s, len); if (!utfForm) { utfForm = UTF8FromLatin1(s, len); } pango_layout_set_text(layout, utfForm, len); int i = 0; int clusterStart = 0; // Each Latin1 input character may take 1 or 2 bytes in UTF-8 // and groups of up to 3 may be represented as ligatures. ClusterIterator iti(layout, strlen(utfForm)); while (!iti.finished) { iti.Next(); int clusterEnd = iti.curIndex; int ligatureLength = g_utf8_strlen(utfForm + clusterStart, clusterEnd - clusterStart); PLATFORM_ASSERT(ligatureLength > 0 && ligatureLength <= 3); for (int charInLig=0; charInLig<ligatureLength; charInLig++) { positions[i++] = iti.position - (ligatureLength - 1 - charInLig) * iti.distance / ligatureLength; } clusterStart = clusterEnd; } delete []utfForm; PLATFORM_ASSERT(i == lenPositions); } } if (len == 1) { PFont(font_)->SetCharWidth(*s, positions[0], et); } return; } } else { // No font so return an ascending range of values for (int i = 0; i < len; i++) { positions[i] = i + 1; } } } XYPOSITION SurfaceImpl::WidthText(Font &font_, const char *s, int len) { if (font_.GetID()) { if (PFont(font_)->pfd) { char *utfForm = 0; pango_layout_set_font_description(layout, PFont(font_)->pfd); PangoRectangle pos; if (et == UTF8) { pango_layout_set_text(layout, s, len); } else { if (!utfForm) { // use iconv SetConverter(PFont(font_)->characterSet); utfForm = UTF8FromIconv(conv, s, len); } if (!utfForm) { // iconv failed so treat as Latin1 utfForm = UTF8FromLatin1(s, len); } pango_layout_set_text(layout, utfForm, len); } #ifdef PANGO_VERSION PangoLayoutLine *pangoLine = pango_layout_get_line_readonly(layout,0); #else PangoLayoutLine *pangoLine = pango_layout_get_line(layout,0); #endif pango_layout_line_get_extents(pangoLine, NULL, &pos); delete []utfForm; return doubleFromPangoUnits(pos.width); } return 1; } else { return 1; } } XYPOSITION SurfaceImpl::WidthChar(Font &font_, char ch) { if (font_.GetID()) { if (PFont(font_)->pfd) { return WidthText(font_, &ch, 1); } return 1; } else { return 1; } } // Ascent and descent determined by Pango font metrics. XYPOSITION SurfaceImpl::Ascent(Font &font_) { if (!(font_.GetID())) return 1; FontMutexLock(); int ascent = PFont(font_)->ascent; if ((ascent == 0) && (PFont(font_)->pfd)) { PangoFontMetrics *metrics = pango_context_get_metrics(pcontext, PFont(font_)->pfd, pango_context_get_language(pcontext)); PFont(font_)->ascent = doubleFromPangoUnits(pango_font_metrics_get_ascent(metrics)); pango_font_metrics_unref(metrics); ascent = PFont(font_)->ascent; } if (ascent == 0) { ascent = 1; } FontMutexUnlock(); return ascent; } XYPOSITION SurfaceImpl::Descent(Font &font_) { if (!(font_.GetID())) return 1; if (PFont(font_)->pfd) { PangoFontMetrics *metrics = pango_context_get_metrics(pcontext, PFont(font_)->pfd, pango_context_get_language(pcontext)); int descent = doubleFromPangoUnits(pango_font_metrics_get_descent(metrics)); pango_font_metrics_unref(metrics); return descent; } return 0; } XYPOSITION SurfaceImpl::InternalLeading(Font &) { return 0; } XYPOSITION SurfaceImpl::ExternalLeading(Font &) { return 0; } XYPOSITION SurfaceImpl::Height(Font &font_) { return Ascent(font_) + Descent(font_); } XYPOSITION SurfaceImpl::AverageCharWidth(Font &font_) { return WidthChar(font_, 'n'); } void SurfaceImpl::SetClip(PRectangle rc) { cairo_rectangle(context, rc.left, rc.top, rc.right, rc.bottom); cairo_clip(context); } void SurfaceImpl::FlushCachedState() {} void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) { if (unicodeMode_) et = UTF8; } void SurfaceImpl::SetDBCSMode(int codePage) { if (codePage && (codePage != SC_CP_UTF8)) et = dbcs; } Surface *Surface::Allocate(int) { return new SurfaceImpl(); } Window::~Window() {} void Window::Destroy() { if (wid) gtk_widget_destroy(GTK_WIDGET(wid)); wid = 0; } bool Window::HasFocus() { return IS_WIDGET_FOCUSSED(wid); } PRectangle Window::GetPosition() { // Before any size allocated pretend its 1000 wide so not scrolled PRectangle rc(0, 0, 1000, 1000); if (wid) { GtkAllocation allocation; #if GTK_CHECK_VERSION(3,0,0) gtk_widget_get_allocation(PWidget(wid), &allocation); #else allocation = PWidget(wid)->allocation; #endif rc.left = allocation.x; rc.top = allocation.y; if (allocation.width > 20) { rc.right = rc.left + allocation.width; rc.bottom = rc.top + allocation.height; } } return rc; } void Window::SetPosition(PRectangle rc) { GtkAllocation alloc; alloc.x = rc.left; alloc.y = rc.top; alloc.width = rc.Width(); alloc.height = rc.Height(); gtk_widget_size_allocate(PWidget(wid), &alloc); } void Window::SetPositionRelative(PRectangle rc, Window relativeTo) { int ox = 0; int oy = 0; gdk_window_get_origin(WindowFromWidget(PWidget(relativeTo.wid)), &ox, &oy); ox += rc.left; if (ox < 0) ox = 0; oy += rc.top; if (oy < 0) oy = 0; /* do some corrections to fit into screen */ int sizex = rc.right - rc.left; int sizey = rc.bottom - rc.top; int screenWidth = gdk_screen_width(); int screenHeight = gdk_screen_height(); if (sizex > screenWidth) ox = 0; /* the best we can do */ else if (ox + sizex > screenWidth) ox = screenWidth - sizex; if (oy + sizey > screenHeight) oy = screenHeight - sizey; gtk_window_move(GTK_WINDOW(PWidget(wid)), ox, oy); gtk_widget_set_size_request(PWidget(wid), sizex, sizey); } PRectangle Window::GetClientPosition() { // On GTK+, the client position is the window position return GetPosition(); } void Window::Show(bool show) { if (show) gtk_widget_show(PWidget(wid)); } void Window::InvalidateAll() { if (wid) { gtk_widget_queue_draw(PWidget(wid)); } } void Window::InvalidateRectangle(PRectangle rc) { if (wid) { gtk_widget_queue_draw_area(PWidget(wid), rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); } } void Window::SetFont(Font &) { // Can not be done generically but only needed for ListBox } void Window::SetCursor(Cursor curs) { // We don't set the cursor to same value numerous times under gtk because // it stores the cursor in the window once it's set if (curs == cursorLast) return; cursorLast = curs; GdkCursor *gdkCurs; switch (curs) { case cursorText: gdkCurs = gdk_cursor_new(GDK_XTERM); break; case cursorArrow: gdkCurs = gdk_cursor_new(GDK_LEFT_PTR); break; case cursorUp: gdkCurs = gdk_cursor_new(GDK_CENTER_PTR); break; case cursorWait: gdkCurs = gdk_cursor_new(GDK_WATCH); break; case cursorHand: gdkCurs = gdk_cursor_new(GDK_HAND2); break; case cursorReverseArrow: gdkCurs = gdk_cursor_new(GDK_RIGHT_PTR); break; default: gdkCurs = gdk_cursor_new(GDK_LEFT_PTR); cursorLast = cursorArrow; break; } if (WindowFromWidget(PWidget(wid))) gdk_window_set_cursor(WindowFromWidget(PWidget(wid)), gdkCurs); #if GTK_CHECK_VERSION(3,0,0) g_object_unref(gdkCurs); #else gdk_cursor_unref(gdkCurs); #endif } void Window::SetTitle(const char *s) { gtk_window_set_title(GTK_WINDOW(wid), s); } /* Returns rectangle of monitor pt is on, both rect and pt are in Window's gdk window coordinates */ PRectangle Window::GetMonitorRect(Point pt) { gint x_offset, y_offset; gdk_window_get_origin(WindowFromWidget(PWidget(wid)), &x_offset, &y_offset); GdkScreen* screen; gint monitor_num; GdkRectangle rect; screen = gtk_widget_get_screen(PWidget(wid)); monitor_num = gdk_screen_get_monitor_at_point(screen, pt.x + x_offset, pt.y + y_offset); gdk_screen_get_monitor_geometry(screen, monitor_num, &rect); rect.x -= x_offset; rect.y -= y_offset; return PRectangle(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height); } typedef std::map<int, RGBAImage*> ImageMap; struct ListImage { const RGBAImage *rgba_data; GdkPixbuf *pixbuf; }; static void list_image_free(gpointer, gpointer value, gpointer) { ListImage *list_image = static_cast<ListImage *>(value); if (list_image->pixbuf) g_object_unref(list_image->pixbuf); g_free(list_image); } ListBox::ListBox() { } ListBox::~ListBox() { } enum { PIXBUF_COLUMN, TEXT_COLUMN, N_COLUMNS }; class ListBoxX : public ListBox { WindowID list; WindowID scroller; void *pixhash; GtkCellRenderer* pixbuf_renderer; RGBAImageSet images; int desiredVisibleRows; unsigned int maxItemCharacters; unsigned int aveCharWidth; public: CallBackAction doubleClickAction; void *doubleClickActionData; ListBoxX() : list(0), scroller(0), pixhash(NULL), pixbuf_renderer(0), desiredVisibleRows(5), maxItemCharacters(0), aveCharWidth(1), doubleClickAction(NULL), doubleClickActionData(NULL) { } virtual ~ListBoxX() { if (pixhash) { g_hash_table_foreach((GHashTable *) pixhash, list_image_free, NULL); g_hash_table_destroy((GHashTable *) pixhash); } } virtual void SetFont(Font &font); virtual void Create(Window &parent, int ctrlID, Point location_, int lineHeight_, bool unicodeMode_, int technology_); virtual void SetAverageCharWidth(int width); virtual void SetVisibleRows(int rows); virtual int GetVisibleRows() const; virtual PRectangle GetDesiredRect(); virtual int CaretFromEdge(); virtual void Clear(); virtual void Append(char *s, int type = -1); virtual int Length(); virtual void Select(int n); virtual int GetSelection(); virtual int Find(const char *prefix); virtual void GetValue(int n, char *value, int len); void RegisterRGBA(int type, RGBAImage *image); virtual void RegisterImage(int type, const char *xpm_data); virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage); virtual void ClearRegisteredImages(); virtual void SetDoubleClickAction(CallBackAction action, void *data) { doubleClickAction = action; doubleClickActionData = data; } virtual void SetList(const char *listText, char separator, char typesep); }; ListBox *ListBox::Allocate() { ListBoxX *lb = new ListBoxX(); return lb; } static gboolean ButtonPress(GtkWidget *, GdkEventButton* ev, gpointer p) { try { ListBoxX* lb = reinterpret_cast<ListBoxX*>(p); if (ev->type == GDK_2BUTTON_PRESS && lb->doubleClickAction != NULL) { lb->doubleClickAction(lb->doubleClickActionData); return TRUE; } } catch (...) { // No pointer back to Scintilla to save status } return FALSE; } /* Change the active color to the selected color so the listbox uses the color scheme that it would use if it had the focus. */ static void StyleSet(GtkWidget *w, GtkStyle*, void*) { g_return_if_fail(w != NULL); /* Copy the selected color to active. Note that the modify calls will cause recursive calls to this function after the value is updated and w->style to be set to a new object */ #if GTK_CHECK_VERSION(3,0,0) GtkStyleContext *styleContext = gtk_widget_get_style_context(w); if (styleContext == NULL) return; GdkRGBA colourForeSelected; gtk_style_context_get_color(styleContext, GTK_STATE_FLAG_SELECTED, &colourForeSelected); GdkRGBA colourForeActive; gtk_style_context_get_color(styleContext, GTK_STATE_FLAG_ACTIVE, &colourForeActive); if (!gdk_rgba_equal(&colourForeSelected, &colourForeActive)) gtk_widget_override_color(w, GTK_STATE_FLAG_ACTIVE, &colourForeSelected); styleContext = gtk_widget_get_style_context(w); if (styleContext == NULL) return; GdkRGBA colourBaseSelected; gtk_style_context_get_background_color(styleContext, GTK_STATE_FLAG_SELECTED, &colourBaseSelected); GdkRGBA colourBaseActive; gtk_style_context_get_background_color(styleContext, GTK_STATE_FLAG_ACTIVE, &colourBaseActive); if (!gdk_rgba_equal(&colourBaseSelected, &colourBaseActive)) gtk_widget_override_background_color(w, GTK_STATE_FLAG_ACTIVE, &colourBaseSelected); #else GtkStyle *style = gtk_widget_get_style(w); if (style == NULL) return; if (!gdk_color_equal(&style->base[GTK_STATE_SELECTED], &style->base[GTK_STATE_ACTIVE])) gtk_widget_modify_base(w, GTK_STATE_ACTIVE, &style->base[GTK_STATE_SELECTED]); style = gtk_widget_get_style(w); if (style == NULL) return; if (!gdk_color_equal(&style->text[GTK_STATE_SELECTED], &style->text[GTK_STATE_ACTIVE])) gtk_widget_modify_text(w, GTK_STATE_ACTIVE, &style->text[GTK_STATE_SELECTED]); #endif } void ListBoxX::Create(Window &, int, Point, int, bool, int) { wid = gtk_window_new(GTK_WINDOW_POPUP); GtkWidget *frame = gtk_frame_new(NULL); gtk_widget_show(frame); gtk_container_add(GTK_CONTAINER(GetID()), frame); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT); gtk_container_set_border_width(GTK_CONTAINER(frame), 0); scroller = gtk_scrolled_window_new(NULL, NULL); gtk_container_set_border_width(GTK_CONTAINER(scroller), 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroller), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(frame), PWidget(scroller)); gtk_widget_show(PWidget(scroller)); /* Tree and its model */ GtkListStore *store = gtk_list_store_new(N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING); list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); g_signal_connect(G_OBJECT(list), "style-set", G_CALLBACK(StyleSet), NULL); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), FALSE); gtk_tree_view_set_reorderable(GTK_TREE_VIEW(list), FALSE); /* Columns */ GtkTreeViewColumn *column = gtk_tree_view_column_new(); gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_column_set_title(column, "Autocomplete"); pixbuf_renderer = gtk_cell_renderer_pixbuf_new(); gtk_cell_renderer_set_fixed_size(pixbuf_renderer, 0, -1); gtk_tree_view_column_pack_start(column, pixbuf_renderer, FALSE); gtk_tree_view_column_add_attribute(column, pixbuf_renderer, "pixbuf", PIXBUF_COLUMN); GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); gtk_cell_renderer_text_set_fixed_height_from_font(GTK_CELL_RENDERER_TEXT(renderer), 1); gtk_tree_view_column_pack_start(column, renderer, TRUE); gtk_tree_view_column_add_attribute(column, renderer, "text", TEXT_COLUMN); gtk_tree_view_append_column(GTK_TREE_VIEW(list), column); if (g_object_class_find_property(G_OBJECT_GET_CLASS(list), "fixed-height-mode")) g_object_set(G_OBJECT(list), "fixed-height-mode", TRUE, NULL); GtkWidget *wid = PWidget(list); // No code inside the G_OBJECT macro gtk_container_add(GTK_CONTAINER(PWidget(scroller)), wid); gtk_widget_show(wid); g_signal_connect(G_OBJECT(wid), "button_press_event", G_CALLBACK(ButtonPress), this); gtk_widget_realize(PWidget(wid)); } void ListBoxX::SetFont(Font &scint_font) { // Only do for Pango font as there have been crashes for GDK fonts if (Created() && PFont(scint_font)->pfd) { // Current font is Pango font #if GTK_CHECK_VERSION(3,0,0) gtk_widget_override_font(PWidget(list), PFont(scint_font)->pfd); #else gtk_widget_modify_font(PWidget(list), PFont(scint_font)->pfd); #endif } } void ListBoxX::SetAverageCharWidth(int width) { aveCharWidth = width; } void ListBoxX::SetVisibleRows(int rows) { desiredVisibleRows = rows; } int ListBoxX::GetVisibleRows() const { return desiredVisibleRows; } PRectangle ListBoxX::GetDesiredRect() { // Before any size allocated pretend its 100 wide so not scrolled PRectangle rc(0, 0, 100, 100); if (wid) { int rows = Length(); if ((rows == 0) || (rows > desiredVisibleRows)) rows = desiredVisibleRows; GtkRequisition req; #if GTK_CHECK_VERSION(3,0,0) // This, apparently unnecessary call, ensures gtk_tree_view_column_cell_get_size // returns reasonable values. gtk_widget_get_preferred_size(GTK_WIDGET(scroller), NULL, &req); #endif int height; // First calculate height of the clist for our desired visible // row count otherwise it tries to expand to the total # of rows // Get cell height int row_width=0; int row_height=0; GtkTreeViewColumn * column = gtk_tree_view_get_column(GTK_TREE_VIEW(list), 0); gtk_tree_view_column_cell_get_size(column, NULL, NULL, NULL, &row_width, &row_height); #if GTK_CHECK_VERSION(3,0,0) GtkStyleContext *styleContextList = gtk_widget_get_style_context(PWidget(list)); GtkBorder padding; gtk_style_context_get_padding(styleContextList, GTK_STATE_FLAG_NORMAL, &padding); height = (rows * row_height + padding.top + padding.bottom + 2 * (gtk_container_get_border_width(GTK_CONTAINER(PWidget(list))) + 1)); #else int ythickness = PWidget(list)->style->ythickness; height = (rows * row_height + 2 * (ythickness + GTK_CONTAINER(PWidget(list))->border_width + 1)); #endif gtk_widget_set_size_request(GTK_WIDGET(PWidget(list)), -1, height); // Get the size of the scroller because we set usize on the window #if GTK_CHECK_VERSION(3,0,0) gtk_widget_get_preferred_size(GTK_WIDGET(scroller), NULL, &req); #else gtk_widget_size_request(GTK_WIDGET(scroller), &req); #endif rc.right = req.width; rc.bottom = Platform::Maximum(height, req.height); gtk_widget_set_size_request(GTK_WIDGET(list), -1, -1); int width = maxItemCharacters; if (width < 12) width = 12; rc.right = width * (aveCharWidth + aveCharWidth / 3); if (Length() > rows) rc.right = rc.right + 16; } return rc; } int ListBoxX::CaretFromEdge() { gint renderer_width, renderer_height; gtk_cell_renderer_get_fixed_size(pixbuf_renderer, &renderer_width, &renderer_height); return 4 + renderer_width; } void ListBoxX::Clear() { GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list)); gtk_list_store_clear(GTK_LIST_STORE(model)); maxItemCharacters = 0; } static void init_pixmap(ListImage *list_image) { if (list_image->rgba_data) { // Drop any existing pixmap/bitmap as data may have changed if (list_image->pixbuf) g_object_unref(list_image->pixbuf); list_image->pixbuf = gdk_pixbuf_new_from_data(list_image->rgba_data->Pixels(), GDK_COLORSPACE_RGB, TRUE, 8, list_image->rgba_data->GetWidth(), list_image->rgba_data->GetHeight(), list_image->rgba_data->GetWidth() * 4, NULL, NULL); } } #define SPACING 5 void ListBoxX::Append(char *s, int type) { ListImage *list_image = NULL; if ((type >= 0) && pixhash) { list_image = static_cast<ListImage *>(g_hash_table_lookup((GHashTable *) pixhash , (gconstpointer) GINT_TO_POINTER(type))); } GtkTreeIter iter; GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list))); gtk_list_store_append(GTK_LIST_STORE(store), &iter); if (list_image) { if (NULL == list_image->pixbuf) init_pixmap(list_image); if (list_image->pixbuf) { gtk_list_store_set(GTK_LIST_STORE(store), &iter, PIXBUF_COLUMN, list_image->pixbuf, TEXT_COLUMN, s, -1); gint pixbuf_width = gdk_pixbuf_get_width(list_image->pixbuf); gint renderer_height, renderer_width; gtk_cell_renderer_get_fixed_size(pixbuf_renderer, &renderer_width, &renderer_height); if (pixbuf_width > renderer_width) gtk_cell_renderer_set_fixed_size(pixbuf_renderer, pixbuf_width, -1); } else { gtk_list_store_set(GTK_LIST_STORE(store), &iter, TEXT_COLUMN, s, -1); } } else { gtk_list_store_set(GTK_LIST_STORE(store), &iter, TEXT_COLUMN, s, -1); } size_t len = strlen(s); if (maxItemCharacters < len) maxItemCharacters = len; } int ListBoxX::Length() { if (wid) return gtk_tree_model_iter_n_children(gtk_tree_view_get_model (GTK_TREE_VIEW(list)), NULL); return 0; } void ListBoxX::Select(int n) { GtkTreeIter iter; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list)); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list)); if (n < 0) { gtk_tree_selection_unselect_all(selection); return; } bool valid = gtk_tree_model_iter_nth_child(model, &iter, NULL, n) != FALSE; if (valid) { gtk_tree_selection_select_iter(selection, &iter); // Move the scrollbar to show the selection. int total = Length(); #if GTK_CHECK_VERSION(3,0,0) GtkAdjustment *adj = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(list)); gfloat value = ((gfloat)n / total) * (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_lower(adj)) + gtk_adjustment_get_lower(adj) - gtk_adjustment_get_page_size(adj) / 2; #else GtkAdjustment *adj = gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(list)); gfloat value = ((gfloat)n / total) * (adj->upper - adj->lower) + adj->lower - adj->page_size / 2; #endif // Get cell height int row_width; int row_height; GtkTreeViewColumn * column = gtk_tree_view_get_column(GTK_TREE_VIEW(list), 0); gtk_tree_view_column_cell_get_size(column, NULL, NULL, NULL, &row_width, &row_height); int rows = Length(); if ((rows == 0) || (rows > desiredVisibleRows)) rows = desiredVisibleRows; if (rows & 0x1) { // Odd rows to display -- We are now in the middle. // Align it so that we don't chop off rows. value += (gfloat)row_height / 2.0; } // Clamp it. value = (value < 0)? 0 : value; #if GTK_CHECK_VERSION(3,0,0) value = (value > (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj)))? (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj)) : value; #else value = (value > (adj->upper - adj->page_size))? (adj->upper - adj->page_size) : value; #endif // Set it. gtk_adjustment_set_value(adj, value); } else { gtk_tree_selection_unselect_all(selection); } } int ListBoxX::GetSelection() { GtkTreeIter iter; GtkTreeModel *model; GtkTreeSelection *selection; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list)); if (gtk_tree_selection_get_selected(selection, &model, &iter)) { GtkTreePath *path = gtk_tree_model_get_path(model, &iter); int *indices = gtk_tree_path_get_indices(path); // Don't free indices. if (indices) return indices[0]; } return -1; } int ListBoxX::Find(const char *prefix) { GtkTreeIter iter; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list)); bool valid = gtk_tree_model_get_iter_first(model, &iter) != FALSE; int i = 0; while(valid) { gchar *s; gtk_tree_model_get(model, &iter, TEXT_COLUMN, &s, -1); if (s && (0 == strncmp(prefix, s, strlen(prefix)))) { g_free(s); return i; } g_free(s); valid = gtk_tree_model_iter_next(model, &iter) != FALSE; i++; } return -1; } void ListBoxX::GetValue(int n, char *value, int len) { char *text = NULL; GtkTreeIter iter; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list)); bool valid = gtk_tree_model_iter_nth_child(model, &iter, NULL, n) != FALSE; if (valid) { gtk_tree_model_get(model, &iter, TEXT_COLUMN, &text, -1); } if (text && len > 0) { strncpy(value, text, len); value[len - 1] = '\0'; } else { value[0] = '\0'; } g_free(text); } // g_return_if_fail causes unnecessary compiler warning in release compile. #ifdef _MSC_VER #pragma warning(disable: 4127) #endif void ListBoxX::RegisterRGBA(int type, RGBAImage *image) { images.Add(type, image); if (!pixhash) { pixhash = g_hash_table_new(g_direct_hash, g_direct_equal); } ListImage *list_image = static_cast<ListImage *>(g_hash_table_lookup((GHashTable *) pixhash, (gconstpointer) GINT_TO_POINTER(type))); if (list_image) { // Drop icon already registered if (list_image->pixbuf) g_object_unref(list_image->pixbuf); list_image->pixbuf = NULL; list_image->rgba_data = image; } else { list_image = g_new0(ListImage, 1); list_image->rgba_data = image; g_hash_table_insert((GHashTable *) pixhash, GINT_TO_POINTER(type), (gpointer) list_image); } } void ListBoxX::RegisterImage(int type, const char *xpm_data) { g_return_if_fail(xpm_data); XPM xpmImage(xpm_data); RegisterRGBA(type, new RGBAImage(xpmImage)); } void ListBoxX::RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) { RegisterRGBA(type, new RGBAImage(width, height, 1.0, pixelsImage)); } void ListBoxX::ClearRegisteredImages() { images.Clear(); } void ListBoxX::SetList(const char *listText, char separator, char typesep) { Clear(); int count = strlen(listText) + 1; char *words = new char[count]; if (words) { memcpy(words, listText, count); char *startword = words; char *numword = NULL; int i = 0; for (; words[i]; i++) { if (words[i] == separator) { words[i] = '\0'; if (numword) *numword = '\0'; Append(startword, numword?atoi(numword + 1):-1); startword = words + i + 1; numword = NULL; } else if (words[i] == typesep) { numword = words + i; } } if (startword) { if (numword) *numword = '\0'; Append(startword, numword?atoi(numword + 1):-1); } delete []words; } } Menu::Menu() : mid(0) {} void Menu::CreatePopUp() { Destroy(); mid = gtk_menu_new(); #if GLIB_CHECK_VERSION(2,10,0) g_object_ref_sink(G_OBJECT(mid)); #else g_object_ref(G_OBJECT(mid)); gtk_object_sink(GTK_OBJECT(G_OBJECT(mid))); #endif } void Menu::Destroy() { if (mid) g_object_unref(G_OBJECT(mid)); mid = 0; } static void MenuPositionFunc(GtkMenu *, gint *x, gint *y, gboolean *, gpointer userData) { sptr_t intFromPointer = reinterpret_cast<sptr_t>(userData); *x = intFromPointer & 0xffff; *y = intFromPointer >> 16; } void Menu::Show(Point pt, Window &) { int screenHeight = gdk_screen_height(); int screenWidth = gdk_screen_width(); GtkMenu *widget = reinterpret_cast<GtkMenu *>(mid); gtk_widget_show_all(GTK_WIDGET(widget)); GtkRequisition requisition; #if GTK_CHECK_VERSION(3,0,0) gtk_widget_get_preferred_size(GTK_WIDGET(widget), NULL, &requisition); #else gtk_widget_size_request(GTK_WIDGET(widget), &requisition); #endif if ((pt.x + requisition.width) > screenWidth) { pt.x = screenWidth - requisition.width; } if ((pt.y + requisition.height) > screenHeight) { pt.y = screenHeight - requisition.height; } gtk_menu_popup(widget, NULL, NULL, MenuPositionFunc, reinterpret_cast<void *>((static_cast<int>(pt.y) << 16) | static_cast<int>(pt.x)), 0, gtk_get_current_event_time()); } ElapsedTime::ElapsedTime() { GTimeVal curTime; g_get_current_time(&curTime); bigBit = curTime.tv_sec; littleBit = curTime.tv_usec; } class DynamicLibraryImpl : public DynamicLibrary { protected: GModule* m; public: DynamicLibraryImpl(const char *modulePath) { m = g_module_open(modulePath, G_MODULE_BIND_LAZY); } virtual ~DynamicLibraryImpl() { if (m != NULL) g_module_close(m); } // Use g_module_symbol to get a pointer to the relevant function. virtual Function FindFunction(const char *name) { if (m != NULL) { gpointer fn_address = NULL; gboolean status = g_module_symbol(m, name, &fn_address); if (status) return static_cast<Function>(fn_address); else return NULL; } else return NULL; } virtual bool IsValid() { return m != NULL; } }; DynamicLibrary *DynamicLibrary::Load(const char *modulePath) { return static_cast<DynamicLibrary *>( new DynamicLibraryImpl(modulePath) ); } double ElapsedTime::Duration(bool reset) { GTimeVal curTime; g_get_current_time(&curTime); long endBigBit = curTime.tv_sec; long endLittleBit = curTime.tv_usec; double result = 1000000.0 * (endBigBit - bigBit); result += endLittleBit - littleBit; result /= 1000000.0; if (reset) { bigBit = endBigBit; littleBit = endLittleBit; } return result; } ColourDesired Platform::Chrome() { return ColourDesired(0xe0, 0xe0, 0xe0); } ColourDesired Platform::ChromeHighlight() { return ColourDesired(0xff, 0xff, 0xff); } const char *Platform::DefaultFont() { #ifdef G_OS_WIN32 return "Lucida Console"; #else return "!Sans"; #endif } int Platform::DefaultFontSize() { #ifdef G_OS_WIN32 return 10; #else return 12; #endif } unsigned int Platform::DoubleClickTime() { return 500; // Half a second } bool Platform::MouseButtonBounce() { return true; } void Platform::DebugDisplay(const char *s) { fprintf(stderr, "%s", s); } bool Platform::IsKeyDown(int) { // TODO: discover state of keys in GTK+/X return false; } long Platform::SendScintilla( WindowID w, unsigned int msg, unsigned long wParam, long lParam) { return scintilla_send_message(SCINTILLA(w), msg, wParam, lParam); } long Platform::SendScintillaPointer( WindowID w, unsigned int msg, unsigned long wParam, void *lParam) { return scintilla_send_message(SCINTILLA(w), msg, wParam, reinterpret_cast<sptr_t>(lParam)); } bool Platform::IsDBCSLeadByte(int codePage, char ch) { // Byte ranges found in Wikipedia articles with relevant search strings in each case unsigned char uch = static_cast<unsigned char>(ch); switch (codePage) { case 932: // Shift_jis return ((uch >= 0x81) && (uch <= 0x9F)) || ((uch >= 0xE0) && (uch <= 0xFC)); // Lead bytes F0 to FC may be a Microsoft addition. case 936: // GBK return (uch >= 0x81) && (uch <= 0xFE); case 950: // Big5 return (uch >= 0x81) && (uch <= 0xFE); // Korean EUC-KR may be code page 949. } return false; } int Platform::DBCSCharLength(int codePage, const char *s) { if (codePage == 932 || codePage == 936 || codePage == 950) { return IsDBCSLeadByte(codePage, s[0]) ? 2 : 1; } else { int bytes = mblen(s, MB_CUR_MAX); if (bytes >= 1) return bytes; else return 1; } } int Platform::DBCSCharMaxLength() { return MB_CUR_MAX; //return 2; } // These are utility functions not really tied to a platform int Platform::Minimum(int a, int b) { if (a < b) return a; else return b; } int Platform::Maximum(int a, int b) { if (a > b) return a; else return b; } //#define TRACE #ifdef TRACE void Platform::DebugPrintf(const char *format, ...) { char buffer[2000]; va_list pArguments; va_start(pArguments, format); vsprintf(buffer, format, pArguments); va_end(pArguments); Platform::DebugDisplay(buffer); } #else void Platform::DebugPrintf(const char *, ...) {} #endif // Not supported for GTK+ static bool assertionPopUps = true; bool Platform::ShowAssertionPopUps(bool assertionPopUps_) { bool ret = assertionPopUps; assertionPopUps = assertionPopUps_; return ret; } void Platform::Assert(const char *c, const char *file, int line) { char buffer[2000]; sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line); strcat(buffer, "\r\n"); Platform::DebugDisplay(buffer); abort(); } int Platform::Clamp(int val, int minVal, int maxVal) { if (val > maxVal) val = maxVal; if (val < minVal) val = minVal; return val; } void Platform_Initialise() { FontMutexAllocate(); } void Platform_Finalise() { FontMutexFree(); } |
Added gtk/ScintillaGTK.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 |
// Scintilla source code edit control // ScintillaGTK.cxx - GTK+ specific subclass of ScintillaBase // Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <new> #include <stdlib.h> #include <string.h> #include <stdio.h> #include <assert.h> #include <ctype.h> #include <time.h> #include <string> #include <vector> #include <map> #include <gtk/gtk.h> #include <gdk/gdkkeysyms.h> #include "Platform.h" #if PLAT_GTK_WIN32 #include <windows.h> #endif #include "ILexer.h" #include "Scintilla.h" #include "ScintillaWidget.h" #ifdef SCI_LEXER #include "SciLexer.h" #endif #include "SVector.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" #include "ContractionState.h" #include "CellBuffer.h" #include "CallTip.h" #include "KeyMap.h" #include "Indicator.h" #include "XPM.h" #include "LineMarker.h" #include "Style.h" #include "AutoComplete.h" #include "ViewStyle.h" #include "Decoration.h" #include "CharClassify.h" #include "Document.h" #include "Selection.h" #include "PositionCache.h" #include "Editor.h" #include "ScintillaBase.h" #include "UniConversion.h" #include "scintilla-marshal.h" #ifdef SCI_LEXER #include <glib.h> #include <gmodule.h> #include "LexerModule.h" #include "ExternalLexer.h" #endif #include "Converter.h" #if defined(__clang__) // Clang 3.0 incorrectly displays sentinel warnings. Fixed by clang 3.1. #pragma GCC diagnostic ignored "-Wsentinel" #endif #if GTK_CHECK_VERSION(2,20,0) #define IS_WIDGET_REALIZED(w) (gtk_widget_get_realized(GTK_WIDGET(w))) #define IS_WIDGET_MAPPED(w) (gtk_widget_get_mapped(GTK_WIDGET(w))) #define IS_WIDGET_VISIBLE(w) (gtk_widget_get_visible(GTK_WIDGET(w))) #else #define IS_WIDGET_REALIZED(w) (GTK_WIDGET_REALIZED(w)) #define IS_WIDGET_MAPPED(w) (GTK_WIDGET_MAPPED(w)) #define IS_WIDGET_VISIBLE(w) (GTK_WIDGET_VISIBLE(w)) #endif static GdkWindow *WindowFromWidget(GtkWidget *w) { #if GTK_CHECK_VERSION(3,0,0) return gtk_widget_get_window(w); #else return w->window; #endif } static GdkWindow *PWindow(const Window &w) { GtkWidget *widget = reinterpret_cast<GtkWidget *>(w.GetID()); #if GTK_CHECK_VERSION(3,0,0) return gtk_widget_get_window(widget); #else return widget->window; #endif } #ifdef _MSC_VER // Constant conditional expressions are because of GTK+ headers #pragma warning(disable: 4127) // Ignore unreferenced local functions in GTK+ headers #pragma warning(disable: 4505) #endif #define OBJECT_CLASS GObjectClass #ifdef SCI_NAMESPACE using namespace Scintilla; #endif extern char *UTF8FromLatin1(const char *s, int &len); class ScintillaGTK : public ScintillaBase { _ScintillaObject *sci; Window wText; Window scrollbarv; Window scrollbarh; GtkAdjustment *adjustmentv; GtkAdjustment *adjustmenth; int scrollBarWidth; int scrollBarHeight; SelectionText primary; GdkEventButton evbtn; bool capturedMouse; bool dragWasDropped; int lastKey; int rectangularSelectionModifier; GtkWidgetClass *parentClass; static GdkAtom atomClipboard; static GdkAtom atomUTF8; static GdkAtom atomString; static GdkAtom atomUriList; static GdkAtom atomDROPFILES_DND; GdkAtom atomSought; #if PLAT_GTK_WIN32 CLIPFORMAT cfColumnSelect; #endif Window wPreedit; Window wPreeditDraw; GtkIMContext *im_context; // Wheel mouse support unsigned int linesPerScroll; GTimeVal lastWheelMouseTime; gint lastWheelMouseDirection; gint wheelMouseIntensity; #if GTK_CHECK_VERSION(3,0,0) cairo_rectangle_list_t *rgnUpdate; #else GdkRegion *rgnUpdate; #endif // Private so ScintillaGTK objects can not be copied ScintillaGTK(const ScintillaGTK &); ScintillaGTK &operator=(const ScintillaGTK &); public: ScintillaGTK(_ScintillaObject *sci_); virtual ~ScintillaGTK(); static void ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_class, GtkContainerClass *container_class); private: virtual void Initialise(); virtual void Finalise(); virtual void DisplayCursor(Window::Cursor c); virtual bool DragThreshold(Point ptStart, Point ptNow); virtual void StartDrag(); int TargetAsUTF8(char *text); int EncodedFromUTF8(char *utf8, char *encoded); virtual bool ValidCodePage(int codePage) const; public: // Public for scintilla_send_message virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); private: virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); virtual void SetTicking(bool on); virtual bool SetIdle(bool on); virtual void SetMouseCapture(bool on); virtual bool HaveMouseCapture(); virtual bool PaintContains(PRectangle rc); void FullPaint(); virtual PRectangle GetClientRectangle(); void SyncPaint(PRectangle rc); virtual void ScrollText(int linesToMove); virtual void SetVerticalScrollPos(); virtual void SetHorizontalScrollPos(); virtual bool ModifyScrollBars(int nMax, int nPage); void ReconfigureScrollBars(); virtual void NotifyChange(); virtual void NotifyFocus(bool focus); virtual void NotifyParent(SCNotification scn); void NotifyKey(int key, int modifiers); void NotifyURIDropped(const char *list); const char *CharacterSetID() const; virtual CaseFolder *CaseFolderForEncoding(); virtual std::string CaseMapString(const std::string &s, int caseMapping); virtual int KeyDefault(int key, int modifiers); virtual void CopyToClipboard(const SelectionText &selectedText); virtual void Copy(); virtual void Paste(); virtual void CreateCallTipWindow(PRectangle rc); virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true); bool OwnPrimarySelection(); virtual void ClaimSelection(); void GetGtkSelectionText(GtkSelectionData *selectionData, SelectionText &selText); void ReceivedSelection(GtkSelectionData *selection_data); void ReceivedDrop(GtkSelectionData *selection_data); static void GetSelection(GtkSelectionData *selection_data, guint info, SelectionText *selected); void StoreOnClipboard(SelectionText *clipText); static void ClipboardGetSelection(GtkClipboard* clip, GtkSelectionData *selection_data, guint info, void *data); static void ClipboardClearSelection(GtkClipboard* clip, void *data); void UnclaimSelection(GdkEventSelection *selection_event); void Resize(int width, int height); // Callback functions void RealizeThis(GtkWidget *widget); static void Realize(GtkWidget *widget); void UnRealizeThis(GtkWidget *widget); static void UnRealize(GtkWidget *widget); void MapThis(); static void Map(GtkWidget *widget); void UnMapThis(); static void UnMap(GtkWidget *widget); gint FocusInThis(GtkWidget *widget); static gint FocusIn(GtkWidget *widget, GdkEventFocus *event); gint FocusOutThis(GtkWidget *widget); static gint FocusOut(GtkWidget *widget, GdkEventFocus *event); static void SizeRequest(GtkWidget *widget, GtkRequisition *requisition); static void GetPreferredWidth(GtkWidget *widget, gint *minimalWidth, gint *naturalWidth); static void GetPreferredHeight(GtkWidget *widget, gint *minimalHeight, gint *naturalHeight); static void SizeAllocate(GtkWidget *widget, GtkAllocation *allocation); #if GTK_CHECK_VERSION(3,0,0) gboolean DrawTextThis(cairo_t *cr); static gboolean DrawText(GtkWidget *widget, cairo_t *cr, ScintillaGTK *sciThis); gboolean DrawThis(cairo_t *cr); static gboolean DrawMain(GtkWidget *widget, cairo_t *cr); #else gboolean ExposeTextThis(GtkWidget *widget, GdkEventExpose *ose); static gboolean ExposeText(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis); gboolean Expose(GtkWidget *widget, GdkEventExpose *ose); static gboolean ExposeMain(GtkWidget *widget, GdkEventExpose *ose); #endif static void Draw(GtkWidget *widget, GdkRectangle *area); void ForAll(GtkCallback callback, gpointer callback_data); static void MainForAll(GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); static void ScrollSignal(GtkAdjustment *adj, ScintillaGTK *sciThis); static void ScrollHSignal(GtkAdjustment *adj, ScintillaGTK *sciThis); gint PressThis(GdkEventButton *event); static gint Press(GtkWidget *widget, GdkEventButton *event); static gint MouseRelease(GtkWidget *widget, GdkEventButton *event); static gint ScrollEvent(GtkWidget *widget, GdkEventScroll *event); static gint Motion(GtkWidget *widget, GdkEventMotion *event); gboolean KeyThis(GdkEventKey *event); static gboolean KeyPress(GtkWidget *widget, GdkEventKey *event); static gboolean KeyRelease(GtkWidget *widget, GdkEventKey *event); #if GTK_CHECK_VERSION(3,0,0) gboolean DrawPreeditThis(GtkWidget *widget, cairo_t *cr); static gboolean DrawPreedit(GtkWidget *widget, cairo_t *cr, ScintillaGTK *sciThis); #else gboolean ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose); static gboolean ExposePreedit(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis); #endif void CommitThis(char *str); static void Commit(GtkIMContext *context, char *str, ScintillaGTK *sciThis); void PreeditChangedThis(); static void PreeditChanged(GtkIMContext *context, ScintillaGTK *sciThis); static void StyleSetText(GtkWidget *widget, GtkStyle *previous, void*); static void RealizeText(GtkWidget *widget, void*); static void Destroy(GObject *object); static void SelectionReceived(GtkWidget *widget, GtkSelectionData *selection_data, guint time); static void SelectionGet(GtkWidget *widget, GtkSelectionData *selection_data, guint info, guint time); static gint SelectionClear(GtkWidget *widget, GdkEventSelection *selection_event); static void DragBegin(GtkWidget *widget, GdkDragContext *context); gboolean DragMotionThis(GdkDragContext *context, gint x, gint y, guint dragtime); static gboolean DragMotion(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint dragtime); static void DragLeave(GtkWidget *widget, GdkDragContext *context, guint time); static void DragEnd(GtkWidget *widget, GdkDragContext *context); static gboolean Drop(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time); static void DragDataReceived(GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time); static void DragDataGet(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data, guint info, guint time); static gboolean TimeOut(ScintillaGTK *sciThis); static gboolean IdleCallback(ScintillaGTK *sciThis); static gboolean StyleIdle(ScintillaGTK *sciThis); virtual void QueueIdleWork(WorkNeeded::workItems items, int upTo); static void PopUpCB(GtkMenuItem *menuItem, ScintillaGTK *sciThis); #if GTK_CHECK_VERSION(3,0,0) static gboolean DrawCT(GtkWidget *widget, cairo_t *cr, CallTip *ctip); #else static gboolean ExposeCT(GtkWidget *widget, GdkEventExpose *ose, CallTip *ct); #endif static gboolean PressCT(GtkWidget *widget, GdkEventButton *event, ScintillaGTK *sciThis); static sptr_t DirectFunction(ScintillaGTK *sciThis, unsigned int iMessage, uptr_t wParam, sptr_t lParam); }; enum { COMMAND_SIGNAL, NOTIFY_SIGNAL, LAST_SIGNAL }; static gint scintilla_signals[LAST_SIGNAL] = { 0 }; enum { TARGET_STRING, TARGET_TEXT, TARGET_COMPOUND_TEXT, TARGET_UTF8_STRING, TARGET_URI }; GdkAtom ScintillaGTK::atomClipboard = 0; GdkAtom ScintillaGTK::atomUTF8 = 0; GdkAtom ScintillaGTK::atomString = 0; GdkAtom ScintillaGTK::atomUriList = 0; GdkAtom ScintillaGTK::atomDROPFILES_DND = 0; static const GtkTargetEntry clipboardCopyTargets[] = { { (gchar *) "UTF8_STRING", 0, TARGET_UTF8_STRING }, { (gchar *) "STRING", 0, TARGET_STRING }, }; static const gint nClipboardCopyTargets = sizeof(clipboardCopyTargets) / sizeof(clipboardCopyTargets[0]); static const GtkTargetEntry clipboardPasteTargets[] = { { (gchar *) "text/uri-list", 0, TARGET_URI }, { (gchar *) "UTF8_STRING", 0, TARGET_UTF8_STRING }, { (gchar *) "STRING", 0, TARGET_STRING }, }; static const gint nClipboardPasteTargets = sizeof(clipboardPasteTargets) / sizeof(clipboardPasteTargets[0]); static GtkWidget *PWidget(Window &w) { return reinterpret_cast<GtkWidget *>(w.GetID()); } static ScintillaGTK *ScintillaFromWidget(GtkWidget *widget) { ScintillaObject *scio = reinterpret_cast<ScintillaObject *>(widget); return reinterpret_cast<ScintillaGTK *>(scio->pscin); } ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) : adjustmentv(0), adjustmenth(0), scrollBarWidth(30), scrollBarHeight(30), capturedMouse(false), dragWasDropped(false), lastKey(0), rectangularSelectionModifier(SCMOD_CTRL), parentClass(0), im_context(NULL), lastWheelMouseDirection(0), wheelMouseIntensity(0), rgnUpdate(0) { sci = sci_; wMain = GTK_WIDGET(sci); #if PLAT_GTK_WIN32 rectangularSelectionModifier = SCMOD_ALT; #else rectangularSelectionModifier = SCMOD_CTRL; #endif #if PLAT_GTK_WIN32 // There does not seem to be a real standard for indicating that the clipboard // contains a rectangular selection, so copy Developer Studio. cfColumnSelect = static_cast<CLIPFORMAT>( ::RegisterClipboardFormat("MSDEVColumnSelect")); // Get intellimouse parameters when running on win32; otherwise use // reasonable default #ifndef SPI_GETWHEELSCROLLLINES #define SPI_GETWHEELSCROLLLINES 104 #endif ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &linesPerScroll, 0); #else linesPerScroll = 4; #endif lastWheelMouseTime.tv_sec = 0; lastWheelMouseTime.tv_usec = 0; Initialise(); } ScintillaGTK::~ScintillaGTK() { g_idle_remove_by_data(this); } static void UnRefCursor(GdkCursor *cursor) { #if GTK_CHECK_VERSION(3,0,0) g_object_unref(cursor); #else gdk_cursor_unref(cursor); #endif } void ScintillaGTK::RealizeThis(GtkWidget *widget) { //Platform::DebugPrintf("ScintillaGTK::realize this\n"); #if GTK_CHECK_VERSION(2,20,0) gtk_widget_set_realized(widget, TRUE); #else GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED); #endif GdkWindowAttr attrs; attrs.window_type = GDK_WINDOW_CHILD; GtkAllocation allocation; #if GTK_CHECK_VERSION(3,0,0) gtk_widget_get_allocation(widget, &allocation); #else allocation = widget->allocation; #endif attrs.x = allocation.x; attrs.y = allocation.y; attrs.width = allocation.width; attrs.height = allocation.height; attrs.wclass = GDK_INPUT_OUTPUT; attrs.visual = gtk_widget_get_visual(widget); #if !GTK_CHECK_VERSION(3,0,0) attrs.colormap = gtk_widget_get_colormap(widget); #endif attrs.event_mask = gtk_widget_get_events(widget) | GDK_EXPOSURE_MASK; GdkCursor *cursor = gdk_cursor_new(GDK_XTERM); attrs.cursor = cursor; #if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_window(widget, gdk_window_new(gtk_widget_get_parent_window(widget), &attrs, GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_CURSOR)); gdk_window_set_user_data(gtk_widget_get_window(widget), widget); GtkStyleContext *styleContext = gtk_widget_get_style_context(widget); if (styleContext) { GdkRGBA colourBackWidget; gtk_style_context_get_background_color(styleContext, GTK_STATE_FLAG_NORMAL, &colourBackWidget); gdk_window_set_background_rgba(gtk_widget_get_window(widget), &colourBackWidget); } gdk_window_show(gtk_widget_get_window(widget)); UnRefCursor(cursor); #else widget->window = gdk_window_new(gtk_widget_get_parent_window(widget), &attrs, GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_CURSOR); gdk_window_set_user_data(widget->window, widget); widget->style = gtk_style_attach(widget->style, widget->window); gdk_window_set_background(widget->window, &widget->style->bg[GTK_STATE_NORMAL]); gdk_window_show(widget->window); UnRefCursor(cursor); #endif wPreedit = gtk_window_new(GTK_WINDOW_POPUP); wPreeditDraw = gtk_drawing_area_new(); GtkWidget *predrw = PWidget(wPreeditDraw); // No code inside the G_OBJECT macro #if GTK_CHECK_VERSION(3,0,0) g_signal_connect(G_OBJECT(predrw), "draw", G_CALLBACK(DrawPreedit), this); #else g_signal_connect(G_OBJECT(predrw), "expose_event", G_CALLBACK(ExposePreedit), this); #endif gtk_container_add(GTK_CONTAINER(PWidget(wPreedit)), predrw); gtk_widget_realize(PWidget(wPreedit)); gtk_widget_realize(predrw); gtk_widget_show(predrw); im_context = gtk_im_multicontext_new(); g_signal_connect(G_OBJECT(im_context), "commit", G_CALLBACK(Commit), this); g_signal_connect(G_OBJECT(im_context), "preedit_changed", G_CALLBACK(PreeditChanged), this); gtk_im_context_set_client_window(im_context, WindowFromWidget(widget)); GtkWidget *widtxt = PWidget(wText); // // No code inside the G_OBJECT macro g_signal_connect_after(G_OBJECT(widtxt), "style_set", G_CALLBACK(ScintillaGTK::StyleSetText), NULL); g_signal_connect_after(G_OBJECT(widtxt), "realize", G_CALLBACK(ScintillaGTK::RealizeText), NULL); gtk_widget_realize(widtxt); gtk_widget_realize(PWidget(scrollbarv)); gtk_widget_realize(PWidget(scrollbarh)); cursor = gdk_cursor_new(GDK_XTERM); gdk_window_set_cursor(PWindow(wText), cursor); UnRefCursor(cursor); cursor = gdk_cursor_new(GDK_LEFT_PTR); gdk_window_set_cursor(PWindow(scrollbarv), cursor); UnRefCursor(cursor); cursor = gdk_cursor_new(GDK_LEFT_PTR); gdk_window_set_cursor(PWindow(scrollbarh), cursor); UnRefCursor(cursor); gtk_selection_add_targets(widget, GDK_SELECTION_PRIMARY, clipboardCopyTargets, nClipboardCopyTargets); } void ScintillaGTK::Realize(GtkWidget *widget) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); sciThis->RealizeThis(widget); } void ScintillaGTK::UnRealizeThis(GtkWidget *widget) { try { gtk_selection_clear_targets(widget, GDK_SELECTION_PRIMARY); if (IS_WIDGET_MAPPED(widget)) { gtk_widget_unmap(widget); } #if GTK_CHECK_VERSION(2,20,0) gtk_widget_set_realized(widget, FALSE); #else GTK_WIDGET_UNSET_FLAGS(widget, GTK_REALIZED); #endif gtk_widget_unrealize(PWidget(wText)); gtk_widget_unrealize(PWidget(scrollbarv)); gtk_widget_unrealize(PWidget(scrollbarh)); gtk_widget_unrealize(PWidget(wPreedit)); gtk_widget_unrealize(PWidget(wPreeditDraw)); g_object_unref(im_context); im_context = NULL; if (GTK_WIDGET_CLASS(parentClass)->unrealize) GTK_WIDGET_CLASS(parentClass)->unrealize(widget); Finalise(); } catch (...) { errorStatus = SC_STATUS_FAILURE; } } void ScintillaGTK::UnRealize(GtkWidget *widget) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); sciThis->UnRealizeThis(widget); } static void MapWidget(GtkWidget *widget) { if (widget && IS_WIDGET_VISIBLE(widget) && !IS_WIDGET_MAPPED(widget)) { gtk_widget_map(widget); } } void ScintillaGTK::MapThis() { try { //Platform::DebugPrintf("ScintillaGTK::map this\n"); #if GTK_CHECK_VERSION(2,20,0) gtk_widget_set_mapped(PWidget(wMain), TRUE); #else GTK_WIDGET_SET_FLAGS(PWidget(wMain), GTK_MAPPED); #endif MapWidget(PWidget(wText)); MapWidget(PWidget(scrollbarh)); MapWidget(PWidget(scrollbarv)); wMain.SetCursor(Window::cursorArrow); scrollbarv.SetCursor(Window::cursorArrow); scrollbarh.SetCursor(Window::cursorArrow); ChangeSize(); gdk_window_show(PWindow(wMain)); } catch (...) { errorStatus = SC_STATUS_FAILURE; } } void ScintillaGTK::Map(GtkWidget *widget) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); sciThis->MapThis(); } void ScintillaGTK::UnMapThis() { try { //Platform::DebugPrintf("ScintillaGTK::unmap this\n"); #if GTK_CHECK_VERSION(2,20,0) gtk_widget_set_mapped(PWidget(wMain), FALSE); #else GTK_WIDGET_UNSET_FLAGS(PWidget(wMain), GTK_MAPPED); #endif DropGraphics(false); gdk_window_hide(PWindow(wMain)); gtk_widget_unmap(PWidget(wText)); gtk_widget_unmap(PWidget(scrollbarh)); gtk_widget_unmap(PWidget(scrollbarv)); } catch (...) { errorStatus = SC_STATUS_FAILURE; } } void ScintillaGTK::UnMap(GtkWidget *widget) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); sciThis->UnMapThis(); } void ScintillaGTK::ForAll(GtkCallback callback, gpointer callback_data) { try { (*callback) (PWidget(wText), callback_data); (*callback) (PWidget(scrollbarv), callback_data); (*callback) (PWidget(scrollbarh), callback_data); } catch (...) { errorStatus = SC_STATUS_FAILURE; } } void ScintillaGTK::MainForAll(GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data) { ScintillaGTK *sciThis = ScintillaFromWidget((GtkWidget *)container); if (callback != NULL && include_internals) { sciThis->ForAll(callback, callback_data); } } gint ScintillaGTK::FocusInThis(GtkWidget *widget) { try { SetFocusState(true); if (im_context != NULL) { gchar *str = NULL; gint cursor_pos; gtk_im_context_get_preedit_string(im_context, &str, NULL, &cursor_pos); if (PWidget(wPreedit) != NULL) { if (strlen(str) > 0) { gtk_widget_show(PWidget(wPreedit)); } else { gtk_widget_hide(PWidget(wPreedit)); } } g_free(str); gtk_im_context_focus_in(im_context); } } catch (...) { errorStatus = SC_STATUS_FAILURE; } return FALSE; } gint ScintillaGTK::FocusIn(GtkWidget *widget, GdkEventFocus * /*event*/) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); return sciThis->FocusInThis(widget); } gint ScintillaGTK::FocusOutThis(GtkWidget *widget) { try { SetFocusState(false); if (PWidget(wPreedit) != NULL) gtk_widget_hide(PWidget(wPreedit)); if (im_context != NULL) gtk_im_context_focus_out(im_context); } catch (...) { errorStatus = SC_STATUS_FAILURE; } return FALSE; } gint ScintillaGTK::FocusOut(GtkWidget *widget, GdkEventFocus * /*event*/) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); return sciThis->FocusOutThis(widget); } void ScintillaGTK::SizeRequest(GtkWidget *widget, GtkRequisition *requisition) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); requisition->width = 1; requisition->height = 1; GtkRequisition child_requisition; #if GTK_CHECK_VERSION(3,0,0) gtk_widget_get_preferred_size(PWidget(sciThis->scrollbarh), NULL, &child_requisition); gtk_widget_get_preferred_size(PWidget(sciThis->scrollbarv), NULL, &child_requisition); #else gtk_widget_size_request(PWidget(sciThis->scrollbarh), &child_requisition); gtk_widget_size_request(PWidget(sciThis->scrollbarv), &child_requisition); #endif } void ScintillaGTK::GetPreferredWidth(GtkWidget *widget, gint *minimalWidth, gint *naturalWidth) { GtkRequisition requisition; SizeRequest(widget, &requisition); *minimalWidth = *naturalWidth = requisition.width; } void ScintillaGTK::GetPreferredHeight(GtkWidget *widget, gint *minimalHeight, gint *naturalHeight) { GtkRequisition requisition; SizeRequest(widget, &requisition); *minimalHeight = *naturalHeight = requisition.height; } void ScintillaGTK::SizeAllocate(GtkWidget *widget, GtkAllocation *allocation) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); try { #if GTK_CHECK_VERSION(2,20,0) gtk_widget_set_allocation(widget, allocation); #else widget->allocation = *allocation; #endif if (IS_WIDGET_REALIZED(widget)) gdk_window_move_resize(WindowFromWidget(widget), allocation->x, allocation->y, allocation->width, allocation->height); sciThis->Resize(allocation->width, allocation->height); } catch (...) { sciThis->errorStatus = SC_STATUS_FAILURE; } } void ScintillaGTK::Initialise() { //Platform::DebugPrintf("ScintillaGTK::Initialise\n"); parentClass = reinterpret_cast<GtkWidgetClass *>( g_type_class_ref(gtk_container_get_type())); #if GTK_CHECK_VERSION(2,20,0) gtk_widget_set_can_focus(PWidget(wMain), TRUE); gtk_widget_set_sensitive(PWidget(wMain), TRUE); #else GTK_WIDGET_SET_FLAGS(PWidget(wMain), GTK_CAN_FOCUS); GTK_WIDGET_SET_FLAGS(GTK_WIDGET(PWidget(wMain)), GTK_SENSITIVE); #endif gtk_widget_set_events(PWidget(wMain), GDK_EXPOSURE_MASK | GDK_SCROLL_MASK | GDK_STRUCTURE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); wText = gtk_drawing_area_new(); gtk_widget_set_parent(PWidget(wText), PWidget(wMain)); GtkWidget *widtxt = PWidget(wText); // No code inside the G_OBJECT macro gtk_widget_show(widtxt); #if GTK_CHECK_VERSION(3,0,0) g_signal_connect(G_OBJECT(widtxt), "draw", G_CALLBACK(ScintillaGTK::DrawText), this); #else g_signal_connect(G_OBJECT(widtxt), "expose_event", G_CALLBACK(ScintillaGTK::ExposeText), this); #endif gtk_widget_set_events(widtxt, GDK_EXPOSURE_MASK); // Avoid background drawing flash gtk_widget_set_double_buffered(widtxt, FALSE); gtk_widget_set_size_request(widtxt, 100, 100); adjustmentv = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 201.0, 1.0, 20.0, 20.0)); #if GTK_CHECK_VERSION(3,0,0) scrollbarv = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT(adjustmentv)); #else scrollbarv = gtk_vscrollbar_new(GTK_ADJUSTMENT(adjustmentv)); #endif #if GTK_CHECK_VERSION(2,20,0) gtk_widget_set_can_focus(PWidget(scrollbarv), FALSE); #else GTK_WIDGET_UNSET_FLAGS(PWidget(scrollbarv), GTK_CAN_FOCUS); #endif g_signal_connect(G_OBJECT(adjustmentv), "value_changed", G_CALLBACK(ScrollSignal), this); gtk_widget_set_parent(PWidget(scrollbarv), PWidget(wMain)); gtk_widget_show(PWidget(scrollbarv)); adjustmenth = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 101.0, 1.0, 20.0, 20.0)); #if GTK_CHECK_VERSION(3,0,0) scrollbarh = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT(adjustmenth)); #else scrollbarh = gtk_hscrollbar_new(GTK_ADJUSTMENT(adjustmenth)); #endif #if GTK_CHECK_VERSION(2,20,0) gtk_widget_set_can_focus(PWidget(scrollbarh), FALSE); #else GTK_WIDGET_UNSET_FLAGS(PWidget(scrollbarh), GTK_CAN_FOCUS); #endif g_signal_connect(G_OBJECT(adjustmenth), "value_changed", G_CALLBACK(ScrollHSignal), this); gtk_widget_set_parent(PWidget(scrollbarh), PWidget(wMain)); gtk_widget_show(PWidget(scrollbarh)); gtk_widget_grab_focus(PWidget(wMain)); gtk_drag_dest_set(GTK_WIDGET(PWidget(wMain)), GTK_DEST_DEFAULT_ALL, clipboardPasteTargets, nClipboardPasteTargets, static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE)); // Set caret period based on GTK settings gboolean blinkOn = false; if (g_object_class_find_property(G_OBJECT_GET_CLASS( G_OBJECT(gtk_settings_get_default())), "gtk-cursor-blink")) { g_object_get(G_OBJECT( gtk_settings_get_default()), "gtk-cursor-blink", &blinkOn, NULL); } if (blinkOn && g_object_class_find_property(G_OBJECT_GET_CLASS( G_OBJECT(gtk_settings_get_default())), "gtk-cursor-blink-time")) { gint value; g_object_get(G_OBJECT( gtk_settings_get_default()), "gtk-cursor-blink-time", &value, NULL); caret.period = gint(value / 1.75); } else { caret.period = 0; } SetTicking(true); } void ScintillaGTK::Finalise() { SetTicking(false); ScintillaBase::Finalise(); } void ScintillaGTK::DisplayCursor(Window::Cursor c) { if (cursorMode == SC_CURSORNORMAL) wText.SetCursor(c); else wText.SetCursor(static_cast<Window::Cursor>(cursorMode)); } bool ScintillaGTK::DragThreshold(Point ptStart, Point ptNow) { return gtk_drag_check_threshold(GTK_WIDGET(PWidget(wMain)), ptStart.x, ptStart.y, ptNow.x, ptNow.y); } void ScintillaGTK::StartDrag() { dragWasDropped = false; inDragDrop = ddDragging; GtkTargetList *tl = gtk_target_list_new(clipboardCopyTargets, nClipboardCopyTargets); gtk_drag_begin(GTK_WIDGET(PWidget(wMain)), tl, static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE), evbtn.button, reinterpret_cast<GdkEvent *>(&evbtn)); } static char *ConvertText(int *lenResult, char *s, size_t len, const char *charSetDest, const char *charSetSource, bool transliterations, bool silent=false) { // s is not const because of different versions of iconv disagreeing about const *lenResult = 0; char *destForm = 0; Converter conv(charSetDest, charSetSource, transliterations); if (conv) { destForm = new char[len*3+1]; char *pin = s; size_t inLeft = len; char *pout = destForm; size_t outLeft = len*3+1; size_t conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft); if (conversions == ((size_t)(-1))) { if (!silent) fprintf(stderr, "iconv %s->%s failed for %s\n", charSetSource, charSetDest, static_cast<char *>(s)); delete []destForm; destForm = 0; } else { //fprintf(stderr, "iconv OK %s %d\n", destForm, pout - destForm); *pout = '\0'; *lenResult = pout - destForm; } } else { fprintf(stderr, "Can not iconv %s %s\n", charSetDest, charSetSource); } if (!destForm) { destForm = new char[1]; destForm[0] = '\0'; *lenResult = 0; } return destForm; } // Returns the target converted to UTF8. // Return the length in bytes. int ScintillaGTK::TargetAsUTF8(char *text) { int targetLength = targetEnd - targetStart; if (IsUnicodeMode()) { if (text) { pdoc->GetCharRange(text, targetStart, targetLength); } } else { // Need to convert const char *charSetBuffer = CharacterSetID(); if (*charSetBuffer) { //~ fprintf(stderr, "AsUTF8 %s %d %0d-%0d\n", charSetBuffer, targetLength, targetStart, targetEnd); char *s = new char[targetLength]; if (s) { pdoc->GetCharRange(s, targetStart, targetLength); //~ fprintf(stderr, " \"%s\"\n", s); if (text) { char *tmputf = ConvertText(&targetLength, s, targetLength, "UTF-8", charSetBuffer, false); memcpy(text, tmputf, targetLength); delete []tmputf; //~ fprintf(stderr, " \"%s\"\n", text); } delete []s; } } else { if (text) { pdoc->GetCharRange(text, targetStart, targetLength); } } } //~ fprintf(stderr, "Length = %d bytes\n", targetLength); return targetLength; } // Translates a nul terminated UTF8 string into the document encoding. // Return the length of the result in bytes. int ScintillaGTK::EncodedFromUTF8(char *utf8, char *encoded) { int inputLength = (lengthForEncode >= 0) ? lengthForEncode : strlen(utf8); if (IsUnicodeMode()) { if (encoded) { memcpy(encoded, utf8, inputLength); } return inputLength; } else { // Need to convert const char *charSetBuffer = CharacterSetID(); if (*charSetBuffer) { int outLength = 0; char *tmpEncoded = ConvertText(&outLength, utf8, inputLength, charSetBuffer, "UTF-8", true); if (tmpEncoded) { if (encoded) { memcpy(encoded, tmpEncoded, outLength); } delete []tmpEncoded; } return outLength; } else { if (encoded) { memcpy(encoded, utf8, inputLength); } return inputLength; } } // Fail return 0; } bool ScintillaGTK::ValidCodePage(int codePage) const { return codePage == 0 || codePage == SC_CP_UTF8 || codePage == 932 || codePage == 936 || codePage == 949 || codePage == 950 || codePage == 1361; } sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { try { switch (iMessage) { case SCI_GRABFOCUS: gtk_widget_grab_focus(PWidget(wMain)); break; case SCI_GETDIRECTFUNCTION: return reinterpret_cast<sptr_t>(DirectFunction); case SCI_GETDIRECTPOINTER: return reinterpret_cast<sptr_t>(this); #ifdef SCI_LEXER case SCI_LOADLEXERLIBRARY: LexerManager::GetInstance()->Load(reinterpret_cast<const char*>(lParam)); break; #endif case SCI_TARGETASUTF8: return TargetAsUTF8(reinterpret_cast<char*>(lParam)); case SCI_ENCODEDFROMUTF8: return EncodedFromUTF8(reinterpret_cast<char*>(wParam), reinterpret_cast<char*>(lParam)); case SCI_SETRECTANGULARSELECTIONMODIFIER: rectangularSelectionModifier = wParam; break; case SCI_GETRECTANGULARSELECTIONMODIFIER: return rectangularSelectionModifier; default: return ScintillaBase::WndProc(iMessage, wParam, lParam); } } catch (std::bad_alloc&) { errorStatus = SC_STATUS_BADALLOC; } catch (...) { errorStatus = SC_STATUS_FAILURE; } return 0l; } sptr_t ScintillaGTK::DefWndProc(unsigned int, uptr_t, sptr_t) { return 0; } void ScintillaGTK::SetTicking(bool on) { if (timer.ticking != on) { timer.ticking = on; if (timer.ticking) { timer.tickerID = reinterpret_cast<TickerID>(g_timeout_add(timer.tickSize, reinterpret_cast<GSourceFunc>(TimeOut), this)); } else { g_source_remove(GPOINTER_TO_UINT(timer.tickerID)); } } timer.ticksToWait = caret.period; } bool ScintillaGTK::SetIdle(bool on) { if (on) { // Start idler, if it's not running. if (!idler.state) { idler.state = true; idler.idlerID = reinterpret_cast<IdlerID>( g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, reinterpret_cast<GSourceFunc>(IdleCallback), this, NULL)); } } else { // Stop idler, if it's running if (idler.state) { idler.state = false; g_source_remove(GPOINTER_TO_UINT(idler.idlerID)); } } return true; } void ScintillaGTK::SetMouseCapture(bool on) { if (mouseDownCaptures) { if (on) { gtk_grab_add(GTK_WIDGET(PWidget(wMain))); } else { gtk_grab_remove(GTK_WIDGET(PWidget(wMain))); } } capturedMouse = on; } bool ScintillaGTK::HaveMouseCapture() { return capturedMouse; } #if GTK_CHECK_VERSION(3,0,0) // Is crcTest completely in crcContainer? static bool CRectContains(const cairo_rectangle_t &crcContainer, const cairo_rectangle_t &crcTest) { return (crcTest.x >= crcContainer.x) && ((crcTest.x + crcTest.width) <= (crcContainer.x + crcContainer.width)) && (crcTest.y >= crcContainer.y) && ((crcTest.y + crcTest.height) <= (crcContainer.y + crcContainer.height)); } // Is crcTest completely in crcListContainer? // May incorrectly return false if complex shape static bool CRectListContains(const cairo_rectangle_list_t *crcListContainer, const cairo_rectangle_t &crcTest) { for (int r=0; r<crcListContainer->num_rectangles; r++) { if (CRectContains(crcListContainer->rectangles[r], crcTest)) return true; } return false; } #endif bool ScintillaGTK::PaintContains(PRectangle rc) { // This allows optimization when a rectangle is completely in the update region. // It is OK to return false when too difficult to determine as that just performs extra drawing bool contains = true; if (paintState == painting) { if (!rcPaint.Contains(rc)) { contains = false; } else if (rgnUpdate) { #if GTK_CHECK_VERSION(3,0,0) cairo_rectangle_t grc = {rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top}; contains = CRectListContains(rgnUpdate, grc); #else GdkRectangle grc = {static_cast<gint>(rc.left), static_cast<gint>(rc.top), static_cast<gint>(rc.right - rc.left), static_cast<gint>(rc.bottom - rc.top)}; if (gdk_region_rect_in(rgnUpdate, &grc) != GDK_OVERLAP_RECTANGLE_IN) { contains = false; } #endif } } return contains; } // Redraw all of text area. This paint will not be abandoned. void ScintillaGTK::FullPaint() { wText.InvalidateAll(); } PRectangle ScintillaGTK::GetClientRectangle() { PRectangle rc = wMain.GetClientPosition(); if (verticalScrollBarVisible) rc.right -= scrollBarWidth; if (horizontalScrollBarVisible && (wrapState == eWrapNone)) rc.bottom -= scrollBarHeight; // Move to origin rc.right -= rc.left; rc.bottom -= rc.top; rc.left = 0; rc.top = 0; return rc; } // Synchronously paint a rectangle of the window. void ScintillaGTK::SyncPaint(PRectangle rc) { paintState = painting; rcPaint = rc; PRectangle rcClient = GetClientRectangle(); paintingAllText = rcPaint.Contains(rcClient); if (PWindow(wText)) { Surface *sw = Surface::Allocate(SC_TECHNOLOGY_DEFAULT); if (sw) { cairo_t *cr = gdk_cairo_create(PWindow(wText)); sw->Init(cr, PWidget(wText)); Paint(sw, rc); sw->Release(); delete sw; cairo_destroy(cr); } } if (paintState == paintAbandoned) { // Painting area was insufficient to cover new styling or brace highlight positions FullPaint(); } paintState = notPainting; } void ScintillaGTK::ScrollText(int linesToMove) { int diff = vs.lineHeight * -linesToMove; //Platform::DebugPrintf("ScintillaGTK::ScrollText %d %d %0d,%0d %0d,%0d\n", linesToMove, diff, // rc.left, rc.top, rc.right, rc.bottom); GtkWidget *wi = PWidget(wText); NotifyUpdateUI(); if (IS_WIDGET_REALIZED(wi)) { gdk_window_scroll(WindowFromWidget(wi), 0, -diff); gdk_window_process_updates(WindowFromWidget(wi), FALSE); } } void ScintillaGTK::SetVerticalScrollPos() { DwellEnd(true); gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustmentv), topLine); } void ScintillaGTK::SetHorizontalScrollPos() { DwellEnd(true); gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustmenth), xOffset / 2); } bool ScintillaGTK::ModifyScrollBars(int nMax, int nPage) { bool modified = false; int pageScroll = LinesToScroll(); #if GTK_CHECK_VERSION(3,0,0) if (gtk_adjustment_get_upper(adjustmentv) != (nMax + 1) || gtk_adjustment_get_page_size(adjustmentv) != nPage || gtk_adjustment_get_page_increment(adjustmentv) != pageScroll) { gtk_adjustment_set_upper(adjustmentv, nMax + 1); gtk_adjustment_set_page_size(adjustmentv, nPage); gtk_adjustment_set_page_increment(adjustmentv, pageScroll); gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmentv)); modified = true; } #else if (GTK_ADJUSTMENT(adjustmentv)->upper != (nMax + 1) || GTK_ADJUSTMENT(adjustmentv)->page_size != nPage || GTK_ADJUSTMENT(adjustmentv)->page_increment != pageScroll) { GTK_ADJUSTMENT(adjustmentv)->upper = nMax + 1; GTK_ADJUSTMENT(adjustmentv)->page_size = nPage; GTK_ADJUSTMENT(adjustmentv)->page_increment = pageScroll; gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmentv)); modified = true; } #endif PRectangle rcText = GetTextRectangle(); int horizEndPreferred = scrollWidth; if (horizEndPreferred < 0) horizEndPreferred = 0; unsigned int pageWidth = rcText.Width(); unsigned int pageIncrement = pageWidth / 3; unsigned int charWidth = vs.styles[STYLE_DEFAULT].aveCharWidth; #if GTK_CHECK_VERSION(3,0,0) if (gtk_adjustment_get_upper(adjustmenth) != horizEndPreferred || gtk_adjustment_get_page_size(adjustmenth) != pageWidth || gtk_adjustment_get_page_increment(adjustmenth) != pageIncrement || gtk_adjustment_get_step_increment(adjustmenth) != charWidth) { gtk_adjustment_set_upper(adjustmenth, horizEndPreferred); gtk_adjustment_set_page_size(adjustmenth, pageWidth); gtk_adjustment_set_page_increment(adjustmenth, pageIncrement); gtk_adjustment_set_step_increment(adjustmenth, charWidth); gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmenth)); modified = true; } #else if (GTK_ADJUSTMENT(adjustmenth)->upper != horizEndPreferred || GTK_ADJUSTMENT(adjustmenth)->page_size != pageWidth || GTK_ADJUSTMENT(adjustmenth)->page_increment != pageIncrement || GTK_ADJUSTMENT(adjustmenth)->step_increment != charWidth) { GTK_ADJUSTMENT(adjustmenth)->upper = horizEndPreferred; GTK_ADJUSTMENT(adjustmenth)->step_increment = charWidth; GTK_ADJUSTMENT(adjustmenth)->page_size = pageWidth; GTK_ADJUSTMENT(adjustmenth)->page_increment = pageIncrement; gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmenth)); modified = true; } #endif if (modified && (paintState == painting)) { paintState = paintAbandoned; } return modified; } void ScintillaGTK::ReconfigureScrollBars() { PRectangle rc = wMain.GetClientPosition(); Resize(rc.Width(), rc.Height()); } void ScintillaGTK::NotifyChange() { g_signal_emit(G_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL], 0, Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE), PWidget(wMain)); } void ScintillaGTK::NotifyFocus(bool focus) { g_signal_emit(G_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL], 0, Platform::LongFromTwoShorts (GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), PWidget(wMain)); } void ScintillaGTK::NotifyParent(SCNotification scn) { scn.nmhdr.hwndFrom = PWidget(wMain); scn.nmhdr.idFrom = GetCtrlID(); g_signal_emit(G_OBJECT(sci), scintilla_signals[NOTIFY_SIGNAL], 0, GetCtrlID(), &scn); } void ScintillaGTK::NotifyKey(int key, int modifiers) { SCNotification scn = {0}; scn.nmhdr.code = SCN_KEY; scn.ch = key; scn.modifiers = modifiers; NotifyParent(scn); } void ScintillaGTK::NotifyURIDropped(const char *list) { SCNotification scn = {0}; scn.nmhdr.code = SCN_URIDROPPED; scn.text = list; NotifyParent(scn); } const char *CharacterSetID(int characterSet); const char *ScintillaGTK::CharacterSetID() const { return ::CharacterSetID(vs.styles[STYLE_DEFAULT].characterSet); } class CaseFolderUTF8 : public CaseFolderTable { public: CaseFolderUTF8() { StandardASCII(); } virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) { if ((lenMixed == 1) && (sizeFolded > 0)) { folded[0] = mapping[static_cast<unsigned char>(mixed[0])]; return 1; } else { gchar *mapped = g_utf8_casefold(mixed, lenMixed); size_t lenMapped = strlen(mapped); if (lenMapped < sizeFolded) { memcpy(folded, mapped, lenMapped); } else { lenMapped = 0; } g_free(mapped); return lenMapped; } } }; class CaseFolderDBCS : public CaseFolderTable { const char *charSet; public: CaseFolderDBCS(const char *charSet_) : charSet(charSet_) { StandardASCII(); } virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) { if ((lenMixed == 1) && (sizeFolded > 0)) { folded[0] = mapping[static_cast<unsigned char>(mixed[0])]; return 1; } else if (*charSet) { int convertedLength = lenMixed; char *sUTF8 = ConvertText(&convertedLength, const_cast<char *>(mixed), lenMixed, "UTF-8", charSet, false); if (sUTF8) { gchar *mapped = g_utf8_casefold(sUTF8, strlen(sUTF8)); size_t lenMapped = strlen(mapped); if (lenMapped < sizeFolded) { memcpy(folded, mapped, lenMapped); } else { folded[0] = '\0'; lenMapped = 1; } g_free(mapped); delete []sUTF8; return lenMapped; } } // Something failed so return a single NUL byte folded[0] = '\0'; return 1; } }; CaseFolder *ScintillaGTK::CaseFolderForEncoding() { if (pdoc->dbcsCodePage == SC_CP_UTF8) { return new CaseFolderUTF8(); } else { const char *charSetBuffer = CharacterSetID(); if (charSetBuffer) { if (pdoc->dbcsCodePage == 0) { CaseFolderTable *pcf = new CaseFolderTable(); pcf->StandardASCII(); // Only for single byte encodings for (int i=0x80; i<0x100; i++) { char sCharacter[2] = "A"; sCharacter[0] = i; int convertedLength = 1; const char *sUTF8 = ConvertText(&convertedLength, sCharacter, 1, "UTF-8", charSetBuffer, false); if (sUTF8) { gchar *mapped = g_utf8_casefold(sUTF8, strlen(sUTF8)); if (mapped) { int mappedLength = strlen(mapped); const char *mappedBack = ConvertText(&mappedLength, mapped, mappedLength, charSetBuffer, "UTF-8", false, true); if (mappedBack && (strlen(mappedBack) == 1) && (mappedBack[0] != sCharacter[0])) { pcf->SetTranslation(sCharacter[0], mappedBack[0]); } delete []mappedBack; g_free(mapped); } } delete []sUTF8; } return pcf; } else { return new CaseFolderDBCS(charSetBuffer); } } return 0; } } std::string ScintillaGTK::CaseMapString(const std::string &s, int caseMapping) { if (s.size() == 0) return std::string(); if (caseMapping == cmSame) return s; const char *needsFree1 = 0; // Must be freed with delete [] const char *charSetBuffer = CharacterSetID(); const char *sUTF8 = s.c_str(); int rangeBytes = s.size(); int convertedLength = rangeBytes; // Change text to UTF-8 if (!IsUnicodeMode()) { // Need to convert if (*charSetBuffer) { sUTF8 = ConvertText(&convertedLength, const_cast<char *>(s.c_str()), rangeBytes, "UTF-8", charSetBuffer, false); needsFree1 = sUTF8; } } gchar *mapped; // Must be freed with g_free if (caseMapping == cmUpper) { mapped = g_utf8_strup(sUTF8, convertedLength); } else { mapped = g_utf8_strdown(sUTF8, convertedLength); } int mappedLength = strlen(mapped); char *mappedBack = mapped; char *needsFree2 = 0; // Must be freed with delete [] if (!IsUnicodeMode()) { if (*charSetBuffer) { mappedBack = ConvertText(&mappedLength, mapped, mappedLength, charSetBuffer, "UTF-8", false); needsFree2 = mappedBack; } } std::string ret(mappedBack, mappedLength); g_free(mapped); delete []needsFree1; delete []needsFree2; return ret; } int ScintillaGTK::KeyDefault(int key, int modifiers) { // Pass up to container in case it is an accelerator NotifyKey(key, modifiers); return 0; } void ScintillaGTK::CopyToClipboard(const SelectionText &selectedText) { SelectionText *clipText = new SelectionText(); clipText->Copy(selectedText); StoreOnClipboard(clipText); } void ScintillaGTK::Copy() { if (!sel.Empty()) { SelectionText *clipText = new SelectionText(); CopySelectionRange(clipText); StoreOnClipboard(clipText); #if PLAT_GTK_WIN32 if (sel.IsRectangular()) { ::OpenClipboard(NULL); ::SetClipboardData(cfColumnSelect, 0); ::CloseClipboard(); } #endif } } void ScintillaGTK::Paste() { atomSought = atomUTF8; gtk_selection_convert(GTK_WIDGET(PWidget(wMain)), atomClipboard, atomSought, GDK_CURRENT_TIME); } void ScintillaGTK::CreateCallTipWindow(PRectangle rc) { if (!ct.wCallTip.Created()) { ct.wCallTip = gtk_window_new(GTK_WINDOW_POPUP); ct.wDraw = gtk_drawing_area_new(); GtkWidget *widcdrw = PWidget(ct.wDraw); // // No code inside the G_OBJECT macro gtk_container_add(GTK_CONTAINER(PWidget(ct.wCallTip)), widcdrw); #if GTK_CHECK_VERSION(3,0,0) g_signal_connect(G_OBJECT(widcdrw), "draw", G_CALLBACK(ScintillaGTK::DrawCT), &ct); #else g_signal_connect(G_OBJECT(widcdrw), "expose_event", G_CALLBACK(ScintillaGTK::ExposeCT), &ct); #endif g_signal_connect(G_OBJECT(widcdrw), "button_press_event", G_CALLBACK(ScintillaGTK::PressCT), static_cast<void *>(this)); gtk_widget_set_events(widcdrw, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK); } gtk_widget_set_size_request(PWidget(ct.wDraw), rc.Width(), rc.Height()); ct.wDraw.Show(); if (PWindow(ct.wCallTip)) { gdk_window_resize(PWindow(ct.wCallTip), rc.Width(), rc.Height()); } } void ScintillaGTK::AddToPopUp(const char *label, int cmd, bool enabled) { GtkWidget *menuItem; if (label[0]) menuItem = gtk_menu_item_new_with_label(label); else menuItem = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(popup.GetID()), menuItem); g_object_set_data(G_OBJECT(menuItem), "CmdNum", reinterpret_cast<void *>(cmd)); g_signal_connect(G_OBJECT(menuItem),"activate", G_CALLBACK(PopUpCB), this); if (cmd) { if (menuItem) gtk_widget_set_sensitive(menuItem, enabled); } } bool ScintillaGTK::OwnPrimarySelection() { return ((gdk_selection_owner_get(GDK_SELECTION_PRIMARY) == PWindow(wMain)) && (PWindow(wMain) != NULL)); } void ScintillaGTK::ClaimSelection() { // X Windows has a 'primary selection' as well as the clipboard. // Whenever the user selects some text, we become the primary selection if (!sel.Empty() && IS_WIDGET_REALIZED(GTK_WIDGET(PWidget(wMain)))) { primarySelection = true; gtk_selection_owner_set(GTK_WIDGET(PWidget(wMain)), GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME); primary.Free(); } else if (OwnPrimarySelection()) { primarySelection = true; if (primary.s == NULL) gtk_selection_owner_set(NULL, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME); } else { primarySelection = false; primary.Free(); } } #if GTK_CHECK_VERSION(3,0,0) static const guchar *DataOfGSD(GtkSelectionData *sd) { return gtk_selection_data_get_data(sd); } static gint LengthOfGSD(GtkSelectionData *sd) { return gtk_selection_data_get_length(sd); } static GdkAtom TypeOfGSD(GtkSelectionData *sd) { return gtk_selection_data_get_data_type(sd); } static GdkAtom SelectionOfGSD(GtkSelectionData *sd) { return gtk_selection_data_get_selection(sd); } #else static const guchar *DataOfGSD(GtkSelectionData *sd) { return sd->data; } static gint LengthOfGSD(GtkSelectionData *sd) { return sd->length; } static GdkAtom TypeOfGSD(GtkSelectionData *sd) { return sd->type; } static GdkAtom SelectionOfGSD(GtkSelectionData *sd) { return sd->selection; } #endif // Detect rectangular text, convert line ends to current mode, convert from or to UTF-8 void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, SelectionText &selText) { const char *data = reinterpret_cast<const char *>(DataOfGSD(selectionData)); int len = LengthOfGSD(selectionData); GdkAtom selectionTypeData = TypeOfGSD(selectionData); // Return empty string if selection is not a string if ((selectionTypeData != GDK_TARGET_STRING) && (selectionTypeData != atomUTF8)) { char *empty = new char[1]; empty[0] = '\0'; selText.Set(empty, 0, SC_CP_UTF8, 0, false, false); return; } // Check for "\n\0" ending to string indicating that selection is rectangular bool isRectangular; #if PLAT_GTK_WIN32 isRectangular = ::IsClipboardFormatAvailable(cfColumnSelect) != 0; #else isRectangular = ((len > 2) && (data[len - 1] == 0 && data[len - 2] == '\n')); if (isRectangular) len--; // Forget the extra '\0' #endif char *dest; if (selectionTypeData == GDK_TARGET_STRING) { dest = Document::TransformLineEnds(&len, data, len, pdoc->eolMode); if (IsUnicodeMode()) { // Unknown encoding so assume in Latin1 char *destPrevious = dest; dest = UTF8FromLatin1(dest, len); selText.Set(dest, len, SC_CP_UTF8, 0, selText.rectangular, false); delete []destPrevious; } else { // Assume buffer is in same encoding as selection selText.Set(dest, len, pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, isRectangular, false); } } else { // UTF-8 dest = Document::TransformLineEnds(&len, data, len, pdoc->eolMode); selText.Set(dest, len, SC_CP_UTF8, 0, isRectangular, false); const char *charSetBuffer = CharacterSetID(); if (!IsUnicodeMode() && *charSetBuffer) { // Convert to locale dest = ConvertText(&len, selText.s, selText.len, charSetBuffer, "UTF-8", true); selText.Set(dest, len, pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, selText.rectangular, false); } } } void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) { try { if ((SelectionOfGSD(selection_data) == atomClipboard) || (SelectionOfGSD(selection_data) == GDK_SELECTION_PRIMARY)) { if ((atomSought == atomUTF8) && (LengthOfGSD(selection_data) <= 0)) { atomSought = atomString; gtk_selection_convert(GTK_WIDGET(PWidget(wMain)), SelectionOfGSD(selection_data), atomSought, GDK_CURRENT_TIME); } else if ((LengthOfGSD(selection_data) > 0) && ((TypeOfGSD(selection_data) == GDK_TARGET_STRING) || (TypeOfGSD(selection_data) == atomUTF8))) { SelectionText selText; GetGtkSelectionText(selection_data, selText); UndoGroup ug(pdoc); if (SelectionOfGSD(selection_data) != GDK_SELECTION_PRIMARY) { ClearSelection(multiPasteMode == SC_MULTIPASTE_EACH); } SelectionPosition selStart = sel.IsRectangular() ? sel.Rectangular().Start() : sel.Range(sel.Main()).Start(); if (selText.rectangular) { PasteRectangular(selStart, selText.s, selText.len); } else { InsertPaste(selStart, selText.s, selText.len); } EnsureCaretVisible(); } } // else fprintf(stderr, "Target non string %d %d\n", (int)(selection_data->type), // (int)(atomUTF8)); Redraw(); } catch (...) { errorStatus = SC_STATUS_FAILURE; } } void ScintillaGTK::ReceivedDrop(GtkSelectionData *selection_data) { dragWasDropped = true; if (TypeOfGSD(selection_data) == atomUriList || TypeOfGSD(selection_data) == atomDROPFILES_DND) { char *ptr = new char[LengthOfGSD(selection_data) + 1]; ptr[LengthOfGSD(selection_data)] = '\0'; memcpy(ptr, DataOfGSD(selection_data), LengthOfGSD(selection_data)); NotifyURIDropped(ptr); delete []ptr; } else if ((TypeOfGSD(selection_data) == GDK_TARGET_STRING) || (TypeOfGSD(selection_data) == atomUTF8)) { if (TypeOfGSD(selection_data) > 0) { SelectionText selText; GetGtkSelectionText(selection_data, selText); DropAt(posDrop, selText.s, false, selText.rectangular); } } else if (LengthOfGSD(selection_data) > 0) { //~ fprintf(stderr, "ReceivedDrop other %p\n", static_cast<void *>(selection_data->type)); } Redraw(); } void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, SelectionText *text) { #if PLAT_GTK_WIN32 // GDK on Win32 expands any \n into \r\n, so make a copy of // the clip text now with newlines converted to \n. Use { } to hide symbols // from code below SelectionText *newline_normalized = NULL; { int tmpstr_len; char *tmpstr = Document::TransformLineEnds(&tmpstr_len, text->s, text->len, SC_EOL_LF); newline_normalized = new SelectionText(); newline_normalized->Set(tmpstr, tmpstr_len, SC_CP_UTF8, 0, text->rectangular, false); text = newline_normalized; } #endif // Convert text to utf8 if it isn't already SelectionText *converted = 0; if ((text->codePage != SC_CP_UTF8) && (info == TARGET_UTF8_STRING)) { const char *charSet = ::CharacterSetID(text->characterSet); if (*charSet) { int new_len; char* tmputf = ConvertText(&new_len, text->s, text->len, "UTF-8", charSet, false); converted = new SelectionText(); converted->Set(tmputf, new_len, SC_CP_UTF8, 0, text->rectangular, false); text = converted; } } // Here is a somewhat evil kludge. // As I can not work out how to store data on the clipboard in multiple formats // and need some way to mark the clipping as being stream or rectangular, // the terminating \0 is included in the length for rectangular clippings. // All other tested aplications behave benignly by ignoring the \0. // The #if is here because on Windows cfColumnSelect clip entry is used // instead as standard indicator of rectangularness (so no need to kludge) const char *textData = text->s ? text->s : ""; int len = strlen(textData); #if PLAT_GTK_WIN32 == 0 if (text->rectangular) len++; #endif if (info == TARGET_UTF8_STRING) { gtk_selection_data_set_text(selection_data, textData, len); } else { gtk_selection_data_set(selection_data, static_cast<GdkAtom>(GDK_SELECTION_TYPE_STRING), 8, reinterpret_cast<const unsigned char *>(textData), len); } delete converted; #if PLAT_GTK_WIN32 delete newline_normalized; #endif } void ScintillaGTK::StoreOnClipboard(SelectionText *clipText) { GtkClipboard *clipBoard = gtk_widget_get_clipboard(GTK_WIDGET(PWidget(wMain)), atomClipboard); if (clipBoard == NULL) // Occurs if widget isn't in a toplevel return; if (gtk_clipboard_set_with_data(clipBoard, clipboardCopyTargets, nClipboardCopyTargets, ClipboardGetSelection, ClipboardClearSelection, clipText)) { gtk_clipboard_set_can_store(clipBoard, clipboardCopyTargets, nClipboardCopyTargets); } } void ScintillaGTK::ClipboardGetSelection(GtkClipboard *, GtkSelectionData *selection_data, guint info, void *data) { GetSelection(selection_data, info, static_cast<SelectionText*>(data)); } void ScintillaGTK::ClipboardClearSelection(GtkClipboard *, void *data) { SelectionText *obj = static_cast<SelectionText*>(data); delete obj; } void ScintillaGTK::UnclaimSelection(GdkEventSelection *selection_event) { try { //Platform::DebugPrintf("UnclaimSelection\n"); if (selection_event->selection == GDK_SELECTION_PRIMARY) { //Platform::DebugPrintf("UnclaimPrimarySelection\n"); if (!OwnPrimarySelection()) { primary.Free(); primarySelection = false; FullPaint(); } } } catch (...) { errorStatus = SC_STATUS_FAILURE; } } void ScintillaGTK::Resize(int width, int height) { //Platform::DebugPrintf("Resize %d %d\n", width, height); //printf("Resize %d %d\n", width, height); // Not always needed, but some themes can have different sizes of scrollbars #if GTK_CHECK_VERSION(3,0,0) GtkRequisition requisition; gtk_widget_get_requisition(PWidget(scrollbarv), &requisition); scrollBarWidth = requisition.width; gtk_widget_get_requisition(PWidget(scrollbarh), &requisition); scrollBarHeight = requisition.height; #else scrollBarWidth = GTK_WIDGET(PWidget(scrollbarv))->requisition.width; scrollBarHeight = GTK_WIDGET(PWidget(scrollbarh))->requisition.height; #endif // These allocations should never produce negative sizes as they would wrap around to huge // unsigned numbers inside GTK+ causing warnings. bool showSBHorizontal = horizontalScrollBarVisible && (wrapState == eWrapNone); int horizontalScrollBarHeight = scrollBarHeight; if (!showSBHorizontal) horizontalScrollBarHeight = 0; GtkAllocation alloc; if (showSBHorizontal) { gtk_widget_show(GTK_WIDGET(PWidget(scrollbarh))); alloc.x = 0; alloc.y = height - scrollBarHeight; alloc.width = Platform::Maximum(1, width - scrollBarWidth); alloc.height = horizontalScrollBarHeight; gtk_widget_size_allocate(GTK_WIDGET(PWidget(scrollbarh)), &alloc); } else { gtk_widget_hide(GTK_WIDGET(PWidget(scrollbarh))); } if (verticalScrollBarVisible) { gtk_widget_show(GTK_WIDGET(PWidget(scrollbarv))); alloc.x = width - scrollBarWidth; alloc.y = 0; alloc.width = scrollBarWidth; alloc.height = Platform::Maximum(1, height - scrollBarHeight); if (!showSBHorizontal) alloc.height += scrollBarWidth-1; gtk_widget_size_allocate(GTK_WIDGET(PWidget(scrollbarv)), &alloc); } else { gtk_widget_hide(GTK_WIDGET(PWidget(scrollbarv))); } if (IS_WIDGET_MAPPED(PWidget(wMain))) { ChangeSize(); } alloc.x = 0; alloc.y = 0; alloc.width = Platform::Maximum(1, width - scrollBarWidth); alloc.height = Platform::Maximum(1, height - scrollBarHeight); if (!showSBHorizontal) alloc.height += scrollBarHeight; if (!verticalScrollBarVisible) alloc.width += scrollBarWidth; gtk_widget_size_allocate(GTK_WIDGET(PWidget(wText)), &alloc); } static void SetAdjustmentValue(GtkAdjustment *object, int value) { GtkAdjustment *adjustment = GTK_ADJUSTMENT(object); #if GTK_CHECK_VERSION(3,0,0) int maxValue = static_cast<int>( gtk_adjustment_get_upper(adjustment) - gtk_adjustment_get_page_size(adjustment)); #else int maxValue = static_cast<int>( adjustment->upper - adjustment->page_size); #endif if (value > maxValue) value = maxValue; if (value < 0) value = 0; gtk_adjustment_set_value(adjustment, value); } static int modifierTranslated(int sciModifier) { switch (sciModifier) { case SCMOD_SHIFT: return GDK_SHIFT_MASK; case SCMOD_CTRL: return GDK_CONTROL_MASK; case SCMOD_ALT: return GDK_MOD1_MASK; case SCMOD_SUPER: return GDK_MOD4_MASK; default: return 0; } } gint ScintillaGTK::PressThis(GdkEventButton *event) { try { //Platform::DebugPrintf("Press %x time=%d state = %x button = %x\n",this,event->time, event->state, event->button); // Do not use GTK+ double click events as Scintilla has its own double click detection if (event->type != GDK_BUTTON_PRESS) return FALSE; evbtn = *event; Point pt; pt.x = int(event->x); pt.y = int(event->y); PRectangle rcClient = GetClientRectangle(); //Platform::DebugPrintf("Press %0d,%0d in %0d,%0d %0d,%0d\n", // pt.x, pt.y, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); if ((pt.x > rcClient.right) || (pt.y > rcClient.bottom)) { Platform::DebugPrintf("Bad location\n"); return FALSE; } bool ctrl = (event->state & GDK_CONTROL_MASK) != 0; gtk_widget_grab_focus(PWidget(wMain)); if (event->button == 1) { // On X, instead of sending literal modifiers use the user specified // modifier, defaulting to control instead of alt. // This is because most X window managers grab alt + click for moving ButtonDown(pt, event->time, (event->state & GDK_SHIFT_MASK) != 0, (event->state & GDK_CONTROL_MASK) != 0, (event->state & modifierTranslated(rectangularSelectionModifier)) != 0); } else if (event->button == 2) { // Grab the primary selection if it exists SelectionPosition pos = SPositionFromLocation(pt, false, false, UserVirtualSpace()); if (OwnPrimarySelection() && primary.s == NULL) CopySelectionRange(&primary); sel.Clear(); SetSelection(pos, pos); atomSought = atomUTF8; gtk_selection_convert(GTK_WIDGET(PWidget(wMain)), GDK_SELECTION_PRIMARY, atomSought, event->time); } else if (event->button == 3) { if (!PointInSelection(pt)) SetEmptySelection(PositionFromLocation(pt)); if (displayPopupMenu) { // PopUp menu // Convert to screen int ox = 0; int oy = 0; gdk_window_get_origin(PWindow(wMain), &ox, &oy); ContextMenu(Point(pt.x + ox, pt.y + oy)); } else { return FALSE; } } else if (event->button == 4) { // Wheel scrolling up (only GTK 1.x does it this way) if (ctrl) SetAdjustmentValue(adjustmenth, (xOffset / 2) - 6); else SetAdjustmentValue(adjustmentv, topLine - 3); } else if (event->button == 5) { // Wheel scrolling down (only GTK 1.x does it this way) if (ctrl) SetAdjustmentValue(adjustmenth, (xOffset / 2) + 6); else SetAdjustmentValue(adjustmentv, topLine + 3); } } catch (...) { errorStatus = SC_STATUS_FAILURE; } return TRUE; } gint ScintillaGTK::Press(GtkWidget *widget, GdkEventButton *event) { if (event->window != WindowFromWidget(widget)) return FALSE; ScintillaGTK *sciThis = ScintillaFromWidget(widget); return sciThis->PressThis(event); } gint ScintillaGTK::MouseRelease(GtkWidget *widget, GdkEventButton *event) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); try { //Platform::DebugPrintf("Release %x %d %d\n",sciThis,event->time,event->state); if (!sciThis->HaveMouseCapture()) return FALSE; if (event->button == 1) { Point pt; pt.x = int(event->x); pt.y = int(event->y); //Platform::DebugPrintf("Up %x %x %d %d %d\n", // sciThis,event->window,event->time, pt.x, pt.y); if (event->window != PWindow(sciThis->wMain)) // If mouse released on scroll bar then the position is relative to the // scrollbar, not the drawing window so just repeat the most recent point. pt = sciThis->ptMouseLast; sciThis->ButtonUp(pt, event->time, (event->state & 4) != 0); } } catch (...) { sciThis->errorStatus = SC_STATUS_FAILURE; } return FALSE; } // win32gtk and GTK >= 2 use SCROLL_* events instead of passing the // button4/5/6/7 events to the GTK app gint ScintillaGTK::ScrollEvent(GtkWidget *widget, GdkEventScroll *event) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); try { if (widget == NULL || event == NULL) return FALSE; // Compute amount and direction to scroll (even tho on win32 there is // intensity of scrolling info in the native message, gtk doesn't // support this so we simulate similarly adaptive scrolling) // Note that this is disabled on OS X (Darwin) where the X11 server already has // and adaptive scrolling algorithm that fights with this one int cLineScroll; #if defined(__MWERKS__) || defined(__APPLE_CPP__) || defined(__APPLE_CC__) cLineScroll = sciThis->linesPerScroll; if (cLineScroll == 0) cLineScroll = 4; sciThis->wheelMouseIntensity = cLineScroll; #else int timeDelta = 1000000; GTimeVal curTime; g_get_current_time(&curTime); if (curTime.tv_sec == sciThis->lastWheelMouseTime.tv_sec) timeDelta = curTime.tv_usec - sciThis->lastWheelMouseTime.tv_usec; else if (curTime.tv_sec == sciThis->lastWheelMouseTime.tv_sec + 1) timeDelta = 1000000 + (curTime.tv_usec - sciThis->lastWheelMouseTime.tv_usec); if ((event->direction == sciThis->lastWheelMouseDirection) && (timeDelta < 250000)) { if (sciThis->wheelMouseIntensity < 12) sciThis->wheelMouseIntensity++; cLineScroll = sciThis->wheelMouseIntensity; } else { cLineScroll = sciThis->linesPerScroll; if (cLineScroll == 0) cLineScroll = 4; sciThis->wheelMouseIntensity = cLineScroll; } #endif if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_LEFT) { cLineScroll *= -1; } g_get_current_time(&sciThis->lastWheelMouseTime); sciThis->lastWheelMouseDirection = event->direction; // Note: Unpatched versions of win32gtk don't set the 'state' value so // only regular scrolling is supported there. Also, unpatched win32gtk // issues spurious button 2 mouse events during wheeling, which can cause // problems (a patch for both was submitted by archaeopteryx.com on 13Jun2001) // Data zoom not supported if (event->state & GDK_SHIFT_MASK) { return FALSE; } #if GTK_CHECK_VERSION(3,4,0) // Smooth scrolling not supported if (event->direction == GDK_SCROLL_SMOOTH) { return FALSE; } #endif // Horizontal scrolling if (event->direction == GDK_SCROLL_LEFT || event->direction == GDK_SCROLL_RIGHT) { sciThis->HorizontalScrollTo(sciThis->xOffset + cLineScroll); // Text font size zoom } else if (event->state & GDK_CONTROL_MASK) { if (cLineScroll < 0) { sciThis->KeyCommand(SCI_ZOOMIN); } else { sciThis->KeyCommand(SCI_ZOOMOUT); } // Regular scrolling } else { sciThis->ScrollTo(sciThis->topLine + cLineScroll); } return TRUE; } catch (...) { sciThis->errorStatus = SC_STATUS_FAILURE; } return FALSE; } gint ScintillaGTK::Motion(GtkWidget *widget, GdkEventMotion *event) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); try { //Platform::DebugPrintf("Motion %x %d\n",sciThis,event->time); if (event->window != WindowFromWidget(widget)) return FALSE; int x = 0; int y = 0; GdkModifierType state; if (event->is_hint) { #if GTK_CHECK_VERSION(3,0,0) gdk_window_get_device_position(event->window, event->device, &x, &y, &state); #else gdk_window_get_pointer(event->window, &x, &y, &state); #endif } else { x = static_cast<int>(event->x); y = static_cast<int>(event->y); state = static_cast<GdkModifierType>(event->state); } //Platform::DebugPrintf("Move %x %x %d %c %d %d\n", // sciThis,event->window,event->time,event->is_hint? 'h' :'.', x, y); Point pt(x, y); sciThis->ButtonMove(pt); } catch (...) { sciThis->errorStatus = SC_STATUS_FAILURE; } return FALSE; } // Map the keypad keys to their equivalent functions static int KeyTranslate(int keyIn) { switch (keyIn) { #if GTK_CHECK_VERSION(3,0,0) case GDK_KEY_ISO_Left_Tab: return SCK_TAB; case GDK_KEY_KP_Down: return SCK_DOWN; case GDK_KEY_KP_Up: return SCK_UP; case GDK_KEY_KP_Left: return SCK_LEFT; case GDK_KEY_KP_Right: return SCK_RIGHT; case GDK_KEY_KP_Home: return SCK_HOME; case GDK_KEY_KP_End: return SCK_END; case GDK_KEY_KP_Page_Up: return SCK_PRIOR; case GDK_KEY_KP_Page_Down: return SCK_NEXT; case GDK_KEY_KP_Delete: return SCK_DELETE; case GDK_KEY_KP_Insert: return SCK_INSERT; case GDK_KEY_KP_Enter: return SCK_RETURN; case GDK_KEY_Down: return SCK_DOWN; case GDK_KEY_Up: return SCK_UP; case GDK_KEY_Left: return SCK_LEFT; case GDK_KEY_Right: return SCK_RIGHT; case GDK_KEY_Home: return SCK_HOME; case GDK_KEY_End: return SCK_END; case GDK_KEY_Page_Up: return SCK_PRIOR; case GDK_KEY_Page_Down: return SCK_NEXT; case GDK_KEY_Delete: return SCK_DELETE; case GDK_KEY_Insert: return SCK_INSERT; case GDK_KEY_Escape: return SCK_ESCAPE; case GDK_KEY_BackSpace: return SCK_BACK; case GDK_KEY_Tab: return SCK_TAB; case GDK_KEY_Return: return SCK_RETURN; case GDK_KEY_KP_Add: return SCK_ADD; case GDK_KEY_KP_Subtract: return SCK_SUBTRACT; case GDK_KEY_KP_Divide: return SCK_DIVIDE; case GDK_KEY_Super_L: return SCK_WIN; case GDK_KEY_Super_R: return SCK_RWIN; case GDK_KEY_Menu: return SCK_MENU; #else case GDK_ISO_Left_Tab: return SCK_TAB; case GDK_KP_Down: return SCK_DOWN; case GDK_KP_Up: return SCK_UP; case GDK_KP_Left: return SCK_LEFT; case GDK_KP_Right: return SCK_RIGHT; case GDK_KP_Home: return SCK_HOME; case GDK_KP_End: return SCK_END; case GDK_KP_Page_Up: return SCK_PRIOR; case GDK_KP_Page_Down: return SCK_NEXT; case GDK_KP_Delete: return SCK_DELETE; case GDK_KP_Insert: return SCK_INSERT; case GDK_KP_Enter: return SCK_RETURN; case GDK_Down: return SCK_DOWN; case GDK_Up: return SCK_UP; case GDK_Left: return SCK_LEFT; case GDK_Right: return SCK_RIGHT; case GDK_Home: return SCK_HOME; case GDK_End: return SCK_END; case GDK_Page_Up: return SCK_PRIOR; case GDK_Page_Down: return SCK_NEXT; case GDK_Delete: return SCK_DELETE; case GDK_Insert: return SCK_INSERT; case GDK_Escape: return SCK_ESCAPE; case GDK_BackSpace: return SCK_BACK; case GDK_Tab: return SCK_TAB; case GDK_Return: return SCK_RETURN; case GDK_KP_Add: return SCK_ADD; case GDK_KP_Subtract: return SCK_SUBTRACT; case GDK_KP_Divide: return SCK_DIVIDE; case GDK_Super_L: return SCK_WIN; case GDK_Super_R: return SCK_RWIN; case GDK_Menu: return SCK_MENU; #endif default: return keyIn; } } gboolean ScintillaGTK::KeyThis(GdkEventKey *event) { try { //fprintf(stderr, "SC-key: %d %x [%s]\n", // event->keyval, event->state, (event->length > 0) ? event->string : "empty"); if (gtk_im_context_filter_keypress(im_context, event)) { return 1; } if (!event->keyval) { return true; } bool shift = (event->state & GDK_SHIFT_MASK) != 0; bool ctrl = (event->state & GDK_CONTROL_MASK) != 0; bool alt = (event->state & GDK_MOD1_MASK) != 0; guint key = event->keyval; if ((ctrl || alt) && (key < 128)) key = toupper(key); #if GTK_CHECK_VERSION(3,0,0) else if (!ctrl && (key >= GDK_KEY_KP_Multiply && key <= GDK_KEY_KP_9)) #else else if (!ctrl && (key >= GDK_KP_Multiply && key <= GDK_KP_9)) #endif key &= 0x7F; // Hack for keys over 256 and below command keys but makes Hungarian work. // This will have to change for Unicode else if (key >= 0xFE00) key = KeyTranslate(key); bool consumed = false; #if !(PLAT_GTK_MACOSX) bool added = KeyDown(key, shift, ctrl, alt, &consumed) != 0; #else bool meta = ctrl; ctrl = (event->state & GDK_META_MASK) != 0; bool added = KeyDownWithModifiers(key, (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | (alt ? SCI_ALT : 0) | (meta ? SCI_META : 0), &consumed) != 0; #endif if (!consumed) consumed = added; //fprintf(stderr, "SK-key: %d %x %x\n",event->keyval, event->state, consumed); if (event->keyval == 0xffffff && event->length > 0) { ClearSelection(); if (pdoc->InsertCString(CurrentPosition(), event->string)) { MovePositionTo(CurrentPosition() + event->length); } } return consumed; } catch (...) { errorStatus = SC_STATUS_FAILURE; } return FALSE; } gboolean ScintillaGTK::KeyPress(GtkWidget *widget, GdkEventKey *event) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); return sciThis->KeyThis(event); } gboolean ScintillaGTK::KeyRelease(GtkWidget *widget, GdkEventKey *event) { //Platform::DebugPrintf("SC-keyrel: %d %x %3s\n",event->keyval, event->state, event->string); ScintillaGTK *sciThis = ScintillaFromWidget(widget); if (gtk_im_context_filter_keypress(sciThis->im_context, event)) { return TRUE; } return FALSE; } #if GTK_CHECK_VERSION(3,0,0) gboolean ScintillaGTK::DrawPreeditThis(GtkWidget *widget, cairo_t *cr) { try { gchar *str; gint cursor_pos; PangoAttrList *attrs; gtk_im_context_get_preedit_string(im_context, &str, &attrs, &cursor_pos); PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), str); pango_layout_set_attributes(layout, attrs); cairo_move_to(cr, 0, 0); pango_cairo_show_layout(cr, layout); g_free(str); pango_attr_list_unref(attrs); g_object_unref(layout); } catch (...) { errorStatus = SC_STATUS_FAILURE; } return TRUE; } gboolean ScintillaGTK::DrawPreedit(GtkWidget *widget, cairo_t *cr, ScintillaGTK *sciThis) { return sciThis->DrawPreeditThis(widget, cr); } #else gboolean ScintillaGTK::ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose) { try { gchar *str; gint cursor_pos; PangoAttrList *attrs; gtk_im_context_get_preedit_string(im_context, &str, &attrs, &cursor_pos); PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), str); pango_layout_set_attributes(layout, attrs); cairo_t *context = gdk_cairo_create(reinterpret_cast<GdkDrawable *>(WindowFromWidget(widget))); cairo_move_to(context, 0, 0); pango_cairo_show_layout(context, layout); cairo_destroy(context); g_free(str); pango_attr_list_unref(attrs); g_object_unref(layout); } catch (...) { errorStatus = SC_STATUS_FAILURE; } return TRUE; } gboolean ScintillaGTK::ExposePreedit(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis) { return sciThis->ExposePreeditThis(widget, ose); } #endif void ScintillaGTK::CommitThis(char *utfVal) { try { //~ fprintf(stderr, "Commit '%s'\n", utfVal); if (IsUnicodeMode()) { AddCharUTF(utfVal, strlen(utfVal)); } else { const char *source = CharacterSetID(); if (*source) { Converter conv(source, "UTF-8", true); if (conv) { char localeVal[4] = "\0\0\0"; char *pin = utfVal; size_t inLeft = strlen(utfVal); char *pout = localeVal; size_t outLeft = sizeof(localeVal); size_t conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft); if (conversions != ((size_t)(-1))) { *pout = '\0'; for (int i = 0; localeVal[i]; i++) { AddChar(localeVal[i]); } } else { fprintf(stderr, "Conversion failed '%s'\n", utfVal); } } } } } catch (...) { errorStatus = SC_STATUS_FAILURE; } } void ScintillaGTK::Commit(GtkIMContext *, char *str, ScintillaGTK *sciThis) { sciThis->CommitThis(str); } void ScintillaGTK::PreeditChangedThis() { try { gchar *str; PangoAttrList *attrs; gint cursor_pos; gtk_im_context_get_preedit_string(im_context, &str, &attrs, &cursor_pos); if (strlen(str) > 0) { PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), str); pango_layout_set_attributes(layout, attrs); gint w, h; pango_layout_get_pixel_size(layout, &w, &h); g_object_unref(layout); gint x, y; gdk_window_get_origin(PWindow(wText), &x, &y); Point pt = PointMainCaret(); if (pt.x < 0) pt.x = 0; if (pt.y < 0) pt.y = 0; gtk_window_move(GTK_WINDOW(PWidget(wPreedit)), x + pt.x, y + pt.y); gtk_window_resize(GTK_WINDOW(PWidget(wPreedit)), w, h); gtk_widget_show(PWidget(wPreedit)); gtk_widget_queue_draw_area(PWidget(wPreeditDraw), 0, 0, w, h); } else { gtk_widget_hide(PWidget(wPreedit)); } g_free(str); pango_attr_list_unref(attrs); } catch (...) { errorStatus = SC_STATUS_FAILURE; } } void ScintillaGTK::PreeditChanged(GtkIMContext *, ScintillaGTK *sciThis) { sciThis->PreeditChangedThis(); } void ScintillaGTK::StyleSetText(GtkWidget *widget, GtkStyle *, void*) { RealizeText(widget, NULL); } void ScintillaGTK::RealizeText(GtkWidget *widget, void*) { // Set NULL background to avoid automatic clearing so Scintilla responsible for all drawing if (WindowFromWidget(widget)) { #if GTK_CHECK_VERSION(3,0,0) gdk_window_set_background_pattern(WindowFromWidget(widget), NULL); #else gdk_window_set_back_pixmap(WindowFromWidget(widget), NULL, FALSE); #endif } } void ScintillaGTK::Destroy(GObject *object) { try { ScintillaObject *scio = reinterpret_cast<ScintillaObject *>(object); // This avoids a double destruction if (!scio->pscin) return; ScintillaGTK *sciThis = reinterpret_cast<ScintillaGTK *>(scio->pscin); //Platform::DebugPrintf("Destroying %x %x\n", sciThis, object); sciThis->Finalise(); delete sciThis; scio->pscin = 0; } catch (...) { // Its dead so nowhere to save the status } } #if GTK_CHECK_VERSION(3,0,0) gboolean ScintillaGTK::DrawTextThis(cairo_t *cr) { try { paintState = painting; rcPaint = GetClientRectangle(); PLATFORM_ASSERT(rgnUpdate == NULL); rgnUpdate = cairo_copy_clip_rectangle_list(cr); if (rgnUpdate && rgnUpdate->status != CAIRO_STATUS_SUCCESS) { // If not successful then ignore fprintf(stderr, "DrawTextThis failed to copy update region %d [%d]\n", rgnUpdate->status, rgnUpdate->num_rectangles); cairo_rectangle_list_destroy(rgnUpdate); rgnUpdate = 0; } double x1, y1, x2, y2; cairo_clip_extents(cr, &x1, &y1, &x2, &y2); rcPaint.left = x1; rcPaint.top = y1; rcPaint.right = x2; rcPaint.bottom = y2; PRectangle rcClient = GetClientRectangle(); paintingAllText = rcPaint.Contains(rcClient); Surface *surfaceWindow = Surface::Allocate(SC_TECHNOLOGY_DEFAULT); if (surfaceWindow) { surfaceWindow->Init(cr, PWidget(wText)); Paint(surfaceWindow, rcPaint); surfaceWindow->Release(); delete surfaceWindow; } if (paintState == paintAbandoned) { // Painting area was insufficient to cover new styling or brace highlight positions FullPaint(); } paintState = notPainting; if (rgnUpdate) { cairo_rectangle_list_destroy(rgnUpdate); } rgnUpdate = 0; paintState = notPainting; } catch (...) { errorStatus = SC_STATUS_FAILURE; } return FALSE; } gboolean ScintillaGTK::DrawText(GtkWidget *, cairo_t *cr, ScintillaGTK *sciThis) { return sciThis->DrawTextThis(cr); } gboolean ScintillaGTK::DrawThis(cairo_t *cr) { try { gtk_container_propagate_draw( GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarh), cr); gtk_container_propagate_draw( GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarv), cr); } catch (...) { errorStatus = SC_STATUS_FAILURE; } return FALSE; } gboolean ScintillaGTK::DrawMain(GtkWidget *widget, cairo_t *cr) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); return sciThis->DrawThis(cr); } #else gboolean ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *ose) { try { paintState = painting; rcPaint.left = ose->area.x; rcPaint.top = ose->area.y; rcPaint.right = ose->area.x + ose->area.width; rcPaint.bottom = ose->area.y + ose->area.height; PLATFORM_ASSERT(rgnUpdate == NULL); rgnUpdate = gdk_region_copy(ose->region); PRectangle rcClient = GetClientRectangle(); paintingAllText = rcPaint.Contains(rcClient); Surface *surfaceWindow = Surface::Allocate(SC_TECHNOLOGY_DEFAULT); if (surfaceWindow) { cairo_t *cr = gdk_cairo_create(PWindow(wText)); surfaceWindow->Init(cr, PWidget(wText)); Paint(surfaceWindow, rcPaint); surfaceWindow->Release(); delete surfaceWindow; cairo_destroy(cr); } if (paintState == paintAbandoned) { // Painting area was insufficient to cover new styling or brace highlight positions FullPaint(); } paintState = notPainting; if (rgnUpdate) { gdk_region_destroy(rgnUpdate); } rgnUpdate = 0; } catch (...) { errorStatus = SC_STATUS_FAILURE; } return FALSE; } gboolean ScintillaGTK::ExposeText(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis) { return sciThis->ExposeTextThis(widget, ose); } gboolean ScintillaGTK::ExposeMain(GtkWidget *widget, GdkEventExpose *ose) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); //Platform::DebugPrintf("Expose Main %0d,%0d %0d,%0d\n", //ose->area.x, ose->area.y, ose->area.width, ose->area.height); return sciThis->Expose(widget, ose); } gboolean ScintillaGTK::Expose(GtkWidget *, GdkEventExpose *ose) { try { //fprintf(stderr, "Expose %0d,%0d %0d,%0d\n", //ose->area.x, ose->area.y, ose->area.width, ose->area.height); // The text is painted in ExposeText gtk_container_propagate_expose( GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarh), ose); gtk_container_propagate_expose( GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarv), ose); } catch (...) { errorStatus = SC_STATUS_FAILURE; } return FALSE; } #endif void ScintillaGTK::ScrollSignal(GtkAdjustment *adj, ScintillaGTK *sciThis) { try { #if GTK_CHECK_VERSION(3,0,0) sciThis->ScrollTo(static_cast<int>(gtk_adjustment_get_value(adj)), false); #else sciThis->ScrollTo(static_cast<int>(adj->value), false); #endif } catch (...) { sciThis->errorStatus = SC_STATUS_FAILURE; } } void ScintillaGTK::ScrollHSignal(GtkAdjustment *adj, ScintillaGTK *sciThis) { try { #if GTK_CHECK_VERSION(3,0,0) sciThis->HorizontalScrollTo(static_cast<int>(gtk_adjustment_get_value(adj) * 2)); #else sciThis->HorizontalScrollTo(static_cast<int>(adj->value * 2)); #endif } catch (...) { sciThis->errorStatus = SC_STATUS_FAILURE; } } void ScintillaGTK::SelectionReceived(GtkWidget *widget, GtkSelectionData *selection_data, guint) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); //Platform::DebugPrintf("Selection received\n"); sciThis->ReceivedSelection(selection_data); } void ScintillaGTK::SelectionGet(GtkWidget *widget, GtkSelectionData *selection_data, guint info, guint) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); try { //Platform::DebugPrintf("Selection get\n"); if (SelectionOfGSD(selection_data) == GDK_SELECTION_PRIMARY) { if (sciThis->primary.s == NULL) { sciThis->CopySelectionRange(&sciThis->primary); } sciThis->GetSelection(selection_data, info, &sciThis->primary); } } catch (...) { sciThis->errorStatus = SC_STATUS_FAILURE; } } gint ScintillaGTK::SelectionClear(GtkWidget *widget, GdkEventSelection *selection_event) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); //Platform::DebugPrintf("Selection clear\n"); sciThis->UnclaimSelection(selection_event); if (GTK_WIDGET_CLASS(sciThis->parentClass)->selection_clear_event) { return GTK_WIDGET_CLASS(sciThis->parentClass)->selection_clear_event(widget, selection_event); } return TRUE; } void ScintillaGTK::DragBegin(GtkWidget *, GdkDragContext *) { //Platform::DebugPrintf("DragBegin\n"); } gboolean ScintillaGTK::DragMotionThis(GdkDragContext *context, gint x, gint y, guint dragtime) { try { Point npt(x, y); SetDragPosition(SPositionFromLocation(npt, false, false, UserVirtualSpace())); #if GTK_CHECK_VERSION(3,0,0) GdkDragAction preferredAction = gdk_drag_context_get_suggested_action(context); GdkDragAction actions = gdk_drag_context_get_actions(context); #else GdkDragAction preferredAction = context->suggested_action; GdkDragAction actions = context->actions; #endif SelectionPosition pos = SPositionFromLocation(npt); if ((inDragDrop == ddDragging) && (PositionInSelection(pos.Position()))) { // Avoid dragging selection onto itself as that produces a move // with no real effect but which creates undo actions. preferredAction = static_cast<GdkDragAction>(0); } else if (actions == static_cast<GdkDragAction> (GDK_ACTION_COPY | GDK_ACTION_MOVE)) { preferredAction = GDK_ACTION_MOVE; } gdk_drag_status(context, preferredAction, dragtime); } catch (...) { errorStatus = SC_STATUS_FAILURE; } return FALSE; } gboolean ScintillaGTK::DragMotion(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint dragtime) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); return sciThis->DragMotionThis(context, x, y, dragtime); } void ScintillaGTK::DragLeave(GtkWidget *widget, GdkDragContext * /*context*/, guint) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); try { sciThis->SetDragPosition(SelectionPosition(invalidPosition)); //Platform::DebugPrintf("DragLeave %x\n", sciThis); } catch (...) { sciThis->errorStatus = SC_STATUS_FAILURE; } } void ScintillaGTK::DragEnd(GtkWidget *widget, GdkDragContext * /*context*/) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); try { // If drag did not result in drop here or elsewhere if (!sciThis->dragWasDropped) sciThis->SetEmptySelection(sciThis->posDrag); sciThis->SetDragPosition(SelectionPosition(invalidPosition)); //Platform::DebugPrintf("DragEnd %x %d\n", sciThis, sciThis->dragWasDropped); sciThis->inDragDrop = ddNone; } catch (...) { sciThis->errorStatus = SC_STATUS_FAILURE; } } gboolean ScintillaGTK::Drop(GtkWidget *widget, GdkDragContext * /*context*/, gint, gint, guint) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); try { //Platform::DebugPrintf("Drop %x\n", sciThis); sciThis->SetDragPosition(SelectionPosition(invalidPosition)); } catch (...) { sciThis->errorStatus = SC_STATUS_FAILURE; } return FALSE; } void ScintillaGTK::DragDataReceived(GtkWidget *widget, GdkDragContext * /*context*/, gint, gint, GtkSelectionData *selection_data, guint /*info*/, guint) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); try { sciThis->ReceivedDrop(selection_data); sciThis->SetDragPosition(SelectionPosition(invalidPosition)); } catch (...) { sciThis->errorStatus = SC_STATUS_FAILURE; } } void ScintillaGTK::DragDataGet(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data, guint info, guint) { ScintillaGTK *sciThis = ScintillaFromWidget(widget); try { sciThis->dragWasDropped = true; if (!sciThis->sel.Empty()) { sciThis->GetSelection(selection_data, info, &sciThis->drag); } #if GTK_CHECK_VERSION(3,0,0) GdkDragAction action = gdk_drag_context_get_selected_action(context); #else GdkDragAction action = context->action; #endif if (action == GDK_ACTION_MOVE) { for (size_t r=0; r<sciThis->sel.Count(); r++) { if (sciThis->posDrop >= sciThis->sel.Range(r).Start()) { if (sciThis->posDrop > sciThis->sel.Range(r).End()) { sciThis->posDrop.Add(-sciThis->sel.Range(r).Length()); } else { sciThis->posDrop.Add(-SelectionRange(sciThis->posDrop, sciThis->sel.Range(r).Start()).Length()); } } } sciThis->ClearSelection(); } sciThis->SetDragPosition(SelectionPosition(invalidPosition)); } catch (...) { sciThis->errorStatus = SC_STATUS_FAILURE; } } int ScintillaGTK::TimeOut(ScintillaGTK *sciThis) { sciThis->Tick(); return 1; } gboolean ScintillaGTK::IdleCallback(ScintillaGTK *sciThis) { // Idler will be automatically stopped, if there is nothing // to do while idle. #ifndef GDK_VERSION_3_6 gdk_threads_enter(); #endif bool ret = sciThis->Idle(); if (ret == false) { // FIXME: This will remove the idler from GTK, we don't want to // remove it as it is removed automatically when this function // returns false (although, it should be harmless). sciThis->SetIdle(false); } #ifndef GDK_VERSION_3_6 gdk_threads_leave(); #endif return ret; } gboolean ScintillaGTK::StyleIdle(ScintillaGTK *sciThis) { #ifndef GDK_VERSION_3_6 gdk_threads_enter(); #endif sciThis->IdleWork(); #ifndef GDK_VERSION_3_6 gdk_threads_leave(); #endif // Idler will be automatically stopped return FALSE; } void ScintillaGTK::QueueIdleWork(WorkNeeded::workItems items, int upTo) { Editor::QueueIdleWork(items, upTo); if (!workNeeded.active) { // Only allow one style needed to be queued workNeeded.active = true; g_idle_add_full(G_PRIORITY_HIGH_IDLE, reinterpret_cast<GSourceFunc>(StyleIdle), this, NULL); } } void ScintillaGTK::PopUpCB(GtkMenuItem *menuItem, ScintillaGTK *sciThis) { guint action = (sptr_t)(g_object_get_data(G_OBJECT(menuItem), "CmdNum")); if (action) { sciThis->Command(action); } } gboolean ScintillaGTK::PressCT(GtkWidget *widget, GdkEventButton *event, ScintillaGTK *sciThis) { try { if (event->window != WindowFromWidget(widget)) return FALSE; if (event->type != GDK_BUTTON_PRESS) return FALSE; Point pt; pt.x = int(event->x); pt.y = int(event->y); sciThis->ct.MouseClick(pt); sciThis->CallTipClick(); } catch (...) { } return TRUE; } #if GTK_CHECK_VERSION(3,0,0) gboolean ScintillaGTK::DrawCT(GtkWidget *widget, cairo_t *cr, CallTip *ctip) { try { Surface *surfaceWindow = Surface::Allocate(SC_TECHNOLOGY_DEFAULT); if (surfaceWindow) { surfaceWindow->Init(cr, widget); surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == ctip->codePage); surfaceWindow->SetDBCSMode(ctip->codePage); ctip->PaintCT(surfaceWindow); surfaceWindow->Release(); delete surfaceWindow; } } catch (...) { // No pointer back to Scintilla to save status } return TRUE; } #else gboolean ScintillaGTK::ExposeCT(GtkWidget *widget, GdkEventExpose * /*ose*/, CallTip *ctip) { try { Surface *surfaceWindow = Surface::Allocate(SC_TECHNOLOGY_DEFAULT); if (surfaceWindow) { cairo_t *cr = gdk_cairo_create(WindowFromWidget(widget)); surfaceWindow->Init(cr, widget); surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == ctip->codePage); surfaceWindow->SetDBCSMode(ctip->codePage); ctip->PaintCT(surfaceWindow); surfaceWindow->Release(); delete surfaceWindow; cairo_destroy(cr); } } catch (...) { // No pointer back to Scintilla to save status } return TRUE; } #endif sptr_t ScintillaGTK::DirectFunction( ScintillaGTK *sciThis, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return sciThis->WndProc(iMessage, wParam, lParam); } sptr_t scintilla_send_message(ScintillaObject *sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { ScintillaGTK *psci = reinterpret_cast<ScintillaGTK *>(sci->pscin); return psci->WndProc(iMessage, wParam, lParam); } static void scintilla_class_init(ScintillaClass *klass); static void scintilla_init(ScintillaObject *sci); extern void Platform_Initialise(); extern void Platform_Finalise(); GType scintilla_get_type() { static GType scintilla_type = 0; try { if (!scintilla_type) { scintilla_type = g_type_from_name("Scintilla"); if (!scintilla_type) { static GTypeInfo scintilla_info = { (guint16) sizeof (ScintillaClass), NULL, //(GBaseInitFunc) NULL, //(GBaseFinalizeFunc) (GClassInitFunc) scintilla_class_init, NULL, //(GClassFinalizeFunc) NULL, //gconstpointer data (guint16) sizeof (ScintillaObject), 0, //n_preallocs (GInstanceInitFunc) scintilla_init, NULL //(GTypeValueTable*) }; scintilla_type = g_type_register_static( GTK_TYPE_CONTAINER, "Scintilla", &scintilla_info, (GTypeFlags) 0); } } } catch (...) { } return scintilla_type; } void ScintillaGTK::ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_class, GtkContainerClass *container_class) { Platform_Initialise(); #ifdef SCI_LEXER Scintilla_LinkLexers(); #endif atomClipboard = gdk_atom_intern("CLIPBOARD", FALSE); atomUTF8 = gdk_atom_intern("UTF8_STRING", FALSE); atomString = GDK_SELECTION_TYPE_STRING; atomUriList = gdk_atom_intern("text/uri-list", FALSE); atomDROPFILES_DND = gdk_atom_intern("DROPFILES_DND", FALSE); // Define default signal handlers for the class: Could move more // of the signal handlers here (those that currently attached to wDraw // in Initialise() may require coordinate translation?) object_class->finalize = Destroy; #if GTK_CHECK_VERSION(3,0,0) widget_class->get_preferred_width = GetPreferredWidth; widget_class->get_preferred_height = GetPreferredHeight; #else widget_class->size_request = SizeRequest; #endif widget_class->size_allocate = SizeAllocate; #if GTK_CHECK_VERSION(3,0,0) widget_class->draw = DrawMain; #else widget_class->expose_event = ExposeMain; #endif widget_class->motion_notify_event = Motion; widget_class->button_press_event = Press; widget_class->button_release_event = MouseRelease; widget_class->scroll_event = ScrollEvent; widget_class->key_press_event = KeyPress; widget_class->key_release_event = KeyRelease; widget_class->focus_in_event = FocusIn; widget_class->focus_out_event = FocusOut; widget_class->selection_received = SelectionReceived; widget_class->selection_get = SelectionGet; widget_class->selection_clear_event = SelectionClear; widget_class->drag_data_received = DragDataReceived; widget_class->drag_motion = DragMotion; widget_class->drag_leave = DragLeave; widget_class->drag_end = DragEnd; widget_class->drag_drop = Drop; widget_class->drag_data_get = DragDataGet; widget_class->realize = Realize; widget_class->unrealize = UnRealize; widget_class->map = Map; widget_class->unmap = UnMap; container_class->forall = MainForAll; } #define SIG_MARSHAL scintilla_marshal_NONE__INT_POINTER #define MARSHAL_ARGUMENTS G_TYPE_INT, G_TYPE_POINTER static void scintilla_class_init(ScintillaClass *klass) { try { OBJECT_CLASS *object_class = (OBJECT_CLASS*) klass; GtkWidgetClass *widget_class = (GtkWidgetClass*) klass; GtkContainerClass *container_class = (GtkContainerClass*) klass; GSignalFlags sigflags = GSignalFlags(G_SIGNAL_ACTION | G_SIGNAL_RUN_LAST); scintilla_signals[COMMAND_SIGNAL] = g_signal_new( "command", G_TYPE_FROM_CLASS(object_class), sigflags, G_STRUCT_OFFSET(ScintillaClass, command), NULL, //(GSignalAccumulator) NULL, //(gpointer) SIG_MARSHAL, G_TYPE_NONE, 2, MARSHAL_ARGUMENTS); scintilla_signals[NOTIFY_SIGNAL] = g_signal_new( SCINTILLA_NOTIFY, G_TYPE_FROM_CLASS(object_class), sigflags, G_STRUCT_OFFSET(ScintillaClass, notify), NULL, NULL, SIG_MARSHAL, G_TYPE_NONE, 2, MARSHAL_ARGUMENTS); klass->command = NULL; klass->notify = NULL; ScintillaGTK::ClassInit(object_class, widget_class, container_class); } catch (...) { } } static void scintilla_init(ScintillaObject *sci) { try { #if GTK_CHECK_VERSION(2,20,0) gtk_widget_set_can_focus(GTK_WIDGET(sci), TRUE); #else GTK_WIDGET_SET_FLAGS(sci, GTK_CAN_FOCUS); #endif sci->pscin = new ScintillaGTK(sci); } catch (...) { } } GtkWidget* scintilla_new() { return GTK_WIDGET(g_object_new(scintilla_get_type(), NULL)); } void scintilla_set_id(ScintillaObject *sci, uptr_t id) { ScintillaGTK *psci = reinterpret_cast<ScintillaGTK *>(sci->pscin); psci->ctrlID = id; } void scintilla_release_resources(void) { try { Platform_Finalise(); } catch (...) { } } |
Added gtk/deps.mak.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
PlatGTK.o: PlatGTK.cxx \ ../include/Scintilla.h ../include/ScintillaWidget.h \ ../src/UniConversion.h ../src/XPM.h Converter.h ScintillaGTK.o: ScintillaGTK.cxx \ ../include/ILexer.h ../include/Scintilla.h ../include/ScintillaWidget.h \ ../include/SciLexer.h ../src/SVector.h ../src/SplitVector.h \ ../src/Partitioning.h ../src/RunStyles.h ../src/ContractionState.h \ ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h ../src/Indicator.h \ ../src/XPM.h ../src/LineMarker.h ../src/Style.h ../src/AutoComplete.h \ ../src/ViewStyle.h ../src/Decoration.h ../src/CharClassify.h \ ../src/Document.h ../src/Selection.h ../src/PositionCache.h \ ../src/Editor.h ../src/ScintillaBase.h ../src/UniConversion.h \ scintilla-marshal.h ../lexlib/LexerModule.h ../src/ExternalLexer.h \ Converter.h AutoComplete.o: ../src/AutoComplete.cxx ../include/Platform.h \ ../lexlib/CharacterSet.h ../src/AutoComplete.h ../include/Scintilla.h CallTip.o: ../src/CallTip.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/CallTip.h Catalogue.o: ../src/Catalogue.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/LexerModule.h \ ../src/Catalogue.h CellBuffer.o: ../src/CellBuffer.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/CellBuffer.h ../src/UniConversion.h CharClassify.o: ../src/CharClassify.cxx ../src/CharClassify.h ContractionState.o: ../src/ContractionState.cxx ../include/Platform.h \ ../src/SplitVector.h ../src/Partitioning.h ../src/RunStyles.h \ ../src/ContractionState.h Decoration.o: ../src/Decoration.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/Decoration.h Document.o: ../src/Document.cxx ../include/Platform.h ../include/ILexer.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/CellBuffer.h ../src/PerLine.h \ ../src/CharClassify.h ../lexlib/CharacterSet.h ../src/Decoration.h \ ../src/Document.h ../src/RESearch.h ../src/UniConversion.h Editor.o: ../src/Editor.cxx ../include/Platform.h ../include/ILexer.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/ContractionState.h ../src/CellBuffer.h \ ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ ../src/Style.h ../src/ViewStyle.h ../src/CharClassify.h \ ../src/Decoration.h ../src/Document.h ../src/UniConversion.h \ ../src/Selection.h ../src/PositionCache.h ../src/Editor.h ExternalLexer.o: ../src/ExternalLexer.cxx ../include/Platform.h \ ../include/ILexer.h ../include/Scintilla.h ../include/SciLexer.h \ ../lexlib/LexerModule.h ../src/Catalogue.h ../src/ExternalLexer.h Indicator.o: ../src/Indicator.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/XPM.h ../src/Indicator.h KeyMap.o: ../src/KeyMap.cxx ../include/Platform.h ../include/Scintilla.h \ ../src/KeyMap.h LineMarker.o: ../src/LineMarker.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/XPM.h ../src/LineMarker.h PerLine.o: ../src/PerLine.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/CellBuffer.h ../src/PerLine.h PositionCache.o: ../src/PositionCache.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/ContractionState.h ../src/CellBuffer.h \ ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ ../src/Style.h ../src/ViewStyle.h ../src/CharClassify.h \ ../src/Decoration.h ../include/ILexer.h ../src/Document.h \ ../src/Selection.h ../src/PositionCache.h RESearch.o: ../src/RESearch.cxx ../src/CharClassify.h ../src/RESearch.h RunStyles.o: ../src/RunStyles.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ScintillaBase.o: ../src/ScintillaBase.cxx ../include/Platform.h \ ../include/ILexer.h ../include/Scintilla.h ../lexlib/PropSetSimple.h \ ../include/SciLexer.h ../lexlib/LexerModule.h ../src/Catalogue.h \ ../src/SplitVector.h ../src/Partitioning.h ../src/RunStyles.h \ ../src/ContractionState.h ../src/CellBuffer.h ../src/CallTip.h \ ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ ../src/Style.h ../src/ViewStyle.h ../src/AutoComplete.h \ ../src/CharClassify.h ../src/Decoration.h ../src/Document.h \ ../src/Selection.h ../src/PositionCache.h ../src/Editor.h \ ../src/ScintillaBase.h Selection.o: ../src/Selection.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/Selection.h Style.o: ../src/Style.cxx ../include/Platform.h ../include/Scintilla.h \ ../src/Style.h UniConversion.o: ../src/UniConversion.cxx ../src/UniConversion.h ViewStyle.o: ../src/ViewStyle.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ ../src/Style.h ../src/ViewStyle.h XPM.o: ../src/XPM.cxx ../include/Platform.h ../src/XPM.h |
Added gtk/makefile.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# Make file for Scintilla on Linux or compatible OS # Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> # The License.txt file describes the conditions under which this software may be distributed. # This makefile assumes GCC 4.3 is used and changes will be needed to use other compilers. # GNU make does not like \r\n line endings so should be saved to CVS in binary form. # Builds for GTK+ 2 and no longer supports GTK+ 1. # Also works with ming32-make on Windows. .SUFFIXES: .cxx .c .o .h .a ifdef CLANG CC = clang --std=c++0x CCOMP = clang else CC = g++ CCOMP = gcc endif AR = ar RANLIB = touch ifdef GTK3 GTKVERSION=gtk+-3.0 else GTKVERSION=gtk+-2.0 endif # Environment variable windir always defined on Win32 ifndef windir ifeq ($(shell uname),Darwin) RANLIB = ranlib endif endif ifdef windir DEL = del /q COMPLIB=..\bin\scintilla.a else DEL = rm -f COMPLIB=../bin/scintilla.a endif vpath %.h ../src ../include ../lexlib vpath %.cxx ../src ../lexlib ../lexers INCLUDEDIRS=-I ../include -I ../src -I ../lexlib ifdef CHECK_DEPRECATED DEPRECATED=-DGDK_PIXBUF_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DDISABLE_GDK_FONT endif CXXBASEFLAGS=-Wall -Wno-missing-braces -Wno-char-subscripts -pedantic -DGTK -DSCI_LEXER $(INCLUDEDIRS) $(DEPRECATED) ifdef NOTHREADS THREADFLAGS=-DG_THREADS_IMPL_NONE else THREADFLAGS= endif ifdef DEBUG CXXTFLAGS=-DDEBUG -g $(CXXBASEFLAGS) $(THREADFLAGS) else CXXTFLAGS=-DNDEBUG -Os $(CXXBASEFLAGS) $(THREADFLAGS) endif CFLAGS:=$(CXXTFLAGS) CONFIGFLAGS:=$(shell pkg-config --cflags $(GTKVERSION)) MARSHALLER=scintilla-marshal.o .cxx.o: $(CC) $(CONFIGFLAGS) $(CXXTFLAGS) $(CXXFLAGS) -c $< .c.o: $(CCOMP) $(CONFIGFLAGS) $(CFLAGS) -w -c $< LEXOBJS:=$(addsuffix .o,$(basename $(notdir $(wildcard ../lexers/Lex*.cxx)))) all: $(COMPLIB) clean: $(DEL) *.o $(COMPLIB) *.plist analyze: clang --analyze $(CONFIGFLAGS) $(CXXTFLAGS) $(CXXFLAGS) *.cxx ../src/*.cxx ../lexlib/*.cxx ../lexers/*.cxx deps: $(CC) -MM $(CONFIGFLAGS) $(CXXTFLAGS) *.cxx ../src/*.cxx | sed -e 's/\/usr.* //' | grep [a-zA-Z] >deps.mak $(COMPLIB): Accessor.o CharacterSet.o LexerBase.o LexerModule.o LexerSimple.o StyleContext.o WordList.o \ CharClassify.o Decoration.o Document.o PerLine.o Catalogue.o CallTip.o \ ScintillaBase.o ContractionState.o Editor.o ExternalLexer.o PropSetSimple.o PlatGTK.o \ KeyMap.o LineMarker.o PositionCache.o ScintillaGTK.o CellBuffer.o ViewStyle.o \ RESearch.o RunStyles.o Selection.o Style.o Indicator.o AutoComplete.o UniConversion.o XPM.o \ $(MARSHALLER) $(LEXOBJS) $(AR) rc $@ $^ $(RANLIB) $@ # Automatically generate header dependencies with "make deps" include deps.mak |
Added gtk/scintilla-marshal.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
#include <glib-object.h> #ifdef G_ENABLE_DEBUG #define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) #define g_marshal_value_peek_char(v) g_value_get_char (v) #define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) #define g_marshal_value_peek_int(v) g_value_get_int (v) #define g_marshal_value_peek_uint(v) g_value_get_uint (v) #define g_marshal_value_peek_long(v) g_value_get_long (v) #define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) #define g_marshal_value_peek_int64(v) g_value_get_int64 (v) #define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) #define g_marshal_value_peek_enum(v) g_value_get_enum (v) #define g_marshal_value_peek_flags(v) g_value_get_flags (v) #define g_marshal_value_peek_float(v) g_value_get_float (v) #define g_marshal_value_peek_double(v) g_value_get_double (v) #define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) #define g_marshal_value_peek_param(v) g_value_get_param (v) #define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) #define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) #define g_marshal_value_peek_object(v) g_value_get_object (v) #else /* !G_ENABLE_DEBUG */ /* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. * Do not access GValues directly in your code. Instead, use the * g_value_get_*() functions */ #define g_marshal_value_peek_boolean(v) (v)->data[0].v_int #define g_marshal_value_peek_char(v) (v)->data[0].v_int #define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint #define g_marshal_value_peek_int(v) (v)->data[0].v_int #define g_marshal_value_peek_uint(v) (v)->data[0].v_uint #define g_marshal_value_peek_long(v) (v)->data[0].v_long #define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong #define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 #define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 #define g_marshal_value_peek_enum(v) (v)->data[0].v_int #define g_marshal_value_peek_flags(v) (v)->data[0].v_uint #define g_marshal_value_peek_float(v) (v)->data[0].v_float #define g_marshal_value_peek_double(v) (v)->data[0].v_double #define g_marshal_value_peek_string(v) (v)->data[0].v_pointer #define g_marshal_value_peek_param(v) (v)->data[0].v_pointer #define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer #define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer #define g_marshal_value_peek_object(v) (v)->data[0].v_pointer #endif /* !G_ENABLE_DEBUG */ /* NONE:INT,POINTER (scintilla-marshal.list:1) */ void scintilla_marshal_VOID__INT_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__INT_POINTER) (gpointer data1, gint arg_1, gpointer arg_2, gpointer data2); register GMarshalFunc_VOID__INT_POINTER callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; g_return_if_fail (n_param_values == 3); if (G_CCLOSURE_SWAP_DATA (closure)) { data1 = closure->data; data2 = g_value_peek_pointer (param_values + 0); } else { data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } callback = (GMarshalFunc_VOID__INT_POINTER) (marshal_data ? marshal_data : cc->callback); callback (data1, g_marshal_value_peek_int (param_values + 1), g_marshal_value_peek_pointer (param_values + 2), data2); } |
Added gtk/scintilla-marshal.h.
> > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#ifndef __scintilla_marshal_MARSHAL_H__ #define __scintilla_marshal_MARSHAL_H__ #include <glib-object.h> G_BEGIN_DECLS /* NONE:INT,POINTER (scintilla-marshal.list:1) */ extern void scintilla_marshal_VOID__INT_POINTER (GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data); #define scintilla_marshal_NONE__INT_POINTER scintilla_marshal_VOID__INT_POINTER G_END_DECLS #endif /* __scintilla_marshal_MARSHAL_H__ */ |
Added gtk/scintilla-marshal.list.
> |
1 |
NONE:INT,POINTER
|
Added include/Face.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# Module for reading and parsing Scintilla.iface file def sanitiseLine(line): if line[-1:] == '\n': line = line[:-1] if line.find("##") != -1: line = line[:line.find("##")] line = line.strip() return line def decodeFunction(featureVal): retType, rest = featureVal.split(" ", 1) nameIdent, params = rest.split("(") name, value = nameIdent.split("=") params, rest = params.split(")") param1, param2 = params.split(",") return retType, name, value, param1, param2 def decodeEvent(featureVal): retType, rest = featureVal.split(" ", 1) nameIdent, params = rest.split("(") name, value = nameIdent.split("=") return retType, name, value def decodeParam(p): param = p.strip() type = "" name = "" value = "" if " " in param: type, nv = param.split(" ") if "=" in nv: name, value = nv.split("=") else: name = nv return type, name, value class Face: def __init__(self): self.order = [] self.features = {} self.values = {} self.events = {} def ReadFromFile(self, name): currentCategory = "" currentComment = [] currentCommentFinished = 0 file = open(name) for line in file.readlines(): line = sanitiseLine(line) if line: if line[0] == "#": if line[1] == " ": if currentCommentFinished: currentComment = [] currentCommentFinished = 0 currentComment.append(line[2:]) else: currentCommentFinished = 1 featureType, featureVal = line.split(" ", 1) if featureType in ["fun", "get", "set"]: try: retType, name, value, param1, param2 = decodeFunction(featureVal) except ValueError: print("Failed to decode %s" % line) raise p1 = decodeParam(param1) p2 = decodeParam(param2) self.features[name] = { "FeatureType": featureType, "ReturnType": retType, "Value": value, "Param1Type": p1[0], "Param1Name": p1[1], "Param1Value": p1[2], "Param2Type": p2[0], "Param2Name": p2[1], "Param2Value": p2[2], "Category": currentCategory, "Comment": currentComment } if value in self.values: raise Exception("Duplicate value " + value + " " + name) self.values[value] = 1 self.order.append(name) elif featureType == "evt": retType, name, value = decodeEvent(featureVal) self.features[name] = { "FeatureType": featureType, "ReturnType": retType, "Value": value, "Category": currentCategory, "Comment": currentComment } if value in self.events: raise Exception("Duplicate event " + value + " " + name) self.events[value] = 1 self.order.append(name) elif featureType == "cat": currentCategory = featureVal elif featureType == "val": try: name, value = featureVal.split("=", 1) except ValueError: print("Failure %s" % featureVal) raise Exception() self.features[name] = { "FeatureType": featureType, "Category": currentCategory, "Value": value } self.order.append(name) elif featureType == "enu" or featureType == "lex": name, value = featureVal.split("=", 1) self.features[name] = { "FeatureType": featureType, "Category": currentCategory, "Value": value } self.order.append(name) |
Added include/Face.pyc.
cannot compute difference between binary files
Added include/HFacer.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
#!/usr/bin/env python # HFacer.py - regenerate the Scintilla.h and SciLexer.h files from the Scintilla.iface interface # definition file. # The header files are copied to a temporary file apart from the section between a /* ++Autogenerated*/ # comment and a /* --Autogenerated*/ comment which is generated by the printHFile and printLexHFile # functions. After the temporary file is created, it is copied back to the original file name. import sys import os import Face def Contains(s,sub): return s.find(sub) != -1 def printLexHFile(f,out): for name in f.order: v = f.features[name] if v["FeatureType"] in ["val"]: if Contains(name, "SCE_") or Contains(name, "SCLEX_"): out.write("#define " + name + " " + v["Value"] + "\n") def printHFile(f,out): previousCategory = "" for name in f.order: v = f.features[name] if v["Category"] != "Deprecated": if v["Category"] == "Provisional" and previousCategory != "Provisional": out.write("#ifndef SCI_DISABLE_PROVISIONAL\n") previousCategory = v["Category"] if v["FeatureType"] in ["fun", "get", "set"]: featureDefineName = "SCI_" + name.upper() out.write("#define " + featureDefineName + " " + v["Value"] + "\n") elif v["FeatureType"] in ["evt"]: featureDefineName = "SCN_" + name.upper() out.write("#define " + featureDefineName + " " + v["Value"] + "\n") elif v["FeatureType"] in ["val"]: if not (Contains(name, "SCE_") or Contains(name, "SCLEX_")): out.write("#define " + name + " " + v["Value"] + "\n") out.write("#endif\n") def CopyWithInsertion(input, output, genfn, definition): copying = 1 for line in input.readlines(): if copying: output.write(line) if Contains(line, "/* ++Autogenerated"): copying = 0 genfn(definition, output) if Contains(line, "/* --Autogenerated"): copying = 1 output.write(line) def contents(filename): f = open(filename) t = f.read() f.close() return t def Regenerate(filename, genfn, definition): inText = contents(filename) tempname = "HFacer.tmp" out = open(tempname,"w") hfile = open(filename) CopyWithInsertion(hfile, out, genfn, definition) out.close() hfile.close() outText = contents(tempname) if inText == outText: os.unlink(tempname) else: os.unlink(filename) os.rename(tempname, filename) f = Face.Face() try: f.ReadFromFile("Scintilla.iface") Regenerate("Scintilla.h", printHFile, f) Regenerate("SciLexer.h", printLexHFile, f) print("Maximum ID is %s" % max([x for x in f.values if int(x) < 3000])) except: raise |
Added include/ILexer.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
// Scintilla source code edit control /** @file ILexer.h ** Interface between Scintilla and lexers. **/ // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef ILEXER_H #define ILEXER_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif #ifdef _WIN32 #define SCI_METHOD __stdcall #else #define SCI_METHOD #endif enum { dvOriginal=0, dvLineEnd=1 }; class IDocument { public: virtual int SCI_METHOD Version() const = 0; virtual void SCI_METHOD SetErrorStatus(int status) = 0; virtual int SCI_METHOD Length() const = 0; virtual void SCI_METHOD GetCharRange(char *buffer, int position, int lengthRetrieve) const = 0; virtual char SCI_METHOD StyleAt(int position) const = 0; virtual int SCI_METHOD LineFromPosition(int position) const = 0; virtual int SCI_METHOD LineStart(int line) const = 0; virtual int SCI_METHOD GetLevel(int line) const = 0; virtual int SCI_METHOD SetLevel(int line, int level) = 0; virtual int SCI_METHOD GetLineState(int line) const = 0; virtual int SCI_METHOD SetLineState(int line, int state) = 0; virtual void SCI_METHOD StartStyling(int position, char mask) = 0; virtual bool SCI_METHOD SetStyleFor(int length, char style) = 0; virtual bool SCI_METHOD SetStyles(int length, const char *styles) = 0; virtual void SCI_METHOD DecorationSetCurrentIndicator(int indicator) = 0; virtual void SCI_METHOD DecorationFillRange(int position, int value, int fillLength) = 0; virtual void SCI_METHOD ChangeLexerState(int start, int end) = 0; virtual int SCI_METHOD CodePage() const = 0; virtual bool SCI_METHOD IsDBCSLeadByte(char ch) const = 0; virtual const char * SCI_METHOD BufferPointer() = 0; virtual int SCI_METHOD GetLineIndentation(int line) = 0; virtual ~IDocument() {} }; class IDocumentWithLineEnd : public IDocument { public: virtual int SCI_METHOD LineEnd(int line) const = 0; }; enum { lvOriginal=0, lvSubStyles=1 }; class ILexer { public: virtual int SCI_METHOD Version() const = 0; virtual void SCI_METHOD Release() = 0; virtual const char * SCI_METHOD PropertyNames() = 0; virtual int SCI_METHOD PropertyType(const char *name) = 0; virtual const char * SCI_METHOD DescribeProperty(const char *name) = 0; virtual int SCI_METHOD PropertySet(const char *key, const char *val) = 0; virtual const char * SCI_METHOD DescribeWordListSets() = 0; virtual int SCI_METHOD WordListSet(int n, const char *wl) = 0; virtual void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0; virtual void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0; virtual void * SCI_METHOD PrivateCall(int operation, void *pointer) = 0; virtual ~ILexer() {} }; class ILexerWithSubStyles : public ILexer { public: virtual int SCI_METHOD LineEndTypesSupported() = 0; virtual int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) = 0; virtual int SCI_METHOD SubStylesStart(int styleBase) = 0; virtual int SCI_METHOD SubStylesLength(int styleBase) = 0; virtual void SCI_METHOD FreeSubStyles() = 0; virtual void SCI_METHOD SetIdentifiers(int style, const char *identifiers) = 0; virtual int SCI_METHOD DistanceToSecondaryStyles() = 0; virtual const char * SCI_METHOD GetSubStyleBases() = 0; }; class ILoader { public: virtual int SCI_METHOD Release() = 0; // Returns a status code from SC_STATUS_* virtual int SCI_METHOD AddData(char *data, int length) = 0; virtual void * SCI_METHOD ConvertToDocument() = 0; virtual ~ILoader() {} }; #ifdef SCI_NAMESPACE } #endif #endif |
Added include/Platform.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 |
// Scintilla source code edit control /** @file Platform.h ** Interface to platform facilities. Also includes some basic utilities. ** Implemented in PlatGTK.cxx for GTK+/Linux, PlatWin.cxx for Windows, and PlatWX.cxx for wxWindows. **/ // Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef PLATFORM_H #define PLATFORM_H // PLAT_TK = Tcl/TK on Linux or Win32 // PLAT_GTK = GTK+ on Linux or Win32 // PLAT_GTK_WIN32 is defined additionally when running PLAT_GTK under Win32 // PLAT_WIN = Win32 API on Win32 OS // PLAT_WX is wxWindows on any supported platform #define PLAT_TK 0 #define PLAT_GTK 0 #define PLAT_GTK_WIN32 0 #define PLAT_GTK_MACOSX 0 #define PLAT_MACOSX 0 #define PLAT_WIN 0 #define PLAT_WX 0 #define PLAT_QT 0 #define PLAT_FOX 0 #define PLAT_NCURSES 0 #if defined(FOX) #undef PLAT_FOX #define PLAT_FOX 1 #elif defined(__WX__) #undef PLAT_WX #define PLAT_WX 1 #elif defined(NCURSES) #undef PLAT_NCURSES #define PLAT_NCURSES 1 #elif defined(SCINTILLA_QT) #undef PLAT_QT #define PLAT_QT 1 #elif defined(TK) #undef PLAT_TK #define PLAT_TK 1 #elif defined(GTK) #undef PLAT_GTK #define PLAT_GTK 1 #if defined(__WIN32__) || defined(_MSC_VER) #undef PLAT_GTK_WIN32 #define PLAT_GTK_WIN32 1 #endif #if defined(__APPLE__) #undef PLAT_GTK_MACOSX #define PLAT_GTK_MACOSX 1 #endif #elif defined(__APPLE__) #undef PLAT_MACOSX #define PLAT_MACOSX 1 #else #undef PLAT_WIN #define PLAT_WIN 1 #endif #ifdef SCI_NAMESPACE namespace Scintilla { #endif #if defined(TK) typedef int XYPOSITION; #else typedef float XYPOSITION; #endif typedef double XYACCUMULATOR; //#define XYPOSITION int // Underlying the implementation of the platform classes are platform specific types. // Sometimes these need to be passed around by client code so they are defined here typedef void *FontID; typedef void *SurfaceID; typedef void *WindowID; typedef void *MenuID; typedef void *TickerID; typedef void *Function; typedef void *IdlerID; /** * A geometric point class. * Point is exactly the same as the Win32 POINT and GTK+ GdkPoint so can be used interchangeably. */ class Point { public: XYPOSITION x; XYPOSITION y; explicit Point(XYPOSITION x_=0, XYPOSITION y_=0) : x(x_), y(y_) { } // Other automatically defined methods (assignment, copy constructor, destructor) are fine static Point FromLong(long lpoint); }; /** * A geometric rectangle class. * PRectangle is exactly the same as the Win32 RECT so can be used interchangeably. * PRectangles contain their top and left sides, but not their right and bottom sides. */ class PRectangle { public: XYPOSITION left; XYPOSITION top; XYPOSITION right; XYPOSITION bottom; PRectangle(XYPOSITION left_=0, XYPOSITION top_=0, XYPOSITION right_=0, XYPOSITION bottom_ = 0) : left(left_), top(top_), right(right_), bottom(bottom_) { } // Other automatically defined methods (assignment, copy constructor, destructor) are fine bool operator==(PRectangle &rc) { return (rc.left == left) && (rc.right == right) && (rc.top == top) && (rc.bottom == bottom); } bool Contains(Point pt) { return (pt.x >= left) && (pt.x <= right) && (pt.y >= top) && (pt.y <= bottom); } bool Contains(PRectangle rc) { return (rc.left >= left) && (rc.right <= right) && (rc.top >= top) && (rc.bottom <= bottom); } bool Intersects(PRectangle other) { return (right > other.left) && (left < other.right) && (bottom > other.top) && (top < other.bottom); } void Move(XYPOSITION xDelta, XYPOSITION yDelta) { left += xDelta; top += yDelta; right += xDelta; bottom += yDelta; } XYPOSITION Width() { return right - left; } XYPOSITION Height() { return bottom - top; } bool Empty() { return (Height() <= 0) || (Width() <= 0); } }; /** * Holds a desired RGB colour. */ class ColourDesired { long co; public: ColourDesired(long lcol=0) { co = lcol; } ColourDesired(unsigned int red, unsigned int green, unsigned int blue) { Set(red, green, blue); } bool operator==(const ColourDesired &other) const { return co == other.co; } void Set(long lcol) { co = lcol; } void Set(unsigned int red, unsigned int green, unsigned int blue) { co = red | (green << 8) | (blue << 16); } static inline unsigned int ValueOfHex(const char ch) { if (ch >= '0' && ch <= '9') return ch - '0'; else if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10; else if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10; else return 0; } void Set(const char *val) { if (*val == '#') { val++; } unsigned int r = ValueOfHex(val[0]) * 16 + ValueOfHex(val[1]); unsigned int g = ValueOfHex(val[2]) * 16 + ValueOfHex(val[3]); unsigned int b = ValueOfHex(val[4]) * 16 + ValueOfHex(val[5]); Set(r, g, b); } long AsLong() const { return co; } unsigned int GetRed() { return co & 0xff; } unsigned int GetGreen() { return (co >> 8) & 0xff; } unsigned int GetBlue() { return (co >> 16) & 0xff; } }; /** * Font management. */ struct FontParameters { const char *faceName; float size; int weight; bool italic; int extraFontFlag; int technology; int characterSet; FontParameters( const char *faceName_, float size_=10, int weight_=400, bool italic_=false, int extraFontFlag_=0, int technology_=0, int characterSet_=0) : faceName(faceName_), size(size_), weight(weight_), italic(italic_), extraFontFlag(extraFontFlag_), technology(technology_), characterSet(characterSet_) { } }; class Font { protected: FontID fid; #if PLAT_WX int ascent; #endif // Private so Font objects can not be copied Font(const Font &); Font &operator=(const Font &); public: Font(); virtual ~Font(); virtual void Create(const FontParameters &fp); virtual void Release(); FontID GetID() { return fid; } // Alias another font - caller guarantees not to Release void SetID(FontID fid_) { fid = fid_; } #if PLAT_WX void SetAscent(int ascent_) { ascent = ascent_; } #endif friend class Surface; friend class SurfaceImpl; }; /** * A surface abstracts a place to draw. */ class Surface { private: // Private so Surface objects can not be copied Surface(const Surface &) {} Surface &operator=(const Surface &) { return *this; } public: Surface() {} virtual ~Surface() {} static Surface *Allocate(int technology); virtual void Init(WindowID wid)=0; virtual void Init(SurfaceID sid, WindowID wid)=0; virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid)=0; virtual void Release()=0; virtual bool Initialised()=0; virtual void PenColour(ColourDesired fore)=0; virtual int LogPixelsY()=0; virtual int DeviceHeightFont(int points)=0; virtual void MoveTo(int x_, int y_)=0; virtual void LineTo(int x_, int y_)=0; virtual void Polygon(Point *pts, int npts, ColourDesired fore, ColourDesired back)=0; virtual void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back)=0; virtual void FillRectangle(PRectangle rc, ColourDesired back)=0; virtual void FillRectangle(PRectangle rc, Surface &surfacePattern)=0; virtual void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back)=0; virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, ColourDesired outline, int alphaOutline, int flags)=0; virtual void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) = 0; virtual void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back)=0; virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0; virtual void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back)=0; virtual void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back)=0; virtual void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore)=0; virtual void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions)=0; virtual XYPOSITION WidthText(Font &font_, const char *s, int len)=0; virtual XYPOSITION WidthChar(Font &font_, char ch)=0; virtual XYPOSITION Ascent(Font &font_)=0; virtual XYPOSITION Descent(Font &font_)=0; virtual XYPOSITION InternalLeading(Font &font_)=0; virtual XYPOSITION ExternalLeading(Font &font_)=0; virtual XYPOSITION Height(Font &font_)=0; virtual XYPOSITION AverageCharWidth(Font &font_)=0; virtual void SetClip(PRectangle rc)=0; virtual void FlushCachedState()=0; virtual void SetUnicodeMode(bool unicodeMode_)=0; virtual void SetDBCSMode(int codePage)=0; }; /** * A simple callback action passing one piece of untyped user data. */ typedef void (*CallBackAction)(void*); /** * Class to hide the details of window manipulation. * Does not own the window which will normally have a longer life than this object. */ class Window { protected: WindowID wid; #if PLAT_MACOSX void *windowRef; void *control; #endif public: Window() : wid(0), cursorLast(cursorInvalid) { #if PLAT_MACOSX windowRef = 0; control = 0; #endif } Window(const Window &source) : wid(source.wid), cursorLast(cursorInvalid) { #if PLAT_MACOSX windowRef = 0; control = 0; #endif } virtual ~Window(); Window &operator=(WindowID wid_) { wid = wid_; return *this; } WindowID GetID() const { return wid; } bool Created() const { return wid != 0; } void Destroy(); bool HasFocus(); PRectangle GetPosition(); void SetPosition(PRectangle rc); void SetPositionRelative(PRectangle rc, Window relativeTo); PRectangle GetClientPosition(); void Show(bool show=true); void InvalidateAll(); void InvalidateRectangle(PRectangle rc); virtual void SetFont(Font &font); enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand }; void SetCursor(Cursor curs); void SetTitle(const char *s); PRectangle GetMonitorRect(Point pt); #if PLAT_MACOSX void SetWindow(void *ref) { windowRef = ref; } void SetControl(void *_control) { control = _control; } #endif private: Cursor cursorLast; }; /** * Listbox management. */ class ListBox : public Window { public: ListBox(); virtual ~ListBox(); static ListBox *Allocate(); virtual void SetFont(Font &font)=0; virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_, int technology_)=0; virtual void SetAverageCharWidth(int width)=0; virtual void SetVisibleRows(int rows)=0; virtual int GetVisibleRows() const=0; virtual PRectangle GetDesiredRect()=0; virtual int CaretFromEdge()=0; virtual void Clear()=0; virtual void Append(char *s, int type = -1)=0; virtual int Length()=0; virtual void Select(int n)=0; virtual int GetSelection()=0; virtual int Find(const char *prefix)=0; virtual void GetValue(int n, char *value, int len)=0; virtual void RegisterImage(int type, const char *xpm_data)=0; virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) = 0; virtual void ClearRegisteredImages()=0; virtual void SetDoubleClickAction(CallBackAction, void *)=0; virtual void SetList(const char* list, char separator, char typesep)=0; }; /** * Menu management. */ class Menu { MenuID mid; public: Menu(); MenuID GetID() { return mid; } void CreatePopUp(); void Destroy(); void Show(Point pt, Window &w); }; class ElapsedTime { long bigBit; long littleBit; public: ElapsedTime(); double Duration(bool reset=false); }; /** * Dynamic Library (DLL/SO/...) loading */ class DynamicLibrary { public: virtual ~DynamicLibrary() {} /// @return Pointer to function "name", or NULL on failure. virtual Function FindFunction(const char *name) = 0; /// @return true if the library was loaded successfully. virtual bool IsValid() = 0; /// @return An instance of a DynamicLibrary subclass with "modulePath" loaded. static DynamicLibrary *Load(const char *modulePath); }; /** * Platform class used to retrieve system wide parameters such as double click speed * and chrome colour. Not a creatable object, more of a module with several functions. */ class Platform { // Private so Platform objects can not be copied Platform(const Platform &) {} Platform &operator=(const Platform &) { return *this; } public: // Should be private because no new Platforms are ever created // but gcc warns about this Platform() {} ~Platform() {} static ColourDesired Chrome(); static ColourDesired ChromeHighlight(); static const char *DefaultFont(); static int DefaultFontSize(); static unsigned int DoubleClickTime(); static bool MouseButtonBounce(); static void DebugDisplay(const char *s); static bool IsKeyDown(int key); static long SendScintilla( WindowID w, unsigned int msg, unsigned long wParam=0, long lParam=0); static long SendScintillaPointer( WindowID w, unsigned int msg, unsigned long wParam=0, void *lParam=0); static bool IsDBCSLeadByte(int codePage, char ch); static int DBCSCharLength(int codePage, const char *s); static int DBCSCharMaxLength(); // These are utility functions not really tied to a platform static int Minimum(int a, int b); static int Maximum(int a, int b); // Next three assume 16 bit shorts and 32 bit longs static long LongFromTwoShorts(short a,short b) { return (a) | ((b) << 16); } static short HighShortFromLong(long x) { return static_cast<short>(x >> 16); } static short LowShortFromLong(long x) { return static_cast<short>(x & 0xffff); } static void DebugPrintf(const char *format, ...); static bool ShowAssertionPopUps(bool assertionPopUps_); static void Assert(const char *c, const char *file, int line); static int Clamp(int val, int minVal, int maxVal); }; #ifdef NDEBUG #define PLATFORM_ASSERT(c) ((void)0) #else #ifdef SCI_NAMESPACE #define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Scintilla::Platform::Assert(#c, __FILE__, __LINE__)) #else #define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Platform::Assert(#c, __FILE__, __LINE__)) #endif #endif #ifdef SCI_NAMESPACE } #endif // Shut up annoying Visual C++ warnings: #ifdef _MSC_VER #pragma warning(disable: 4244 4309 4514 4710) #endif #if defined(__GNUC__) && defined(SCINTILLA_QT) #pragma GCC diagnostic ignored "-Wmissing-braces" #pragma GCC diagnostic ignored "-Wmissing-field-initializers" #pragma GCC diagnostic ignored "-Wchar-subscripts" #endif #endif |
Added include/SciLexer.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 |
/* Scintilla source code edit control */ /** @file SciLexer.h ** Interface to the added lexer functions in the SciLexer version of the edit control. **/ /* Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> * The License.txt file describes the conditions under which this software may be distributed. */ /* Most of this file is automatically generated from the Scintilla.iface interface definition * file which contains any comments about the definitions. HFacer.py does the generation. */ #ifndef SCILEXER_H #define SCILEXER_H /* SciLexer features - not in standard Scintilla */ /* ++Autogenerated -- start of section automatically generated from Scintilla.iface */ #define SCLEX_CONTAINER 0 #define SCLEX_NULL 1 #define SCLEX_PYTHON 2 #define SCLEX_CPP 3 #define SCLEX_HTML 4 #define SCLEX_XML 5 #define SCLEX_PERL 6 #define SCLEX_SQL 7 #define SCLEX_VB 8 #define SCLEX_PROPERTIES 9 #define SCLEX_ERRORLIST 10 #define SCLEX_MAKEFILE 11 #define SCLEX_BATCH 12 #define SCLEX_XCODE 13 #define SCLEX_LATEX 14 #define SCLEX_LUA 15 #define SCLEX_DIFF 16 #define SCLEX_CONF 17 #define SCLEX_PASCAL 18 #define SCLEX_AVE 19 #define SCLEX_ADA 20 #define SCLEX_LISP 21 #define SCLEX_RUBY 22 #define SCLEX_EIFFEL 23 #define SCLEX_EIFFELKW 24 #define SCLEX_TCL 25 #define SCLEX_NNCRONTAB 26 #define SCLEX_BULLANT 27 #define SCLEX_VBSCRIPT 28 #define SCLEX_BAAN 31 #define SCLEX_MATLAB 32 #define SCLEX_SCRIPTOL 33 #define SCLEX_ASM 34 #define SCLEX_CPPNOCASE 35 #define SCLEX_FORTRAN 36 #define SCLEX_F77 37 #define SCLEX_CSS 38 #define SCLEX_POV 39 #define SCLEX_LOUT 40 #define SCLEX_ESCRIPT 41 #define SCLEX_PS 42 #define SCLEX_NSIS 43 #define SCLEX_MMIXAL 44 #define SCLEX_CLW 45 #define SCLEX_CLWNOCASE 46 #define SCLEX_LOT 47 #define SCLEX_YAML 48 #define SCLEX_TEX 49 #define SCLEX_METAPOST 50 #define SCLEX_POWERBASIC 51 #define SCLEX_FORTH 52 #define SCLEX_ERLANG 53 #define SCLEX_OCTAVE 54 #define SCLEX_MSSQL 55 #define SCLEX_VERILOG 56 #define SCLEX_KIX 57 #define SCLEX_GUI4CLI 58 #define SCLEX_SPECMAN 59 #define SCLEX_AU3 60 #define SCLEX_APDL 61 #define SCLEX_BASH 62 #define SCLEX_ASN1 63 #define SCLEX_VHDL 64 #define SCLEX_CAML 65 #define SCLEX_BLITZBASIC 66 #define SCLEX_PUREBASIC 67 #define SCLEX_HASKELL 68 #define SCLEX_PHPSCRIPT 69 #define SCLEX_TADS3 70 #define SCLEX_REBOL 71 #define SCLEX_SMALLTALK 72 #define SCLEX_FLAGSHIP 73 #define SCLEX_CSOUND 74 #define SCLEX_FREEBASIC 75 #define SCLEX_INNOSETUP 76 #define SCLEX_OPAL 77 #define SCLEX_SPICE 78 #define SCLEX_D 79 #define SCLEX_CMAKE 80 #define SCLEX_GAP 81 #define SCLEX_PLM 82 #define SCLEX_PROGRESS 83 #define SCLEX_ABAQUS 84 #define SCLEX_ASYMPTOTE 85 #define SCLEX_R 86 #define SCLEX_MAGIK 87 #define SCLEX_POWERSHELL 88 #define SCLEX_MYSQL 89 #define SCLEX_PO 90 #define SCLEX_TAL 91 #define SCLEX_COBOL 92 #define SCLEX_TACL 93 #define SCLEX_SORCUS 94 #define SCLEX_POWERPRO 95 #define SCLEX_NIMROD 96 #define SCLEX_SML 97 #define SCLEX_MARKDOWN 98 #define SCLEX_TXT2TAGS 99 #define SCLEX_A68K 100 #define SCLEX_MODULA 101 #define SCLEX_COFFEESCRIPT 102 #define SCLEX_TCMD 103 #define SCLEX_AVS 104 #define SCLEX_ECL 105 #define SCLEX_OSCRIPT 106 #define SCLEX_VISUALPROLOG 107 #define SCLEX_AUTOMATIC 1000 #define SCE_P_DEFAULT 0 #define SCE_P_COMMENTLINE 1 #define SCE_P_NUMBER 2 #define SCE_P_STRING 3 #define SCE_P_CHARACTER 4 #define SCE_P_WORD 5 #define SCE_P_TRIPLE 6 #define SCE_P_TRIPLEDOUBLE 7 #define SCE_P_CLASSNAME 8 #define SCE_P_DEFNAME 9 #define SCE_P_OPERATOR 10 #define SCE_P_IDENTIFIER 11 #define SCE_P_COMMENTBLOCK 12 #define SCE_P_STRINGEOL 13 #define SCE_P_WORD2 14 #define SCE_P_DECORATOR 15 #define SCE_C_DEFAULT 0 #define SCE_C_COMMENT 1 #define SCE_C_COMMENTLINE 2 #define SCE_C_COMMENTDOC 3 #define SCE_C_NUMBER 4 #define SCE_C_WORD 5 #define SCE_C_STRING 6 #define SCE_C_CHARACTER 7 #define SCE_C_UUID 8 #define SCE_C_PREPROCESSOR 9 #define SCE_C_OPERATOR 10 #define SCE_C_IDENTIFIER 11 #define SCE_C_STRINGEOL 12 #define SCE_C_VERBATIM 13 #define SCE_C_REGEX 14 #define SCE_C_COMMENTLINEDOC 15 #define SCE_C_WORD2 16 #define SCE_C_COMMENTDOCKEYWORD 17 #define SCE_C_COMMENTDOCKEYWORDERROR 18 #define SCE_C_GLOBALCLASS 19 #define SCE_C_STRINGRAW 20 #define SCE_C_TRIPLEVERBATIM 21 #define SCE_C_HASHQUOTEDSTRING 22 #define SCE_C_PREPROCESSORCOMMENT 23 #define SCE_D_DEFAULT 0 #define SCE_D_COMMENT 1 #define SCE_D_COMMENTLINE 2 #define SCE_D_COMMENTDOC 3 #define SCE_D_COMMENTNESTED 4 #define SCE_D_NUMBER 5 #define SCE_D_WORD 6 #define SCE_D_WORD2 7 #define SCE_D_WORD3 8 #define SCE_D_TYPEDEF 9 #define SCE_D_STRING 10 #define SCE_D_STRINGEOL 11 #define SCE_D_CHARACTER 12 #define SCE_D_OPERATOR 13 #define SCE_D_IDENTIFIER 14 #define SCE_D_COMMENTLINEDOC 15 #define SCE_D_COMMENTDOCKEYWORD 16 #define SCE_D_COMMENTDOCKEYWORDERROR 17 #define SCE_D_STRINGB 18 #define SCE_D_STRINGR 19 #define SCE_D_WORD5 20 #define SCE_D_WORD6 21 #define SCE_D_WORD7 22 #define SCE_TCL_DEFAULT 0 #define SCE_TCL_COMMENT 1 #define SCE_TCL_COMMENTLINE 2 #define SCE_TCL_NUMBER 3 #define SCE_TCL_WORD_IN_QUOTE 4 #define SCE_TCL_IN_QUOTE 5 #define SCE_TCL_OPERATOR 6 #define SCE_TCL_IDENTIFIER 7 #define SCE_TCL_SUBSTITUTION 8 #define SCE_TCL_SUB_BRACE 9 #define SCE_TCL_MODIFIER 10 #define SCE_TCL_EXPAND 11 #define SCE_TCL_WORD 12 #define SCE_TCL_WORD2 13 #define SCE_TCL_WORD3 14 #define SCE_TCL_WORD4 15 #define SCE_TCL_WORD5 16 #define SCE_TCL_WORD6 17 #define SCE_TCL_WORD7 18 #define SCE_TCL_WORD8 19 #define SCE_TCL_COMMENT_BOX 20 #define SCE_TCL_BLOCK_COMMENT 21 #define SCE_H_DEFAULT 0 #define SCE_H_TAG 1 #define SCE_H_TAGUNKNOWN 2 #define SCE_H_ATTRIBUTE 3 #define SCE_H_ATTRIBUTEUNKNOWN 4 #define SCE_H_NUMBER 5 #define SCE_H_DOUBLESTRING 6 #define SCE_H_SINGLESTRING 7 #define SCE_H_OTHER 8 #define SCE_H_COMMENT 9 #define SCE_H_ENTITY 10 #define SCE_H_TAGEND 11 #define SCE_H_XMLSTART 12 #define SCE_H_XMLEND 13 #define SCE_H_SCRIPT 14 #define SCE_H_ASP 15 #define SCE_H_ASPAT 16 #define SCE_H_CDATA 17 #define SCE_H_QUESTION 18 #define SCE_H_VALUE 19 #define SCE_H_XCCOMMENT 20 #define SCE_H_SGML_DEFAULT 21 #define SCE_H_SGML_COMMAND 22 #define SCE_H_SGML_1ST_PARAM 23 #define SCE_H_SGML_DOUBLESTRING 24 #define SCE_H_SGML_SIMPLESTRING 25 #define SCE_H_SGML_ERROR 26 #define SCE_H_SGML_SPECIAL 27 #define SCE_H_SGML_ENTITY 28 #define SCE_H_SGML_COMMENT 29 #define SCE_H_SGML_1ST_PARAM_COMMENT 30 #define SCE_H_SGML_BLOCK_DEFAULT 31 #define SCE_HJ_START 40 #define SCE_HJ_DEFAULT 41 #define SCE_HJ_COMMENT 42 #define SCE_HJ_COMMENTLINE 43 #define SCE_HJ_COMMENTDOC 44 #define SCE_HJ_NUMBER 45 #define SCE_HJ_WORD 46 #define SCE_HJ_KEYWORD 47 #define SCE_HJ_DOUBLESTRING 48 #define SCE_HJ_SINGLESTRING 49 #define SCE_HJ_SYMBOLS 50 #define SCE_HJ_STRINGEOL 51 #define SCE_HJ_REGEX 52 #define SCE_HJA_START 55 #define SCE_HJA_DEFAULT 56 #define SCE_HJA_COMMENT 57 #define SCE_HJA_COMMENTLINE 58 #define SCE_HJA_COMMENTDOC 59 #define SCE_HJA_NUMBER 60 #define SCE_HJA_WORD 61 #define SCE_HJA_KEYWORD 62 #define SCE_HJA_DOUBLESTRING 63 #define SCE_HJA_SINGLESTRING 64 #define SCE_HJA_SYMBOLS 65 #define SCE_HJA_STRINGEOL 66 #define SCE_HJA_REGEX 67 #define SCE_HB_START 70 #define SCE_HB_DEFAULT 71 #define SCE_HB_COMMENTLINE 72 #define SCE_HB_NUMBER 73 #define SCE_HB_WORD 74 #define SCE_HB_STRING 75 #define SCE_HB_IDENTIFIER 76 #define SCE_HB_STRINGEOL 77 #define SCE_HBA_START 80 #define SCE_HBA_DEFAULT 81 #define SCE_HBA_COMMENTLINE 82 #define SCE_HBA_NUMBER 83 #define SCE_HBA_WORD 84 #define SCE_HBA_STRING 85 #define SCE_HBA_IDENTIFIER 86 #define SCE_HBA_STRINGEOL 87 #define SCE_HP_START 90 #define SCE_HP_DEFAULT 91 #define SCE_HP_COMMENTLINE 92 #define SCE_HP_NUMBER 93 #define SCE_HP_STRING 94 #define SCE_HP_CHARACTER 95 #define SCE_HP_WORD 96 #define SCE_HP_TRIPLE 97 #define SCE_HP_TRIPLEDOUBLE 98 #define SCE_HP_CLASSNAME 99 #define SCE_HP_DEFNAME 100 #define SCE_HP_OPERATOR 101 #define SCE_HP_IDENTIFIER 102 #define SCE_HPHP_COMPLEX_VARIABLE 104 #define SCE_HPA_START 105 #define SCE_HPA_DEFAULT 106 #define SCE_HPA_COMMENTLINE 107 #define SCE_HPA_NUMBER 108 #define SCE_HPA_STRING 109 #define SCE_HPA_CHARACTER 110 #define SCE_HPA_WORD 111 #define SCE_HPA_TRIPLE 112 #define SCE_HPA_TRIPLEDOUBLE 113 #define SCE_HPA_CLASSNAME 114 #define SCE_HPA_DEFNAME 115 #define SCE_HPA_OPERATOR 116 #define SCE_HPA_IDENTIFIER 117 #define SCE_HPHP_DEFAULT 118 #define SCE_HPHP_HSTRING 119 #define SCE_HPHP_SIMPLESTRING 120 #define SCE_HPHP_WORD 121 #define SCE_HPHP_NUMBER 122 #define SCE_HPHP_VARIABLE 123 #define SCE_HPHP_COMMENT 124 #define SCE_HPHP_COMMENTLINE 125 #define SCE_HPHP_HSTRING_VARIABLE 126 #define SCE_HPHP_OPERATOR 127 #define SCE_PL_DEFAULT 0 #define SCE_PL_ERROR 1 #define SCE_PL_COMMENTLINE 2 #define SCE_PL_POD 3 #define SCE_PL_NUMBER 4 #define SCE_PL_WORD 5 #define SCE_PL_STRING 6 #define SCE_PL_CHARACTER 7 #define SCE_PL_PUNCTUATION 8 #define SCE_PL_PREPROCESSOR 9 #define SCE_PL_OPERATOR 10 #define SCE_PL_IDENTIFIER 11 #define SCE_PL_SCALAR 12 #define SCE_PL_ARRAY 13 #define SCE_PL_HASH 14 #define SCE_PL_SYMBOLTABLE 15 #define SCE_PL_VARIABLE_INDEXER 16 #define SCE_PL_REGEX 17 #define SCE_PL_REGSUBST 18 #define SCE_PL_LONGQUOTE 19 #define SCE_PL_BACKTICKS 20 #define SCE_PL_DATASECTION 21 #define SCE_PL_HERE_DELIM 22 #define SCE_PL_HERE_Q 23 #define SCE_PL_HERE_QQ 24 #define SCE_PL_HERE_QX 25 #define SCE_PL_STRING_Q 26 #define SCE_PL_STRING_QQ 27 #define SCE_PL_STRING_QX 28 #define SCE_PL_STRING_QR 29 #define SCE_PL_STRING_QW 30 #define SCE_PL_POD_VERB 31 #define SCE_PL_SUB_PROTOTYPE 40 #define SCE_PL_FORMAT_IDENT 41 #define SCE_PL_FORMAT 42 #define SCE_PL_STRING_VAR 43 #define SCE_PL_XLAT 44 #define SCE_PL_REGEX_VAR 54 #define SCE_PL_REGSUBST_VAR 55 #define SCE_PL_BACKTICKS_VAR 57 #define SCE_PL_HERE_QQ_VAR 61 #define SCE_PL_HERE_QX_VAR 62 #define SCE_PL_STRING_QQ_VAR 64 #define SCE_PL_STRING_QX_VAR 65 #define SCE_PL_STRING_QR_VAR 66 #define SCE_RB_DEFAULT 0 #define SCE_RB_ERROR 1 #define SCE_RB_COMMENTLINE 2 #define SCE_RB_POD 3 #define SCE_RB_NUMBER 4 #define SCE_RB_WORD 5 #define SCE_RB_STRING 6 #define SCE_RB_CHARACTER 7 #define SCE_RB_CLASSNAME 8 #define SCE_RB_DEFNAME 9 #define SCE_RB_OPERATOR 10 #define SCE_RB_IDENTIFIER 11 #define SCE_RB_REGEX 12 #define SCE_RB_GLOBAL 13 #define SCE_RB_SYMBOL 14 #define SCE_RB_MODULE_NAME 15 #define SCE_RB_INSTANCE_VAR 16 #define SCE_RB_CLASS_VAR 17 #define SCE_RB_BACKTICKS 18 #define SCE_RB_DATASECTION 19 #define SCE_RB_HERE_DELIM 20 #define SCE_RB_HERE_Q 21 #define SCE_RB_HERE_QQ 22 #define SCE_RB_HERE_QX 23 #define SCE_RB_STRING_Q 24 #define SCE_RB_STRING_QQ 25 #define SCE_RB_STRING_QX 26 #define SCE_RB_STRING_QR 27 #define SCE_RB_STRING_QW 28 #define SCE_RB_WORD_DEMOTED 29 #define SCE_RB_STDIN 30 #define SCE_RB_STDOUT 31 #define SCE_RB_STDERR 40 #define SCE_RB_UPPER_BOUND 41 #define SCE_B_DEFAULT 0 #define SCE_B_COMMENT 1 #define SCE_B_NUMBER 2 #define SCE_B_KEYWORD 3 #define SCE_B_STRING 4 #define SCE_B_PREPROCESSOR 5 #define SCE_B_OPERATOR 6 #define SCE_B_IDENTIFIER 7 #define SCE_B_DATE 8 #define SCE_B_STRINGEOL 9 #define SCE_B_KEYWORD2 10 #define SCE_B_KEYWORD3 11 #define SCE_B_KEYWORD4 12 #define SCE_B_CONSTANT 13 #define SCE_B_ASM 14 #define SCE_B_LABEL 15 #define SCE_B_ERROR 16 #define SCE_B_HEXNUMBER 17 #define SCE_B_BINNUMBER 18 #define SCE_PROPS_DEFAULT 0 #define SCE_PROPS_COMMENT 1 #define SCE_PROPS_SECTION 2 #define SCE_PROPS_ASSIGNMENT 3 #define SCE_PROPS_DEFVAL 4 #define SCE_PROPS_KEY 5 #define SCE_L_DEFAULT 0 #define SCE_L_COMMAND 1 #define SCE_L_TAG 2 #define SCE_L_MATH 3 #define SCE_L_COMMENT 4 #define SCE_L_TAG2 5 #define SCE_L_MATH2 6 #define SCE_L_COMMENT2 7 #define SCE_L_VERBATIM 8 #define SCE_L_SHORTCMD 9 #define SCE_L_SPECIAL 10 #define SCE_L_CMDOPT 11 #define SCE_L_ERROR 12 #define SCE_LUA_DEFAULT 0 #define SCE_LUA_COMMENT 1 #define SCE_LUA_COMMENTLINE 2 #define SCE_LUA_COMMENTDOC 3 #define SCE_LUA_NUMBER 4 #define SCE_LUA_WORD 5 #define SCE_LUA_STRING 6 #define SCE_LUA_CHARACTER 7 #define SCE_LUA_LITERALSTRING 8 #define SCE_LUA_PREPROCESSOR 9 #define SCE_LUA_OPERATOR 10 #define SCE_LUA_IDENTIFIER 11 #define SCE_LUA_STRINGEOL 12 #define SCE_LUA_WORD2 13 #define SCE_LUA_WORD3 14 #define SCE_LUA_WORD4 15 #define SCE_LUA_WORD5 16 #define SCE_LUA_WORD6 17 #define SCE_LUA_WORD7 18 #define SCE_LUA_WORD8 19 #define SCE_LUA_LABEL 20 #define SCE_ERR_DEFAULT 0 #define SCE_ERR_PYTHON 1 #define SCE_ERR_GCC 2 #define SCE_ERR_MS 3 #define SCE_ERR_CMD 4 #define SCE_ERR_BORLAND 5 #define SCE_ERR_PERL 6 #define SCE_ERR_NET 7 #define SCE_ERR_LUA 8 #define SCE_ERR_CTAG 9 #define SCE_ERR_DIFF_CHANGED 10 #define SCE_ERR_DIFF_ADDITION 11 #define SCE_ERR_DIFF_DELETION 12 #define SCE_ERR_DIFF_MESSAGE 13 #define SCE_ERR_PHP 14 #define SCE_ERR_ELF 15 #define SCE_ERR_IFC 16 #define SCE_ERR_IFORT 17 #define SCE_ERR_ABSF 18 #define SCE_ERR_TIDY 19 #define SCE_ERR_JAVA_STACK 20 #define SCE_ERR_VALUE 21 #define SCE_ERR_GCC_INCLUDED_FROM 22 #define SCE_BAT_DEFAULT 0 #define SCE_BAT_COMMENT 1 #define SCE_BAT_WORD 2 #define SCE_BAT_LABEL 3 #define SCE_BAT_HIDE 4 #define SCE_BAT_COMMAND 5 #define SCE_BAT_IDENTIFIER 6 #define SCE_BAT_OPERATOR 7 #define SCE_TCMD_DEFAULT 0 #define SCE_TCMD_COMMENT 1 #define SCE_TCMD_WORD 2 #define SCE_TCMD_LABEL 3 #define SCE_TCMD_HIDE 4 #define SCE_TCMD_COMMAND 5 #define SCE_TCMD_IDENTIFIER 6 #define SCE_TCMD_OPERATOR 7 #define SCE_TCMD_ENVIRONMENT 8 #define SCE_TCMD_EXPANSION 9 #define SCE_TCMD_CLABEL 10 #define SCE_MAKE_DEFAULT 0 #define SCE_MAKE_COMMENT 1 #define SCE_MAKE_PREPROCESSOR 2 #define SCE_MAKE_IDENTIFIER 3 #define SCE_MAKE_OPERATOR 4 #define SCE_MAKE_TARGET 5 #define SCE_MAKE_IDEOL 9 #define SCE_DIFF_DEFAULT 0 #define SCE_DIFF_COMMENT 1 #define SCE_DIFF_COMMAND 2 #define SCE_DIFF_HEADER 3 #define SCE_DIFF_POSITION 4 #define SCE_DIFF_DELETED 5 #define SCE_DIFF_ADDED 6 #define SCE_DIFF_CHANGED 7 #define SCE_CONF_DEFAULT 0 #define SCE_CONF_COMMENT 1 #define SCE_CONF_NUMBER 2 #define SCE_CONF_IDENTIFIER 3 #define SCE_CONF_EXTENSION 4 #define SCE_CONF_PARAMETER 5 #define SCE_CONF_STRING 6 #define SCE_CONF_OPERATOR 7 #define SCE_CONF_IP 8 #define SCE_CONF_DIRECTIVE 9 #define SCE_AVE_DEFAULT 0 #define SCE_AVE_COMMENT 1 #define SCE_AVE_NUMBER 2 #define SCE_AVE_WORD 3 #define SCE_AVE_STRING 6 #define SCE_AVE_ENUM 7 #define SCE_AVE_STRINGEOL 8 #define SCE_AVE_IDENTIFIER 9 #define SCE_AVE_OPERATOR 10 #define SCE_AVE_WORD1 11 #define SCE_AVE_WORD2 12 #define SCE_AVE_WORD3 13 #define SCE_AVE_WORD4 14 #define SCE_AVE_WORD5 15 #define SCE_AVE_WORD6 16 #define SCE_ADA_DEFAULT 0 #define SCE_ADA_WORD 1 #define SCE_ADA_IDENTIFIER 2 #define SCE_ADA_NUMBER 3 #define SCE_ADA_DELIMITER 4 #define SCE_ADA_CHARACTER 5 #define SCE_ADA_CHARACTEREOL 6 #define SCE_ADA_STRING 7 #define SCE_ADA_STRINGEOL 8 #define SCE_ADA_LABEL 9 #define SCE_ADA_COMMENTLINE 10 #define SCE_ADA_ILLEGAL 11 #define SCE_BAAN_DEFAULT 0 #define SCE_BAAN_COMMENT 1 #define SCE_BAAN_COMMENTDOC 2 #define SCE_BAAN_NUMBER 3 #define SCE_BAAN_WORD 4 #define SCE_BAAN_STRING 5 #define SCE_BAAN_PREPROCESSOR 6 #define SCE_BAAN_OPERATOR 7 #define SCE_BAAN_IDENTIFIER 8 #define SCE_BAAN_STRINGEOL 9 #define SCE_BAAN_WORD2 10 #define SCE_LISP_DEFAULT 0 #define SCE_LISP_COMMENT 1 #define SCE_LISP_NUMBER 2 #define SCE_LISP_KEYWORD 3 #define SCE_LISP_KEYWORD_KW 4 #define SCE_LISP_SYMBOL 5 #define SCE_LISP_STRING 6 #define SCE_LISP_STRINGEOL 8 #define SCE_LISP_IDENTIFIER 9 #define SCE_LISP_OPERATOR 10 #define SCE_LISP_SPECIAL 11 #define SCE_LISP_MULTI_COMMENT 12 #define SCE_EIFFEL_DEFAULT 0 #define SCE_EIFFEL_COMMENTLINE 1 #define SCE_EIFFEL_NUMBER 2 #define SCE_EIFFEL_WORD 3 #define SCE_EIFFEL_STRING 4 #define SCE_EIFFEL_CHARACTER 5 #define SCE_EIFFEL_OPERATOR 6 #define SCE_EIFFEL_IDENTIFIER 7 #define SCE_EIFFEL_STRINGEOL 8 #define SCE_NNCRONTAB_DEFAULT 0 #define SCE_NNCRONTAB_COMMENT 1 #define SCE_NNCRONTAB_TASK 2 #define SCE_NNCRONTAB_SECTION 3 #define SCE_NNCRONTAB_KEYWORD 4 #define SCE_NNCRONTAB_MODIFIER 5 #define SCE_NNCRONTAB_ASTERISK 6 #define SCE_NNCRONTAB_NUMBER 7 #define SCE_NNCRONTAB_STRING 8 #define SCE_NNCRONTAB_ENVIRONMENT 9 #define SCE_NNCRONTAB_IDENTIFIER 10 #define SCE_FORTH_DEFAULT 0 #define SCE_FORTH_COMMENT 1 #define SCE_FORTH_COMMENT_ML 2 #define SCE_FORTH_IDENTIFIER 3 #define SCE_FORTH_CONTROL 4 #define SCE_FORTH_KEYWORD 5 #define SCE_FORTH_DEFWORD 6 #define SCE_FORTH_PREWORD1 7 #define SCE_FORTH_PREWORD2 8 #define SCE_FORTH_NUMBER 9 #define SCE_FORTH_STRING 10 #define SCE_FORTH_LOCALE 11 #define SCE_MATLAB_DEFAULT 0 #define SCE_MATLAB_COMMENT 1 #define SCE_MATLAB_COMMAND 2 #define SCE_MATLAB_NUMBER 3 #define SCE_MATLAB_KEYWORD 4 #define SCE_MATLAB_STRING 5 #define SCE_MATLAB_OPERATOR 6 #define SCE_MATLAB_IDENTIFIER 7 #define SCE_MATLAB_DOUBLEQUOTESTRING 8 #define SCE_SCRIPTOL_DEFAULT 0 #define SCE_SCRIPTOL_WHITE 1 #define SCE_SCRIPTOL_COMMENTLINE 2 #define SCE_SCRIPTOL_PERSISTENT 3 #define SCE_SCRIPTOL_CSTYLE 4 #define SCE_SCRIPTOL_COMMENTBLOCK 5 #define SCE_SCRIPTOL_NUMBER 6 #define SCE_SCRIPTOL_STRING 7 #define SCE_SCRIPTOL_CHARACTER 8 #define SCE_SCRIPTOL_STRINGEOL 9 #define SCE_SCRIPTOL_KEYWORD 10 #define SCE_SCRIPTOL_OPERATOR 11 #define SCE_SCRIPTOL_IDENTIFIER 12 #define SCE_SCRIPTOL_TRIPLE 13 #define SCE_SCRIPTOL_CLASSNAME 14 #define SCE_SCRIPTOL_PREPROCESSOR 15 #define SCE_ASM_DEFAULT 0 #define SCE_ASM_COMMENT 1 #define SCE_ASM_NUMBER 2 #define SCE_ASM_STRING 3 #define SCE_ASM_OPERATOR 4 #define SCE_ASM_IDENTIFIER 5 #define SCE_ASM_CPUINSTRUCTION 6 #define SCE_ASM_MATHINSTRUCTION 7 #define SCE_ASM_REGISTER 8 #define SCE_ASM_DIRECTIVE 9 #define SCE_ASM_DIRECTIVEOPERAND 10 #define SCE_ASM_COMMENTBLOCK 11 #define SCE_ASM_CHARACTER 12 #define SCE_ASM_STRINGEOL 13 #define SCE_ASM_EXTINSTRUCTION 14 #define SCE_ASM_COMMENTDIRECTIVE 15 #define SCE_F_DEFAULT 0 #define SCE_F_COMMENT 1 #define SCE_F_NUMBER 2 #define SCE_F_STRING1 3 #define SCE_F_STRING2 4 #define SCE_F_STRINGEOL 5 #define SCE_F_OPERATOR 6 #define SCE_F_IDENTIFIER 7 #define SCE_F_WORD 8 #define SCE_F_WORD2 9 #define SCE_F_WORD3 10 #define SCE_F_PREPROCESSOR 11 #define SCE_F_OPERATOR2 12 #define SCE_F_LABEL 13 #define SCE_F_CONTINUATION 14 #define SCE_CSS_DEFAULT 0 #define SCE_CSS_TAG 1 #define SCE_CSS_CLASS 2 #define SCE_CSS_PSEUDOCLASS 3 #define SCE_CSS_UNKNOWN_PSEUDOCLASS 4 #define SCE_CSS_OPERATOR 5 #define SCE_CSS_IDENTIFIER 6 #define SCE_CSS_UNKNOWN_IDENTIFIER 7 #define SCE_CSS_VALUE 8 #define SCE_CSS_COMMENT 9 #define SCE_CSS_ID 10 #define SCE_CSS_IMPORTANT 11 #define SCE_CSS_DIRECTIVE 12 #define SCE_CSS_DOUBLESTRING 13 #define SCE_CSS_SINGLESTRING 14 #define SCE_CSS_IDENTIFIER2 15 #define SCE_CSS_ATTRIBUTE 16 #define SCE_CSS_IDENTIFIER3 17 #define SCE_CSS_PSEUDOELEMENT 18 #define SCE_CSS_EXTENDED_IDENTIFIER 19 #define SCE_CSS_EXTENDED_PSEUDOCLASS 20 #define SCE_CSS_EXTENDED_PSEUDOELEMENT 21 #define SCE_CSS_MEDIA 22 #define SCE_CSS_VARIABLE 23 #define SCE_POV_DEFAULT 0 #define SCE_POV_COMMENT 1 #define SCE_POV_COMMENTLINE 2 #define SCE_POV_NUMBER 3 #define SCE_POV_OPERATOR 4 #define SCE_POV_IDENTIFIER 5 #define SCE_POV_STRING 6 #define SCE_POV_STRINGEOL 7 #define SCE_POV_DIRECTIVE 8 #define SCE_POV_BADDIRECTIVE 9 #define SCE_POV_WORD2 10 #define SCE_POV_WORD3 11 #define SCE_POV_WORD4 12 #define SCE_POV_WORD5 13 #define SCE_POV_WORD6 14 #define SCE_POV_WORD7 15 #define SCE_POV_WORD8 16 #define SCE_LOUT_DEFAULT 0 #define SCE_LOUT_COMMENT 1 #define SCE_LOUT_NUMBER 2 #define SCE_LOUT_WORD 3 #define SCE_LOUT_WORD2 4 #define SCE_LOUT_WORD3 5 #define SCE_LOUT_WORD4 6 #define SCE_LOUT_STRING 7 #define SCE_LOUT_OPERATOR 8 #define SCE_LOUT_IDENTIFIER 9 #define SCE_LOUT_STRINGEOL 10 #define SCE_ESCRIPT_DEFAULT 0 #define SCE_ESCRIPT_COMMENT 1 #define SCE_ESCRIPT_COMMENTLINE 2 #define SCE_ESCRIPT_COMMENTDOC 3 #define SCE_ESCRIPT_NUMBER 4 #define SCE_ESCRIPT_WORD 5 #define SCE_ESCRIPT_STRING 6 #define SCE_ESCRIPT_OPERATOR 7 #define SCE_ESCRIPT_IDENTIFIER 8 #define SCE_ESCRIPT_BRACE 9 #define SCE_ESCRIPT_WORD2 10 #define SCE_ESCRIPT_WORD3 11 #define SCE_PS_DEFAULT 0 #define SCE_PS_COMMENT 1 #define SCE_PS_DSC_COMMENT 2 #define SCE_PS_DSC_VALUE 3 #define SCE_PS_NUMBER 4 #define SCE_PS_NAME 5 #define SCE_PS_KEYWORD 6 #define SCE_PS_LITERAL 7 #define SCE_PS_IMMEVAL 8 #define SCE_PS_PAREN_ARRAY 9 #define SCE_PS_PAREN_DICT 10 #define SCE_PS_PAREN_PROC 11 #define SCE_PS_TEXT 12 #define SCE_PS_HEXSTRING 13 #define SCE_PS_BASE85STRING 14 #define SCE_PS_BADSTRINGCHAR 15 #define SCE_NSIS_DEFAULT 0 #define SCE_NSIS_COMMENT 1 #define SCE_NSIS_STRINGDQ 2 #define SCE_NSIS_STRINGLQ 3 #define SCE_NSIS_STRINGRQ 4 #define SCE_NSIS_FUNCTION 5 #define SCE_NSIS_VARIABLE 6 #define SCE_NSIS_LABEL 7 #define SCE_NSIS_USERDEFINED 8 #define SCE_NSIS_SECTIONDEF 9 #define SCE_NSIS_SUBSECTIONDEF 10 #define SCE_NSIS_IFDEFINEDEF 11 #define SCE_NSIS_MACRODEF 12 #define SCE_NSIS_STRINGVAR 13 #define SCE_NSIS_NUMBER 14 #define SCE_NSIS_SECTIONGROUP 15 #define SCE_NSIS_PAGEEX 16 #define SCE_NSIS_FUNCTIONDEF 17 #define SCE_NSIS_COMMENTBOX 18 #define SCE_MMIXAL_LEADWS 0 #define SCE_MMIXAL_COMMENT 1 #define SCE_MMIXAL_LABEL 2 #define SCE_MMIXAL_OPCODE 3 #define SCE_MMIXAL_OPCODE_PRE 4 #define SCE_MMIXAL_OPCODE_VALID 5 #define SCE_MMIXAL_OPCODE_UNKNOWN 6 #define SCE_MMIXAL_OPCODE_POST 7 #define SCE_MMIXAL_OPERANDS 8 #define SCE_MMIXAL_NUMBER 9 #define SCE_MMIXAL_REF 10 #define SCE_MMIXAL_CHAR 11 #define SCE_MMIXAL_STRING 12 #define SCE_MMIXAL_REGISTER 13 #define SCE_MMIXAL_HEX 14 #define SCE_MMIXAL_OPERATOR 15 #define SCE_MMIXAL_SYMBOL 16 #define SCE_MMIXAL_INCLUDE 17 #define SCE_CLW_DEFAULT 0 #define SCE_CLW_LABEL 1 #define SCE_CLW_COMMENT 2 #define SCE_CLW_STRING 3 #define SCE_CLW_USER_IDENTIFIER 4 #define SCE_CLW_INTEGER_CONSTANT 5 #define SCE_CLW_REAL_CONSTANT 6 #define SCE_CLW_PICTURE_STRING 7 #define SCE_CLW_KEYWORD 8 #define SCE_CLW_COMPILER_DIRECTIVE 9 #define SCE_CLW_RUNTIME_EXPRESSIONS 10 #define SCE_CLW_BUILTIN_PROCEDURES_FUNCTION 11 #define SCE_CLW_STRUCTURE_DATA_TYPE 12 #define SCE_CLW_ATTRIBUTE 13 #define SCE_CLW_STANDARD_EQUATE 14 #define SCE_CLW_ERROR 15 #define SCE_CLW_DEPRECATED 16 #define SCE_LOT_DEFAULT 0 #define SCE_LOT_HEADER 1 #define SCE_LOT_BREAK 2 #define SCE_LOT_SET 3 #define SCE_LOT_PASS 4 #define SCE_LOT_FAIL 5 #define SCE_LOT_ABORT 6 #define SCE_YAML_DEFAULT 0 #define SCE_YAML_COMMENT 1 #define SCE_YAML_IDENTIFIER 2 #define SCE_YAML_KEYWORD 3 #define SCE_YAML_NUMBER 4 #define SCE_YAML_REFERENCE 5 #define SCE_YAML_DOCUMENT 6 #define SCE_YAML_TEXT 7 #define SCE_YAML_ERROR 8 #define SCE_YAML_OPERATOR 9 #define SCE_TEX_DEFAULT 0 #define SCE_TEX_SPECIAL 1 #define SCE_TEX_GROUP 2 #define SCE_TEX_SYMBOL 3 #define SCE_TEX_COMMAND 4 #define SCE_TEX_TEXT 5 #define SCE_METAPOST_DEFAULT 0 #define SCE_METAPOST_SPECIAL 1 #define SCE_METAPOST_GROUP 2 #define SCE_METAPOST_SYMBOL 3 #define SCE_METAPOST_COMMAND 4 #define SCE_METAPOST_TEXT 5 #define SCE_METAPOST_EXTRA 6 #define SCE_ERLANG_DEFAULT 0 #define SCE_ERLANG_COMMENT 1 #define SCE_ERLANG_VARIABLE 2 #define SCE_ERLANG_NUMBER 3 #define SCE_ERLANG_KEYWORD 4 #define SCE_ERLANG_STRING 5 #define SCE_ERLANG_OPERATOR 6 #define SCE_ERLANG_ATOM 7 #define SCE_ERLANG_FUNCTION_NAME 8 #define SCE_ERLANG_CHARACTER 9 #define SCE_ERLANG_MACRO 10 #define SCE_ERLANG_RECORD 11 #define SCE_ERLANG_PREPROC 12 #define SCE_ERLANG_NODE_NAME 13 #define SCE_ERLANG_COMMENT_FUNCTION 14 #define SCE_ERLANG_COMMENT_MODULE 15 #define SCE_ERLANG_COMMENT_DOC 16 #define SCE_ERLANG_COMMENT_DOC_MACRO 17 #define SCE_ERLANG_ATOM_QUOTED 18 #define SCE_ERLANG_MACRO_QUOTED 19 #define SCE_ERLANG_RECORD_QUOTED 20 #define SCE_ERLANG_NODE_NAME_QUOTED 21 #define SCE_ERLANG_BIFS 22 #define SCE_ERLANG_MODULES 23 #define SCE_ERLANG_MODULES_ATT 24 #define SCE_ERLANG_UNKNOWN 31 #define SCE_MSSQL_DEFAULT 0 #define SCE_MSSQL_COMMENT 1 #define SCE_MSSQL_LINE_COMMENT 2 #define SCE_MSSQL_NUMBER 3 #define SCE_MSSQL_STRING 4 #define SCE_MSSQL_OPERATOR 5 #define SCE_MSSQL_IDENTIFIER 6 #define SCE_MSSQL_VARIABLE 7 #define SCE_MSSQL_COLUMN_NAME 8 #define SCE_MSSQL_STATEMENT 9 #define SCE_MSSQL_DATATYPE 10 #define SCE_MSSQL_SYSTABLE 11 #define SCE_MSSQL_GLOBAL_VARIABLE 12 #define SCE_MSSQL_FUNCTION 13 #define SCE_MSSQL_STORED_PROCEDURE 14 #define SCE_MSSQL_DEFAULT_PREF_DATATYPE 15 #define SCE_MSSQL_COLUMN_NAME_2 16 #define SCE_V_DEFAULT 0 #define SCE_V_COMMENT 1 #define SCE_V_COMMENTLINE 2 #define SCE_V_COMMENTLINEBANG 3 #define SCE_V_NUMBER 4 #define SCE_V_WORD 5 #define SCE_V_STRING 6 #define SCE_V_WORD2 7 #define SCE_V_WORD3 8 #define SCE_V_PREPROCESSOR 9 #define SCE_V_OPERATOR 10 #define SCE_V_IDENTIFIER 11 #define SCE_V_STRINGEOL 12 #define SCE_V_USER 19 #define SCE_KIX_DEFAULT 0 #define SCE_KIX_COMMENT 1 #define SCE_KIX_STRING1 2 #define SCE_KIX_STRING2 3 #define SCE_KIX_NUMBER 4 #define SCE_KIX_VAR 5 #define SCE_KIX_MACRO 6 #define SCE_KIX_KEYWORD 7 #define SCE_KIX_FUNCTIONS 8 #define SCE_KIX_OPERATOR 9 #define SCE_KIX_IDENTIFIER 31 #define SCE_GC_DEFAULT 0 #define SCE_GC_COMMENTLINE 1 #define SCE_GC_COMMENTBLOCK 2 #define SCE_GC_GLOBAL 3 #define SCE_GC_EVENT 4 #define SCE_GC_ATTRIBUTE 5 #define SCE_GC_CONTROL 6 #define SCE_GC_COMMAND 7 #define SCE_GC_STRING 8 #define SCE_GC_OPERATOR 9 #define SCE_SN_DEFAULT 0 #define SCE_SN_CODE 1 #define SCE_SN_COMMENTLINE 2 #define SCE_SN_COMMENTLINEBANG 3 #define SCE_SN_NUMBER 4 #define SCE_SN_WORD 5 #define SCE_SN_STRING 6 #define SCE_SN_WORD2 7 #define SCE_SN_WORD3 8 #define SCE_SN_PREPROCESSOR 9 #define SCE_SN_OPERATOR 10 #define SCE_SN_IDENTIFIER 11 #define SCE_SN_STRINGEOL 12 #define SCE_SN_REGEXTAG 13 #define SCE_SN_SIGNAL 14 #define SCE_SN_USER 19 #define SCE_AU3_DEFAULT 0 #define SCE_AU3_COMMENT 1 #define SCE_AU3_COMMENTBLOCK 2 #define SCE_AU3_NUMBER 3 #define SCE_AU3_FUNCTION 4 #define SCE_AU3_KEYWORD 5 #define SCE_AU3_MACRO 6 #define SCE_AU3_STRING 7 #define SCE_AU3_OPERATOR 8 #define SCE_AU3_VARIABLE 9 #define SCE_AU3_SENT 10 #define SCE_AU3_PREPROCESSOR 11 #define SCE_AU3_SPECIAL 12 #define SCE_AU3_EXPAND 13 #define SCE_AU3_COMOBJ 14 #define SCE_AU3_UDF 15 #define SCE_APDL_DEFAULT 0 #define SCE_APDL_COMMENT 1 #define SCE_APDL_COMMENTBLOCK 2 #define SCE_APDL_NUMBER 3 #define SCE_APDL_STRING 4 #define SCE_APDL_OPERATOR 5 #define SCE_APDL_WORD 6 #define SCE_APDL_PROCESSOR 7 #define SCE_APDL_COMMAND 8 #define SCE_APDL_SLASHCOMMAND 9 #define SCE_APDL_STARCOMMAND 10 #define SCE_APDL_ARGUMENT 11 #define SCE_APDL_FUNCTION 12 #define SCE_SH_DEFAULT 0 #define SCE_SH_ERROR 1 #define SCE_SH_COMMENTLINE 2 #define SCE_SH_NUMBER 3 #define SCE_SH_WORD 4 #define SCE_SH_STRING 5 #define SCE_SH_CHARACTER 6 #define SCE_SH_OPERATOR 7 #define SCE_SH_IDENTIFIER 8 #define SCE_SH_SCALAR 9 #define SCE_SH_PARAM 10 #define SCE_SH_BACKTICKS 11 #define SCE_SH_HERE_DELIM 12 #define SCE_SH_HERE_Q 13 #define SCE_ASN1_DEFAULT 0 #define SCE_ASN1_COMMENT 1 #define SCE_ASN1_IDENTIFIER 2 #define SCE_ASN1_STRING 3 #define SCE_ASN1_OID 4 #define SCE_ASN1_SCALAR 5 #define SCE_ASN1_KEYWORD 6 #define SCE_ASN1_ATTRIBUTE 7 #define SCE_ASN1_DESCRIPTOR 8 #define SCE_ASN1_TYPE 9 #define SCE_ASN1_OPERATOR 10 #define SCE_VHDL_DEFAULT 0 #define SCE_VHDL_COMMENT 1 #define SCE_VHDL_COMMENTLINEBANG 2 #define SCE_VHDL_NUMBER 3 #define SCE_VHDL_STRING 4 #define SCE_VHDL_OPERATOR 5 #define SCE_VHDL_IDENTIFIER 6 #define SCE_VHDL_STRINGEOL 7 #define SCE_VHDL_KEYWORD 8 #define SCE_VHDL_STDOPERATOR 9 #define SCE_VHDL_ATTRIBUTE 10 #define SCE_VHDL_STDFUNCTION 11 #define SCE_VHDL_STDPACKAGE 12 #define SCE_VHDL_STDTYPE 13 #define SCE_VHDL_USERWORD 14 #define SCE_CAML_DEFAULT 0 #define SCE_CAML_IDENTIFIER 1 #define SCE_CAML_TAGNAME 2 #define SCE_CAML_KEYWORD 3 #define SCE_CAML_KEYWORD2 4 #define SCE_CAML_KEYWORD3 5 #define SCE_CAML_LINENUM 6 #define SCE_CAML_OPERATOR 7 #define SCE_CAML_NUMBER 8 #define SCE_CAML_CHAR 9 #define SCE_CAML_WHITE 10 #define SCE_CAML_STRING 11 #define SCE_CAML_COMMENT 12 #define SCE_CAML_COMMENT1 13 #define SCE_CAML_COMMENT2 14 #define SCE_CAML_COMMENT3 15 #define SCE_HA_DEFAULT 0 #define SCE_HA_IDENTIFIER 1 #define SCE_HA_KEYWORD 2 #define SCE_HA_NUMBER 3 #define SCE_HA_STRING 4 #define SCE_HA_CHARACTER 5 #define SCE_HA_CLASS 6 #define SCE_HA_MODULE 7 #define SCE_HA_CAPITAL 8 #define SCE_HA_DATA 9 #define SCE_HA_IMPORT 10 #define SCE_HA_OPERATOR 11 #define SCE_HA_INSTANCE 12 #define SCE_HA_COMMENTLINE 13 #define SCE_HA_COMMENTBLOCK 14 #define SCE_HA_COMMENTBLOCK2 15 #define SCE_HA_COMMENTBLOCK3 16 #define SCE_T3_DEFAULT 0 #define SCE_T3_X_DEFAULT 1 #define SCE_T3_PREPROCESSOR 2 #define SCE_T3_BLOCK_COMMENT 3 #define SCE_T3_LINE_COMMENT 4 #define SCE_T3_OPERATOR 5 #define SCE_T3_KEYWORD 6 #define SCE_T3_NUMBER 7 #define SCE_T3_IDENTIFIER 8 #define SCE_T3_S_STRING 9 #define SCE_T3_D_STRING 10 #define SCE_T3_X_STRING 11 #define SCE_T3_LIB_DIRECTIVE 12 #define SCE_T3_MSG_PARAM 13 #define SCE_T3_HTML_TAG 14 #define SCE_T3_HTML_DEFAULT 15 #define SCE_T3_HTML_STRING 16 #define SCE_T3_USER1 17 #define SCE_T3_USER2 18 #define SCE_T3_USER3 19 #define SCE_T3_BRACE 20 #define SCE_REBOL_DEFAULT 0 #define SCE_REBOL_COMMENTLINE 1 #define SCE_REBOL_COMMENTBLOCK 2 #define SCE_REBOL_PREFACE 3 #define SCE_REBOL_OPERATOR 4 #define SCE_REBOL_CHARACTER 5 #define SCE_REBOL_QUOTEDSTRING 6 #define SCE_REBOL_BRACEDSTRING 7 #define SCE_REBOL_NUMBER 8 #define SCE_REBOL_PAIR 9 #define SCE_REBOL_TUPLE 10 #define SCE_REBOL_BINARY 11 #define SCE_REBOL_MONEY 12 #define SCE_REBOL_ISSUE 13 #define SCE_REBOL_TAG 14 #define SCE_REBOL_FILE 15 #define SCE_REBOL_EMAIL 16 #define SCE_REBOL_URL 17 #define SCE_REBOL_DATE 18 #define SCE_REBOL_TIME 19 #define SCE_REBOL_IDENTIFIER 20 #define SCE_REBOL_WORD 21 #define SCE_REBOL_WORD2 22 #define SCE_REBOL_WORD3 23 #define SCE_REBOL_WORD4 24 #define SCE_REBOL_WORD5 25 #define SCE_REBOL_WORD6 26 #define SCE_REBOL_WORD7 27 #define SCE_REBOL_WORD8 28 #define SCE_SQL_DEFAULT 0 #define SCE_SQL_COMMENT 1 #define SCE_SQL_COMMENTLINE 2 #define SCE_SQL_COMMENTDOC 3 #define SCE_SQL_NUMBER 4 #define SCE_SQL_WORD 5 #define SCE_SQL_STRING 6 #define SCE_SQL_CHARACTER 7 #define SCE_SQL_SQLPLUS 8 #define SCE_SQL_SQLPLUS_PROMPT 9 #define SCE_SQL_OPERATOR 10 #define SCE_SQL_IDENTIFIER 11 #define SCE_SQL_SQLPLUS_COMMENT 13 #define SCE_SQL_COMMENTLINEDOC 15 #define SCE_SQL_WORD2 16 #define SCE_SQL_COMMENTDOCKEYWORD 17 #define SCE_SQL_COMMENTDOCKEYWORDERROR 18 #define SCE_SQL_USER1 19 #define SCE_SQL_USER2 20 #define SCE_SQL_USER3 21 #define SCE_SQL_USER4 22 #define SCE_SQL_QUOTEDIDENTIFIER 23 #define SCE_ST_DEFAULT 0 #define SCE_ST_STRING 1 #define SCE_ST_NUMBER 2 #define SCE_ST_COMMENT 3 #define SCE_ST_SYMBOL 4 #define SCE_ST_BINARY 5 #define SCE_ST_BOOL 6 #define SCE_ST_SELF 7 #define SCE_ST_SUPER 8 #define SCE_ST_NIL 9 #define SCE_ST_GLOBAL 10 #define SCE_ST_RETURN 11 #define SCE_ST_SPECIAL 12 #define SCE_ST_KWSEND 13 #define SCE_ST_ASSIGN 14 #define SCE_ST_CHARACTER 15 #define SCE_ST_SPEC_SEL 16 #define SCE_FS_DEFAULT 0 #define SCE_FS_COMMENT 1 #define SCE_FS_COMMENTLINE 2 #define SCE_FS_COMMENTDOC 3 #define SCE_FS_COMMENTLINEDOC 4 #define SCE_FS_COMMENTDOCKEYWORD 5 #define SCE_FS_COMMENTDOCKEYWORDERROR 6 #define SCE_FS_KEYWORD 7 #define SCE_FS_KEYWORD2 8 #define SCE_FS_KEYWORD3 9 #define SCE_FS_KEYWORD4 10 #define SCE_FS_NUMBER 11 #define SCE_FS_STRING 12 #define SCE_FS_PREPROCESSOR 13 #define SCE_FS_OPERATOR 14 #define SCE_FS_IDENTIFIER 15 #define SCE_FS_DATE 16 #define SCE_FS_STRINGEOL 17 #define SCE_FS_CONSTANT 18 #define SCE_FS_WORDOPERATOR 19 #define SCE_FS_DISABLEDCODE 20 #define SCE_FS_DEFAULT_C 21 #define SCE_FS_COMMENTDOC_C 22 #define SCE_FS_COMMENTLINEDOC_C 23 #define SCE_FS_KEYWORD_C 24 #define SCE_FS_KEYWORD2_C 25 #define SCE_FS_NUMBER_C 26 #define SCE_FS_STRING_C 27 #define SCE_FS_PREPROCESSOR_C 28 #define SCE_FS_OPERATOR_C 29 #define SCE_FS_IDENTIFIER_C 30 #define SCE_FS_STRINGEOL_C 31 #define SCE_CSOUND_DEFAULT 0 #define SCE_CSOUND_COMMENT 1 #define SCE_CSOUND_NUMBER 2 #define SCE_CSOUND_OPERATOR 3 #define SCE_CSOUND_INSTR 4 #define SCE_CSOUND_IDENTIFIER 5 #define SCE_CSOUND_OPCODE 6 #define SCE_CSOUND_HEADERSTMT 7 #define SCE_CSOUND_USERKEYWORD 8 #define SCE_CSOUND_COMMENTBLOCK 9 #define SCE_CSOUND_PARAM 10 #define SCE_CSOUND_ARATE_VAR 11 #define SCE_CSOUND_KRATE_VAR 12 #define SCE_CSOUND_IRATE_VAR 13 #define SCE_CSOUND_GLOBAL_VAR 14 #define SCE_CSOUND_STRINGEOL 15 #define SCE_INNO_DEFAULT 0 #define SCE_INNO_COMMENT 1 #define SCE_INNO_KEYWORD 2 #define SCE_INNO_PARAMETER 3 #define SCE_INNO_SECTION 4 #define SCE_INNO_PREPROC 5 #define SCE_INNO_INLINE_EXPANSION 6 #define SCE_INNO_COMMENT_PASCAL 7 #define SCE_INNO_KEYWORD_PASCAL 8 #define SCE_INNO_KEYWORD_USER 9 #define SCE_INNO_STRING_DOUBLE 10 #define SCE_INNO_STRING_SINGLE 11 #define SCE_INNO_IDENTIFIER 12 #define SCE_OPAL_SPACE 0 #define SCE_OPAL_COMMENT_BLOCK 1 #define SCE_OPAL_COMMENT_LINE 2 #define SCE_OPAL_INTEGER 3 #define SCE_OPAL_KEYWORD 4 #define SCE_OPAL_SORT 5 #define SCE_OPAL_STRING 6 #define SCE_OPAL_PAR 7 #define SCE_OPAL_BOOL_CONST 8 #define SCE_OPAL_DEFAULT 32 #define SCE_SPICE_DEFAULT 0 #define SCE_SPICE_IDENTIFIER 1 #define SCE_SPICE_KEYWORD 2 #define SCE_SPICE_KEYWORD2 3 #define SCE_SPICE_KEYWORD3 4 #define SCE_SPICE_NUMBER 5 #define SCE_SPICE_DELIMITER 6 #define SCE_SPICE_VALUE 7 #define SCE_SPICE_COMMENTLINE 8 #define SCE_CMAKE_DEFAULT 0 #define SCE_CMAKE_COMMENT 1 #define SCE_CMAKE_STRINGDQ 2 #define SCE_CMAKE_STRINGLQ 3 #define SCE_CMAKE_STRINGRQ 4 #define SCE_CMAKE_COMMANDS 5 #define SCE_CMAKE_PARAMETERS 6 #define SCE_CMAKE_VARIABLE 7 #define SCE_CMAKE_USERDEFINED 8 #define SCE_CMAKE_WHILEDEF 9 #define SCE_CMAKE_FOREACHDEF 10 #define SCE_CMAKE_IFDEFINEDEF 11 #define SCE_CMAKE_MACRODEF 12 #define SCE_CMAKE_STRINGVAR 13 #define SCE_CMAKE_NUMBER 14 #define SCE_GAP_DEFAULT 0 #define SCE_GAP_IDENTIFIER 1 #define SCE_GAP_KEYWORD 2 #define SCE_GAP_KEYWORD2 3 #define SCE_GAP_KEYWORD3 4 #define SCE_GAP_KEYWORD4 5 #define SCE_GAP_STRING 6 #define SCE_GAP_CHAR 7 #define SCE_GAP_OPERATOR 8 #define SCE_GAP_COMMENT 9 #define SCE_GAP_NUMBER 10 #define SCE_GAP_STRINGEOL 11 #define SCE_PLM_DEFAULT 0 #define SCE_PLM_COMMENT 1 #define SCE_PLM_STRING 2 #define SCE_PLM_NUMBER 3 #define SCE_PLM_IDENTIFIER 4 #define SCE_PLM_OPERATOR 5 #define SCE_PLM_CONTROL 6 #define SCE_PLM_KEYWORD 7 #define SCE_4GL_DEFAULT 0 #define SCE_4GL_NUMBER 1 #define SCE_4GL_WORD 2 #define SCE_4GL_STRING 3 #define SCE_4GL_CHARACTER 4 #define SCE_4GL_PREPROCESSOR 5 #define SCE_4GL_OPERATOR 6 #define SCE_4GL_IDENTIFIER 7 #define SCE_4GL_BLOCK 8 #define SCE_4GL_END 9 #define SCE_4GL_COMMENT1 10 #define SCE_4GL_COMMENT2 11 #define SCE_4GL_COMMENT3 12 #define SCE_4GL_COMMENT4 13 #define SCE_4GL_COMMENT5 14 #define SCE_4GL_COMMENT6 15 #define SCE_4GL_DEFAULT_ 16 #define SCE_4GL_NUMBER_ 17 #define SCE_4GL_WORD_ 18 #define SCE_4GL_STRING_ 19 #define SCE_4GL_CHARACTER_ 20 #define SCE_4GL_PREPROCESSOR_ 21 #define SCE_4GL_OPERATOR_ 22 #define SCE_4GL_IDENTIFIER_ 23 #define SCE_4GL_BLOCK_ 24 #define SCE_4GL_END_ 25 #define SCE_4GL_COMMENT1_ 26 #define SCE_4GL_COMMENT2_ 27 #define SCE_4GL_COMMENT3_ 28 #define SCE_4GL_COMMENT4_ 29 #define SCE_4GL_COMMENT5_ 30 #define SCE_4GL_COMMENT6_ 31 #define SCE_ABAQUS_DEFAULT 0 #define SCE_ABAQUS_COMMENT 1 #define SCE_ABAQUS_COMMENTBLOCK 2 #define SCE_ABAQUS_NUMBER 3 #define SCE_ABAQUS_STRING 4 #define SCE_ABAQUS_OPERATOR 5 #define SCE_ABAQUS_WORD 6 #define SCE_ABAQUS_PROCESSOR 7 #define SCE_ABAQUS_COMMAND 8 #define SCE_ABAQUS_SLASHCOMMAND 9 #define SCE_ABAQUS_STARCOMMAND 10 #define SCE_ABAQUS_ARGUMENT 11 #define SCE_ABAQUS_FUNCTION 12 #define SCE_ASY_DEFAULT 0 #define SCE_ASY_COMMENT 1 #define SCE_ASY_COMMENTLINE 2 #define SCE_ASY_NUMBER 3 #define SCE_ASY_WORD 4 #define SCE_ASY_STRING 5 #define SCE_ASY_CHARACTER 6 #define SCE_ASY_OPERATOR 7 #define SCE_ASY_IDENTIFIER 8 #define SCE_ASY_STRINGEOL 9 #define SCE_ASY_COMMENTLINEDOC 10 #define SCE_ASY_WORD2 11 #define SCE_R_DEFAULT 0 #define SCE_R_COMMENT 1 #define SCE_R_KWORD 2 #define SCE_R_BASEKWORD 3 #define SCE_R_OTHERKWORD 4 #define SCE_R_NUMBER 5 #define SCE_R_STRING 6 #define SCE_R_STRING2 7 #define SCE_R_OPERATOR 8 #define SCE_R_IDENTIFIER 9 #define SCE_R_INFIX 10 #define SCE_R_INFIXEOL 11 #define SCE_MAGIK_DEFAULT 0 #define SCE_MAGIK_COMMENT 1 #define SCE_MAGIK_HYPER_COMMENT 16 #define SCE_MAGIK_STRING 2 #define SCE_MAGIK_CHARACTER 3 #define SCE_MAGIK_NUMBER 4 #define SCE_MAGIK_IDENTIFIER 5 #define SCE_MAGIK_OPERATOR 6 #define SCE_MAGIK_FLOW 7 #define SCE_MAGIK_CONTAINER 8 #define SCE_MAGIK_BRACKET_BLOCK 9 #define SCE_MAGIK_BRACE_BLOCK 10 #define SCE_MAGIK_SQBRACKET_BLOCK 11 #define SCE_MAGIK_UNKNOWN_KEYWORD 12 #define SCE_MAGIK_KEYWORD 13 #define SCE_MAGIK_PRAGMA 14 #define SCE_MAGIK_SYMBOL 15 #define SCE_POWERSHELL_DEFAULT 0 #define SCE_POWERSHELL_COMMENT 1 #define SCE_POWERSHELL_STRING 2 #define SCE_POWERSHELL_CHARACTER 3 #define SCE_POWERSHELL_NUMBER 4 #define SCE_POWERSHELL_VARIABLE 5 #define SCE_POWERSHELL_OPERATOR 6 #define SCE_POWERSHELL_IDENTIFIER 7 #define SCE_POWERSHELL_KEYWORD 8 #define SCE_POWERSHELL_CMDLET 9 #define SCE_POWERSHELL_ALIAS 10 #define SCE_POWERSHELL_FUNCTION 11 #define SCE_POWERSHELL_USER1 12 #define SCE_POWERSHELL_COMMENTSTREAM 13 #define SCE_MYSQL_DEFAULT 0 #define SCE_MYSQL_COMMENT 1 #define SCE_MYSQL_COMMENTLINE 2 #define SCE_MYSQL_VARIABLE 3 #define SCE_MYSQL_SYSTEMVARIABLE 4 #define SCE_MYSQL_KNOWNSYSTEMVARIABLE 5 #define SCE_MYSQL_NUMBER 6 #define SCE_MYSQL_MAJORKEYWORD 7 #define SCE_MYSQL_KEYWORD 8 #define SCE_MYSQL_DATABASEOBJECT 9 #define SCE_MYSQL_PROCEDUREKEYWORD 10 #define SCE_MYSQL_STRING 11 #define SCE_MYSQL_SQSTRING 12 #define SCE_MYSQL_DQSTRING 13 #define SCE_MYSQL_OPERATOR 14 #define SCE_MYSQL_FUNCTION 15 #define SCE_MYSQL_IDENTIFIER 16 #define SCE_MYSQL_QUOTEDIDENTIFIER 17 #define SCE_MYSQL_USER1 18 #define SCE_MYSQL_USER2 19 #define SCE_MYSQL_USER3 20 #define SCE_MYSQL_HIDDENCOMMAND 21 #define SCE_MYSQL_PLACEHOLDER 22 #define SCE_PO_DEFAULT 0 #define SCE_PO_COMMENT 1 #define SCE_PO_MSGID 2 #define SCE_PO_MSGID_TEXT 3 #define SCE_PO_MSGSTR 4 #define SCE_PO_MSGSTR_TEXT 5 #define SCE_PO_MSGCTXT 6 #define SCE_PO_MSGCTXT_TEXT 7 #define SCE_PO_FUZZY 8 #define SCE_PO_PROGRAMMER_COMMENT 9 #define SCE_PO_REFERENCE 10 #define SCE_PO_FLAGS 11 #define SCE_PO_MSGID_TEXT_EOL 12 #define SCE_PO_MSGSTR_TEXT_EOL 13 #define SCE_PO_MSGCTXT_TEXT_EOL 14 #define SCE_PO_ERROR 15 #define SCE_PAS_DEFAULT 0 #define SCE_PAS_IDENTIFIER 1 #define SCE_PAS_COMMENT 2 #define SCE_PAS_COMMENT2 3 #define SCE_PAS_COMMENTLINE 4 #define SCE_PAS_PREPROCESSOR 5 #define SCE_PAS_PREPROCESSOR2 6 #define SCE_PAS_NUMBER 7 #define SCE_PAS_HEXNUMBER 8 #define SCE_PAS_WORD 9 #define SCE_PAS_STRING 10 #define SCE_PAS_STRINGEOL 11 #define SCE_PAS_CHARACTER 12 #define SCE_PAS_OPERATOR 13 #define SCE_PAS_ASM 14 #define SCE_SORCUS_DEFAULT 0 #define SCE_SORCUS_COMMAND 1 #define SCE_SORCUS_PARAMETER 2 #define SCE_SORCUS_COMMENTLINE 3 #define SCE_SORCUS_STRING 4 #define SCE_SORCUS_STRINGEOL 5 #define SCE_SORCUS_IDENTIFIER 6 #define SCE_SORCUS_OPERATOR 7 #define SCE_SORCUS_NUMBER 8 #define SCE_SORCUS_CONSTANT 9 #define SCE_POWERPRO_DEFAULT 0 #define SCE_POWERPRO_COMMENTBLOCK 1 #define SCE_POWERPRO_COMMENTLINE 2 #define SCE_POWERPRO_NUMBER 3 #define SCE_POWERPRO_WORD 4 #define SCE_POWERPRO_WORD2 5 #define SCE_POWERPRO_WORD3 6 #define SCE_POWERPRO_WORD4 7 #define SCE_POWERPRO_DOUBLEQUOTEDSTRING 8 #define SCE_POWERPRO_SINGLEQUOTEDSTRING 9 #define SCE_POWERPRO_LINECONTINUE 10 #define SCE_POWERPRO_OPERATOR 11 #define SCE_POWERPRO_IDENTIFIER 12 #define SCE_POWERPRO_STRINGEOL 13 #define SCE_POWERPRO_VERBATIM 14 #define SCE_POWERPRO_ALTQUOTE 15 #define SCE_POWERPRO_FUNCTION 16 #define SCE_SML_DEFAULT 0 #define SCE_SML_IDENTIFIER 1 #define SCE_SML_TAGNAME 2 #define SCE_SML_KEYWORD 3 #define SCE_SML_KEYWORD2 4 #define SCE_SML_KEYWORD3 5 #define SCE_SML_LINENUM 6 #define SCE_SML_OPERATOR 7 #define SCE_SML_NUMBER 8 #define SCE_SML_CHAR 9 #define SCE_SML_STRING 11 #define SCE_SML_COMMENT 12 #define SCE_SML_COMMENT1 13 #define SCE_SML_COMMENT2 14 #define SCE_SML_COMMENT3 15 #define SCE_MARKDOWN_DEFAULT 0 #define SCE_MARKDOWN_LINE_BEGIN 1 #define SCE_MARKDOWN_STRONG1 2 #define SCE_MARKDOWN_STRONG2 3 #define SCE_MARKDOWN_EM1 4 #define SCE_MARKDOWN_EM2 5 #define SCE_MARKDOWN_HEADER1 6 #define SCE_MARKDOWN_HEADER2 7 #define SCE_MARKDOWN_HEADER3 8 #define SCE_MARKDOWN_HEADER4 9 #define SCE_MARKDOWN_HEADER5 10 #define SCE_MARKDOWN_HEADER6 11 #define SCE_MARKDOWN_PRECHAR 12 #define SCE_MARKDOWN_ULIST_ITEM 13 #define SCE_MARKDOWN_OLIST_ITEM 14 #define SCE_MARKDOWN_BLOCKQUOTE 15 #define SCE_MARKDOWN_STRIKEOUT 16 #define SCE_MARKDOWN_HRULE 17 #define SCE_MARKDOWN_LINK 18 #define SCE_MARKDOWN_CODE 19 #define SCE_MARKDOWN_CODE2 20 #define SCE_MARKDOWN_CODEBK 21 #define SCE_TXT2TAGS_DEFAULT 0 #define SCE_TXT2TAGS_LINE_BEGIN 1 #define SCE_TXT2TAGS_STRONG1 2 #define SCE_TXT2TAGS_STRONG2 3 #define SCE_TXT2TAGS_EM1 4 #define SCE_TXT2TAGS_EM2 5 #define SCE_TXT2TAGS_HEADER1 6 #define SCE_TXT2TAGS_HEADER2 7 #define SCE_TXT2TAGS_HEADER3 8 #define SCE_TXT2TAGS_HEADER4 9 #define SCE_TXT2TAGS_HEADER5 10 #define SCE_TXT2TAGS_HEADER6 11 #define SCE_TXT2TAGS_PRECHAR 12 #define SCE_TXT2TAGS_ULIST_ITEM 13 #define SCE_TXT2TAGS_OLIST_ITEM 14 #define SCE_TXT2TAGS_BLOCKQUOTE 15 #define SCE_TXT2TAGS_STRIKEOUT 16 #define SCE_TXT2TAGS_HRULE 17 #define SCE_TXT2TAGS_LINK 18 #define SCE_TXT2TAGS_CODE 19 #define SCE_TXT2TAGS_CODE2 20 #define SCE_TXT2TAGS_CODEBK 21 #define SCE_TXT2TAGS_COMMENT 22 #define SCE_TXT2TAGS_OPTION 23 #define SCE_TXT2TAGS_PREPROC 24 #define SCE_TXT2TAGS_POSTPROC 25 #define SCE_A68K_DEFAULT 0 #define SCE_A68K_COMMENT 1 #define SCE_A68K_NUMBER_DEC 2 #define SCE_A68K_NUMBER_BIN 3 #define SCE_A68K_NUMBER_HEX 4 #define SCE_A68K_STRING1 5 #define SCE_A68K_OPERATOR 6 #define SCE_A68K_CPUINSTRUCTION 7 #define SCE_A68K_EXTINSTRUCTION 8 #define SCE_A68K_REGISTER 9 #define SCE_A68K_DIRECTIVE 10 #define SCE_A68K_MACRO_ARG 11 #define SCE_A68K_LABEL 12 #define SCE_A68K_STRING2 13 #define SCE_A68K_IDENTIFIER 14 #define SCE_A68K_MACRO_DECLARATION 15 #define SCE_A68K_COMMENT_WORD 16 #define SCE_A68K_COMMENT_SPECIAL 17 #define SCE_A68K_COMMENT_DOXYGEN 18 #define SCE_MODULA_DEFAULT 0 #define SCE_MODULA_COMMENT 1 #define SCE_MODULA_DOXYCOMM 2 #define SCE_MODULA_DOXYKEY 3 #define SCE_MODULA_KEYWORD 4 #define SCE_MODULA_RESERVED 5 #define SCE_MODULA_NUMBER 6 #define SCE_MODULA_BASENUM 7 #define SCE_MODULA_FLOAT 8 #define SCE_MODULA_STRING 9 #define SCE_MODULA_STRSPEC 10 #define SCE_MODULA_CHAR 11 #define SCE_MODULA_CHARSPEC 12 #define SCE_MODULA_PROC 13 #define SCE_MODULA_PRAGMA 14 #define SCE_MODULA_PRGKEY 15 #define SCE_MODULA_OPERATOR 16 #define SCE_MODULA_BADSTR 17 #define SCE_COFFEESCRIPT_DEFAULT 0 #define SCE_COFFEESCRIPT_COMMENT 1 #define SCE_COFFEESCRIPT_COMMENTLINE 2 #define SCE_COFFEESCRIPT_COMMENTDOC 3 #define SCE_COFFEESCRIPT_NUMBER 4 #define SCE_COFFEESCRIPT_WORD 5 #define SCE_COFFEESCRIPT_STRING 6 #define SCE_COFFEESCRIPT_CHARACTER 7 #define SCE_COFFEESCRIPT_UUID 8 #define SCE_COFFEESCRIPT_PREPROCESSOR 9 #define SCE_COFFEESCRIPT_OPERATOR 10 #define SCE_COFFEESCRIPT_IDENTIFIER 11 #define SCE_COFFEESCRIPT_STRINGEOL 12 #define SCE_COFFEESCRIPT_VERBATIM 13 #define SCE_COFFEESCRIPT_REGEX 14 #define SCE_COFFEESCRIPT_COMMENTLINEDOC 15 #define SCE_COFFEESCRIPT_WORD2 16 #define SCE_COFFEESCRIPT_COMMENTDOCKEYWORD 17 #define SCE_COFFEESCRIPT_COMMENTDOCKEYWORDERROR 18 #define SCE_COFFEESCRIPT_GLOBALCLASS 19 #define SCE_COFFEESCRIPT_STRINGRAW 20 #define SCE_COFFEESCRIPT_TRIPLEVERBATIM 21 #define SCE_COFFEESCRIPT_HASHQUOTEDSTRING 22 #define SCE_COFFEESCRIPT_COMMENTBLOCK 22 #define SCE_COFFEESCRIPT_VERBOSE_REGEX 23 #define SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT 24 #define SCE_AVS_DEFAULT 0 #define SCE_AVS_COMMENTBLOCK 1 #define SCE_AVS_COMMENTBLOCKN 2 #define SCE_AVS_COMMENTLINE 3 #define SCE_AVS_NUMBER 4 #define SCE_AVS_OPERATOR 5 #define SCE_AVS_IDENTIFIER 6 #define SCE_AVS_STRING 7 #define SCE_AVS_TRIPLESTRING 8 #define SCE_AVS_KEYWORD 9 #define SCE_AVS_FILTER 10 #define SCE_AVS_PLUGIN 11 #define SCE_AVS_FUNCTION 12 #define SCE_AVS_CLIPPROP 13 #define SCE_AVS_USERDFN 14 #define SCE_ECL_DEFAULT 0 #define SCE_ECL_COMMENT 1 #define SCE_ECL_COMMENTLINE 2 #define SCE_ECL_NUMBER 3 #define SCE_ECL_STRING 4 #define SCE_ECL_WORD0 5 #define SCE_ECL_OPERATOR 6 #define SCE_ECL_CHARACTER 7 #define SCE_ECL_UUID 8 #define SCE_ECL_PREPROCESSOR 9 #define SCE_ECL_UNKNOWN 10 #define SCE_ECL_IDENTIFIER 11 #define SCE_ECL_STRINGEOL 12 #define SCE_ECL_VERBATIM 13 #define SCE_ECL_REGEX 14 #define SCE_ECL_COMMENTLINEDOC 15 #define SCE_ECL_WORD1 16 #define SCE_ECL_COMMENTDOCKEYWORD 17 #define SCE_ECL_COMMENTDOCKEYWORDERROR 18 #define SCE_ECL_WORD2 19 #define SCE_ECL_WORD3 20 #define SCE_ECL_WORD4 21 #define SCE_ECL_WORD5 22 #define SCE_ECL_COMMENTDOC 23 #define SCE_ECL_ADDED 24 #define SCE_ECL_DELETED 25 #define SCE_ECL_CHANGED 26 #define SCE_ECL_MOVED 27 #define SCE_OSCRIPT_DEFAULT 0 #define SCE_OSCRIPT_LINE_COMMENT 1 #define SCE_OSCRIPT_BLOCK_COMMENT 2 #define SCE_OSCRIPT_DOC_COMMENT 3 #define SCE_OSCRIPT_PREPROCESSOR 4 #define SCE_OSCRIPT_NUMBER 5 #define SCE_OSCRIPT_SINGLEQUOTE_STRING 6 #define SCE_OSCRIPT_DOUBLEQUOTE_STRING 7 #define SCE_OSCRIPT_CONSTANT 8 #define SCE_OSCRIPT_IDENTIFIER 9 #define SCE_OSCRIPT_GLOBAL 10 #define SCE_OSCRIPT_KEYWORD 11 #define SCE_OSCRIPT_OPERATOR 12 #define SCE_OSCRIPT_LABEL 13 #define SCE_OSCRIPT_TYPE 14 #define SCE_OSCRIPT_FUNCTION 15 #define SCE_OSCRIPT_OBJECT 16 #define SCE_OSCRIPT_PROPERTY 17 #define SCE_OSCRIPT_METHOD 18 #define SCE_VISUALPROLOG_DEFAULT 0 #define SCE_VISUALPROLOG_KEY_MAJOR 1 #define SCE_VISUALPROLOG_KEY_MINOR 2 #define SCE_VISUALPROLOG_KEY_DIRECTIVE 3 #define SCE_VISUALPROLOG_COMMENT_BLOCK 4 #define SCE_VISUALPROLOG_COMMENT_LINE 5 #define SCE_VISUALPROLOG_COMMENT_KEY 6 #define SCE_VISUALPROLOG_COMMENT_KEY_ERROR 7 #define SCE_VISUALPROLOG_IDENTIFIER 8 #define SCE_VISUALPROLOG_VARIABLE 9 #define SCE_VISUALPROLOG_ANONYMOUS 10 #define SCE_VISUALPROLOG_NUMBER 11 #define SCE_VISUALPROLOG_OPERATOR 12 #define SCE_VISUALPROLOG_CHARACTER 13 #define SCE_VISUALPROLOG_CHARACTER_TOO_MANY 14 #define SCE_VISUALPROLOG_CHARACTER_ESCAPE_ERROR 15 #define SCE_VISUALPROLOG_STRING 16 #define SCE_VISUALPROLOG_STRING_ESCAPE 17 #define SCE_VISUALPROLOG_STRING_ESCAPE_ERROR 18 #define SCE_VISUALPROLOG_STRING_EOL_OPEN 19 #define SCE_VISUALPROLOG_STRING_VERBATIM 20 #define SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL 21 #define SCE_VISUALPROLOG_STRING_VERBATIM_EOL 22 /* --Autogenerated -- end of section automatically generated from Scintilla.iface */ #endif |
Added include/Scintilla.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 |
/* Scintilla source code edit control */ /** @file Scintilla.h ** Interface to the edit control. **/ /* Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> * The License.txt file describes the conditions under which this software may be distributed. */ /* Most of this file is automatically generated from the Scintilla.iface interface definition * file which contains any comments about the definitions. HFacer.py does the generation. */ #ifndef SCINTILLA_H #define SCINTILLA_H #ifdef __cplusplus extern "C" { #endif #if defined(_WIN32) /* Return false on failure: */ int Scintilla_RegisterClasses(void *hInstance); int Scintilla_ReleaseResources(); #endif int Scintilla_LinkLexers(); #ifdef __cplusplus } #endif /* Here should be placed typedefs for uptr_t, an unsigned integer type large enough to * hold a pointer and sptr_t, a signed integer large enough to hold a pointer. * May need to be changed for 64 bit platforms. */ #if defined(_WIN32) #include <basetsd.h> #endif #ifdef MAXULONG_PTR typedef ULONG_PTR uptr_t; typedef LONG_PTR sptr_t; #else typedef unsigned long uptr_t; typedef long sptr_t; #endif typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam); /* ++Autogenerated -- start of section automatically generated from Scintilla.iface */ #define INVALID_POSITION -1 #define SCI_START 2000 #define SCI_OPTIONAL_START 3000 #define SCI_LEXER_START 4000 #define SCI_ADDTEXT 2001 #define SCI_ADDSTYLEDTEXT 2002 #define SCI_INSERTTEXT 2003 #define SCI_CLEARALL 2004 #define SCI_DELETERANGE 2645 #define SCI_CLEARDOCUMENTSTYLE 2005 #define SCI_GETLENGTH 2006 #define SCI_GETCHARAT 2007 #define SCI_GETCURRENTPOS 2008 #define SCI_GETANCHOR 2009 #define SCI_GETSTYLEAT 2010 #define SCI_REDO 2011 #define SCI_SETUNDOCOLLECTION 2012 #define SCI_SELECTALL 2013 #define SCI_SETSAVEPOINT 2014 #define SCI_GETSTYLEDTEXT 2015 #define SCI_CANREDO 2016 #define SCI_MARKERLINEFROMHANDLE 2017 #define SCI_MARKERDELETEHANDLE 2018 #define SCI_GETUNDOCOLLECTION 2019 #define SCWS_INVISIBLE 0 #define SCWS_VISIBLEALWAYS 1 #define SCWS_VISIBLEAFTERINDENT 2 #define SCI_GETVIEWWS 2020 #define SCI_SETVIEWWS 2021 #define SCI_POSITIONFROMPOINT 2022 #define SCI_POSITIONFROMPOINTCLOSE 2023 #define SCI_GOTOLINE 2024 #define SCI_GOTOPOS 2025 #define SCI_SETANCHOR 2026 #define SCI_GETCURLINE 2027 #define SCI_GETENDSTYLED 2028 #define SC_EOL_CRLF 0 #define SC_EOL_CR 1 #define SC_EOL_LF 2 #define SCI_CONVERTEOLS 2029 #define SCI_GETEOLMODE 2030 #define SCI_SETEOLMODE 2031 #define SCI_STARTSTYLING 2032 #define SCI_SETSTYLING 2033 #define SCI_GETBUFFEREDDRAW 2034 #define SCI_SETBUFFEREDDRAW 2035 #define SCI_SETTABWIDTH 2036 #define SCI_GETTABWIDTH 2121 #define SC_CP_UTF8 65001 #define SCI_SETCODEPAGE 2037 #define MARKER_MAX 31 #define SC_MARK_CIRCLE 0 #define SC_MARK_ROUNDRECT 1 #define SC_MARK_ARROW 2 #define SC_MARK_SMALLRECT 3 #define SC_MARK_SHORTARROW 4 #define SC_MARK_EMPTY 5 #define SC_MARK_ARROWDOWN 6 #define SC_MARK_MINUS 7 #define SC_MARK_PLUS 8 #define SC_MARK_VLINE 9 #define SC_MARK_LCORNER 10 #define SC_MARK_TCORNER 11 #define SC_MARK_BOXPLUS 12 #define SC_MARK_BOXPLUSCONNECTED 13 #define SC_MARK_BOXMINUS 14 #define SC_MARK_BOXMINUSCONNECTED 15 #define SC_MARK_LCORNERCURVE 16 #define SC_MARK_TCORNERCURVE 17 #define SC_MARK_CIRCLEPLUS 18 #define SC_MARK_CIRCLEPLUSCONNECTED 19 #define SC_MARK_CIRCLEMINUS 20 #define SC_MARK_CIRCLEMINUSCONNECTED 21 #define SC_MARK_BACKGROUND 22 #define SC_MARK_DOTDOTDOT 23 #define SC_MARK_ARROWS 24 #define SC_MARK_PIXMAP 25 #define SC_MARK_FULLRECT 26 #define SC_MARK_LEFTRECT 27 #define SC_MARK_AVAILABLE 28 #define SC_MARK_UNDERLINE 29 #define SC_MARK_RGBAIMAGE 30 #define SC_MARK_CHARACTER 10000 #define SC_MARKNUM_FOLDEREND 25 #define SC_MARKNUM_FOLDEROPENMID 26 #define SC_MARKNUM_FOLDERMIDTAIL 27 #define SC_MARKNUM_FOLDERTAIL 28 #define SC_MARKNUM_FOLDERSUB 29 #define SC_MARKNUM_FOLDER 30 #define SC_MARKNUM_FOLDEROPEN 31 #define SC_MASK_FOLDERS 0xFE000000 #define SCI_MARKERDEFINE 2040 #define SCI_MARKERSETFORE 2041 #define SCI_MARKERSETBACK 2042 #define SCI_MARKERSETBACKSELECTED 2292 #define SCI_MARKERENABLEHIGHLIGHT 2293 #define SCI_MARKERADD 2043 #define SCI_MARKERDELETE 2044 #define SCI_MARKERDELETEALL 2045 #define SCI_MARKERGET 2046 #define SCI_MARKERNEXT 2047 #define SCI_MARKERPREVIOUS 2048 #define SCI_MARKERDEFINEPIXMAP 2049 #define SCI_MARKERADDSET 2466 #define SCI_MARKERSETALPHA 2476 #define SC_MAX_MARGIN 4 #define SC_MARGIN_SYMBOL 0 #define SC_MARGIN_NUMBER 1 #define SC_MARGIN_BACK 2 #define SC_MARGIN_FORE 3 #define SC_MARGIN_TEXT 4 #define SC_MARGIN_RTEXT 5 #define SCI_SETMARGINTYPEN 2240 #define SCI_GETMARGINTYPEN 2241 #define SCI_SETMARGINWIDTHN 2242 #define SCI_GETMARGINWIDTHN 2243 #define SCI_SETMARGINMASKN 2244 #define SCI_GETMARGINMASKN 2245 #define SCI_SETMARGINSENSITIVEN 2246 #define SCI_GETMARGINSENSITIVEN 2247 #define SCI_SETMARGINCURSORN 2248 #define SCI_GETMARGINCURSORN 2249 #define STYLE_DEFAULT 32 #define STYLE_LINENUMBER 33 #define STYLE_BRACELIGHT 34 #define STYLE_BRACEBAD 35 #define STYLE_CONTROLCHAR 36 #define STYLE_INDENTGUIDE 37 #define STYLE_CALLTIP 38 #define STYLE_LASTPREDEFINED 39 #define STYLE_MAX 255 #define SC_CHARSET_ANSI 0 #define SC_CHARSET_DEFAULT 1 #define SC_CHARSET_BALTIC 186 #define SC_CHARSET_CHINESEBIG5 136 #define SC_CHARSET_EASTEUROPE 238 #define SC_CHARSET_GB2312 134 #define SC_CHARSET_GREEK 161 #define SC_CHARSET_HANGUL 129 #define SC_CHARSET_MAC 77 #define SC_CHARSET_OEM 255 #define SC_CHARSET_RUSSIAN 204 #define SC_CHARSET_CYRILLIC 1251 #define SC_CHARSET_SHIFTJIS 128 #define SC_CHARSET_SYMBOL 2 #define SC_CHARSET_TURKISH 162 #define SC_CHARSET_JOHAB 130 #define SC_CHARSET_HEBREW 177 #define SC_CHARSET_ARABIC 178 #define SC_CHARSET_VIETNAMESE 163 #define SC_CHARSET_THAI 222 #define SC_CHARSET_8859_15 1000 #define SCI_STYLECLEARALL 2050 #define SCI_STYLESETFORE 2051 #define SCI_STYLESETBACK 2052 #define SCI_STYLESETBOLD 2053 #define SCI_STYLESETITALIC 2054 #define SCI_STYLESETSIZE 2055 #define SCI_STYLESETFONT 2056 #define SCI_STYLESETEOLFILLED 2057 #define SCI_STYLERESETDEFAULT 2058 #define SCI_STYLESETUNDERLINE 2059 #define SC_CASE_MIXED 0 #define SC_CASE_UPPER 1 #define SC_CASE_LOWER 2 #define SCI_STYLEGETFORE 2481 #define SCI_STYLEGETBACK 2482 #define SCI_STYLEGETBOLD 2483 #define SCI_STYLEGETITALIC 2484 #define SCI_STYLEGETSIZE 2485 #define SCI_STYLEGETFONT 2486 #define SCI_STYLEGETEOLFILLED 2487 #define SCI_STYLEGETUNDERLINE 2488 #define SCI_STYLEGETCASE 2489 #define SCI_STYLEGETCHARACTERSET 2490 #define SCI_STYLEGETVISIBLE 2491 #define SCI_STYLEGETCHANGEABLE 2492 #define SCI_STYLEGETHOTSPOT 2493 #define SCI_STYLESETCASE 2060 #define SC_FONT_SIZE_MULTIPLIER 100 #define SCI_STYLESETSIZEFRACTIONAL 2061 #define SCI_STYLEGETSIZEFRACTIONAL 2062 #define SC_WEIGHT_NORMAL 400 #define SC_WEIGHT_SEMIBOLD 600 #define SC_WEIGHT_BOLD 700 #define SCI_STYLESETWEIGHT 2063 #define SCI_STYLEGETWEIGHT 2064 #define SCI_STYLESETCHARACTERSET 2066 #define SCI_STYLESETHOTSPOT 2409 #define SCI_SETSELFORE 2067 #define SCI_SETSELBACK 2068 #define SCI_GETSELALPHA 2477 #define SCI_SETSELALPHA 2478 #define SCI_GETSELEOLFILLED 2479 #define SCI_SETSELEOLFILLED 2480 #define SCI_SETCARETFORE 2069 #define SCI_ASSIGNCMDKEY 2070 #define SCI_CLEARCMDKEY 2071 #define SCI_CLEARALLCMDKEYS 2072 #define SCI_SETSTYLINGEX 2073 #define SCI_STYLESETVISIBLE 2074 #define SCI_GETCARETPERIOD 2075 #define SCI_SETCARETPERIOD 2076 #define SCI_SETWORDCHARS 2077 #define SCI_GETWORDCHARS 2646 #define SCI_BEGINUNDOACTION 2078 #define SCI_ENDUNDOACTION 2079 #define INDIC_PLAIN 0 #define INDIC_SQUIGGLE 1 #define INDIC_TT 2 #define INDIC_DIAGONAL 3 #define INDIC_STRIKE 4 #define INDIC_HIDDEN 5 #define INDIC_BOX 6 #define INDIC_ROUNDBOX 7 #define INDIC_STRAIGHTBOX 8 #define INDIC_DASH 9 #define INDIC_DOTS 10 #define INDIC_SQUIGGLELOW 11 #define INDIC_DOTBOX 12 #define INDIC_SQUIGGLEPIXMAP 13 #define INDIC_MAX 31 #define INDIC_CONTAINER 8 #define INDIC0_MASK 0x20 #define INDIC1_MASK 0x40 #define INDIC2_MASK 0x80 #define INDICS_MASK 0xE0 #define SCI_INDICSETSTYLE 2080 #define SCI_INDICGETSTYLE 2081 #define SCI_INDICSETFORE 2082 #define SCI_INDICGETFORE 2083 #define SCI_INDICSETUNDER 2510 #define SCI_INDICGETUNDER 2511 #define SCI_SETWHITESPACEFORE 2084 #define SCI_SETWHITESPACEBACK 2085 #define SCI_SETWHITESPACESIZE 2086 #define SCI_GETWHITESPACESIZE 2087 #define SCI_SETSTYLEBITS 2090 #define SCI_GETSTYLEBITS 2091 #define SCI_SETLINESTATE 2092 #define SCI_GETLINESTATE 2093 #define SCI_GETMAXLINESTATE 2094 #define SCI_GETCARETLINEVISIBLE 2095 #define SCI_SETCARETLINEVISIBLE 2096 #define SCI_GETCARETLINEBACK 2097 #define SCI_SETCARETLINEBACK 2098 #define SCI_STYLESETCHANGEABLE 2099 #define SCI_AUTOCSHOW 2100 #define SCI_AUTOCCANCEL 2101 #define SCI_AUTOCACTIVE 2102 #define SCI_AUTOCPOSSTART 2103 #define SCI_AUTOCCOMPLETE 2104 #define SCI_AUTOCSTOPS 2105 #define SCI_AUTOCSETSEPARATOR 2106 #define SCI_AUTOCGETSEPARATOR 2107 #define SCI_AUTOCSELECT 2108 #define SCI_AUTOCSETCANCELATSTART 2110 #define SCI_AUTOCGETCANCELATSTART 2111 #define SCI_AUTOCSETFILLUPS 2112 #define SCI_AUTOCSETCHOOSESINGLE 2113 #define SCI_AUTOCGETCHOOSESINGLE 2114 #define SCI_AUTOCSETIGNORECASE 2115 #define SCI_AUTOCGETIGNORECASE 2116 #define SCI_USERLISTSHOW 2117 #define SCI_AUTOCSETAUTOHIDE 2118 #define SCI_AUTOCGETAUTOHIDE 2119 #define SCI_AUTOCSETDROPRESTOFWORD 2270 #define SCI_AUTOCGETDROPRESTOFWORD 2271 #define SCI_REGISTERIMAGE 2405 #define SCI_CLEARREGISTEREDIMAGES 2408 #define SCI_AUTOCGETTYPESEPARATOR 2285 #define SCI_AUTOCSETTYPESEPARATOR 2286 #define SCI_AUTOCSETMAXWIDTH 2208 #define SCI_AUTOCGETMAXWIDTH 2209 #define SCI_AUTOCSETMAXHEIGHT 2210 #define SCI_AUTOCGETMAXHEIGHT 2211 #define SCI_SETINDENT 2122 #define SCI_GETINDENT 2123 #define SCI_SETUSETABS 2124 #define SCI_GETUSETABS 2125 #define SCI_SETLINEINDENTATION 2126 #define SCI_GETLINEINDENTATION 2127 #define SCI_GETLINEINDENTPOSITION 2128 #define SCI_GETCOLUMN 2129 #define SCI_COUNTCHARACTERS 2633 #define SCI_SETHSCROLLBAR 2130 #define SCI_GETHSCROLLBAR 2131 #define SC_IV_NONE 0 #define SC_IV_REAL 1 #define SC_IV_LOOKFORWARD 2 #define SC_IV_LOOKBOTH 3 #define SCI_SETINDENTATIONGUIDES 2132 #define SCI_GETINDENTATIONGUIDES 2133 #define SCI_SETHIGHLIGHTGUIDE 2134 #define SCI_GETHIGHLIGHTGUIDE 2135 #define SCI_GETLINEENDPOSITION 2136 #define SCI_GETCODEPAGE 2137 #define SCI_GETCARETFORE 2138 #define SCI_GETREADONLY 2140 #define SCI_SETCURRENTPOS 2141 #define SCI_SETSELECTIONSTART 2142 #define SCI_GETSELECTIONSTART 2143 #define SCI_SETSELECTIONEND 2144 #define SCI_GETSELECTIONEND 2145 #define SCI_SETEMPTYSELECTION 2556 #define SCI_SETPRINTMAGNIFICATION 2146 #define SCI_GETPRINTMAGNIFICATION 2147 #define SC_PRINT_NORMAL 0 #define SC_PRINT_INVERTLIGHT 1 #define SC_PRINT_BLACKONWHITE 2 #define SC_PRINT_COLOURONWHITE 3 #define SC_PRINT_COLOURONWHITEDEFAULTBG 4 #define SCI_SETPRINTCOLOURMODE 2148 #define SCI_GETPRINTCOLOURMODE 2149 #define SCFIND_WHOLEWORD 2 #define SCFIND_MATCHCASE 4 #define SCFIND_WORDSTART 0x00100000 #define SCFIND_REGEXP 0x00200000 #define SCFIND_POSIX 0x00400000 #define SCI_FINDTEXT 2150 #define SCI_FORMATRANGE 2151 #define SCI_GETFIRSTVISIBLELINE 2152 #define SCI_GETLINE 2153 #define SCI_GETLINECOUNT 2154 #define SCI_SETMARGINLEFT 2155 #define SCI_GETMARGINLEFT 2156 #define SCI_SETMARGINRIGHT 2157 #define SCI_GETMARGINRIGHT 2158 #define SCI_GETMODIFY 2159 #define SCI_SETSEL 2160 #define SCI_GETSELTEXT 2161 #define SCI_GETTEXTRANGE 2162 #define SCI_HIDESELECTION 2163 #define SCI_POINTXFROMPOSITION 2164 #define SCI_POINTYFROMPOSITION 2165 #define SCI_LINEFROMPOSITION 2166 #define SCI_POSITIONFROMLINE 2167 #define SCI_LINESCROLL 2168 #define SCI_SCROLLCARET 2169 #define SCI_SCROLLRANGE 2569 #define SCI_REPLACESEL 2170 #define SCI_SETREADONLY 2171 #define SCI_NULL 2172 #define SCI_CANPASTE 2173 #define SCI_CANUNDO 2174 #define SCI_EMPTYUNDOBUFFER 2175 #define SCI_UNDO 2176 #define SCI_CUT 2177 #define SCI_COPY 2178 #define SCI_PASTE 2179 #define SCI_CLEAR 2180 #define SCI_SETTEXT 2181 #define SCI_GETTEXT 2182 #define SCI_GETTEXTLENGTH 2183 #define SCI_GETDIRECTFUNCTION 2184 #define SCI_GETDIRECTPOINTER 2185 #define SCI_SETOVERTYPE 2186 #define SCI_GETOVERTYPE 2187 #define SCI_SETCARETWIDTH 2188 #define SCI_GETCARETWIDTH 2189 #define SCI_SETTARGETSTART 2190 #define SCI_GETTARGETSTART 2191 #define SCI_SETTARGETEND 2192 #define SCI_GETTARGETEND 2193 #define SCI_REPLACETARGET 2194 #define SCI_REPLACETARGETRE 2195 #define SCI_SEARCHINTARGET 2197 #define SCI_SETSEARCHFLAGS 2198 #define SCI_GETSEARCHFLAGS 2199 #define SCI_CALLTIPSHOW 2200 #define SCI_CALLTIPCANCEL 2201 #define SCI_CALLTIPACTIVE 2202 #define SCI_CALLTIPPOSSTART 2203 #define SCI_CALLTIPSETHLT 2204 #define SCI_CALLTIPSETBACK 2205 #define SCI_CALLTIPSETFORE 2206 #define SCI_CALLTIPSETFOREHLT 2207 #define SCI_CALLTIPUSESTYLE 2212 #define SCI_CALLTIPSETPOSITION 2213 #define SCI_VISIBLEFROMDOCLINE 2220 #define SCI_DOCLINEFROMVISIBLE 2221 #define SCI_WRAPCOUNT 2235 #define SC_FOLDLEVELBASE 0x400 #define SC_FOLDLEVELWHITEFLAG 0x1000 #define SC_FOLDLEVELHEADERFLAG 0x2000 #define SC_FOLDLEVELNUMBERMASK 0x0FFF #define SCI_SETFOLDLEVEL 2222 #define SCI_GETFOLDLEVEL 2223 #define SCI_GETLASTCHILD 2224 #define SCI_GETFOLDPARENT 2225 #define SCI_SHOWLINES 2226 #define SCI_HIDELINES 2227 #define SCI_GETLINEVISIBLE 2228 #define SCI_GETALLLINESVISIBLE 2236 #define SCI_SETFOLDEXPANDED 2229 #define SCI_GETFOLDEXPANDED 2230 #define SCI_TOGGLEFOLD 2231 #define SCI_ENSUREVISIBLE 2232 #define SC_FOLDFLAG_LINEBEFORE_EXPANDED 0x0002 #define SC_FOLDFLAG_LINEBEFORE_CONTRACTED 0x0004 #define SC_FOLDFLAG_LINEAFTER_EXPANDED 0x0008 #define SC_FOLDFLAG_LINEAFTER_CONTRACTED 0x0010 #define SC_FOLDFLAG_LEVELNUMBERS 0x0040 #define SCI_SETFOLDFLAGS 2233 #define SCI_ENSUREVISIBLEENFORCEPOLICY 2234 #define SCI_SETTABINDENTS 2260 #define SCI_GETTABINDENTS 2261 #define SCI_SETBACKSPACEUNINDENTS 2262 #define SCI_GETBACKSPACEUNINDENTS 2263 #define SC_TIME_FOREVER 10000000 #define SCI_SETMOUSEDWELLTIME 2264 #define SCI_GETMOUSEDWELLTIME 2265 #define SCI_WORDSTARTPOSITION 2266 #define SCI_WORDENDPOSITION 2267 #define SC_WRAP_NONE 0 #define SC_WRAP_WORD 1 #define SC_WRAP_CHAR 2 #define SCI_SETWRAPMODE 2268 #define SCI_GETWRAPMODE 2269 #define SC_WRAPVISUALFLAG_NONE 0x0000 #define SC_WRAPVISUALFLAG_END 0x0001 #define SC_WRAPVISUALFLAG_START 0x0002 #define SC_WRAPVISUALFLAG_MARGIN 0x0004 #define SCI_SETWRAPVISUALFLAGS 2460 #define SCI_GETWRAPVISUALFLAGS 2461 #define SC_WRAPVISUALFLAGLOC_DEFAULT 0x0000 #define SC_WRAPVISUALFLAGLOC_END_BY_TEXT 0x0001 #define SC_WRAPVISUALFLAGLOC_START_BY_TEXT 0x0002 #define SCI_SETWRAPVISUALFLAGSLOCATION 2462 #define SCI_GETWRAPVISUALFLAGSLOCATION 2463 #define SCI_SETWRAPSTARTINDENT 2464 #define SCI_GETWRAPSTARTINDENT 2465 #define SC_WRAPINDENT_FIXED 0 #define SC_WRAPINDENT_SAME 1 #define SC_WRAPINDENT_INDENT 2 #define SCI_SETWRAPINDENTMODE 2472 #define SCI_GETWRAPINDENTMODE 2473 #define SC_CACHE_NONE 0 #define SC_CACHE_CARET 1 #define SC_CACHE_PAGE 2 #define SC_CACHE_DOCUMENT 3 #define SCI_SETLAYOUTCACHE 2272 #define SCI_GETLAYOUTCACHE 2273 #define SCI_SETSCROLLWIDTH 2274 #define SCI_GETSCROLLWIDTH 2275 #define SCI_SETSCROLLWIDTHTRACKING 2516 #define SCI_GETSCROLLWIDTHTRACKING 2517 #define SCI_TEXTWIDTH 2276 #define SCI_SETENDATLASTLINE 2277 #define SCI_GETENDATLASTLINE 2278 #define SCI_TEXTHEIGHT 2279 #define SCI_SETVSCROLLBAR 2280 #define SCI_GETVSCROLLBAR 2281 #define SCI_APPENDTEXT 2282 #define SCI_GETTWOPHASEDRAW 2283 #define SCI_SETTWOPHASEDRAW 2284 #define SC_EFF_QUALITY_MASK 0xF #define SC_EFF_QUALITY_DEFAULT 0 #define SC_EFF_QUALITY_NON_ANTIALIASED 1 #define SC_EFF_QUALITY_ANTIALIASED 2 #define SC_EFF_QUALITY_LCD_OPTIMIZED 3 #define SCI_SETFONTQUALITY 2611 #define SCI_GETFONTQUALITY 2612 #define SCI_SETFIRSTVISIBLELINE 2613 #define SC_MULTIPASTE_ONCE 0 #define SC_MULTIPASTE_EACH 1 #define SCI_SETMULTIPASTE 2614 #define SCI_GETMULTIPASTE 2615 #define SCI_GETTAG 2616 #define SCI_TARGETFROMSELECTION 2287 #define SCI_LINESJOIN 2288 #define SCI_LINESSPLIT 2289 #define SCI_SETFOLDMARGINCOLOUR 2290 #define SCI_SETFOLDMARGINHICOLOUR 2291 #define SCI_LINEDOWN 2300 #define SCI_LINEDOWNEXTEND 2301 #define SCI_LINEUP 2302 #define SCI_LINEUPEXTEND 2303 #define SCI_CHARLEFT 2304 #define SCI_CHARLEFTEXTEND 2305 #define SCI_CHARRIGHT 2306 #define SCI_CHARRIGHTEXTEND 2307 #define SCI_WORDLEFT 2308 #define SCI_WORDLEFTEXTEND 2309 #define SCI_WORDRIGHT 2310 #define SCI_WORDRIGHTEXTEND 2311 #define SCI_HOME 2312 #define SCI_HOMEEXTEND 2313 #define SCI_LINEEND 2314 #define SCI_LINEENDEXTEND 2315 #define SCI_DOCUMENTSTART 2316 #define SCI_DOCUMENTSTARTEXTEND 2317 #define SCI_DOCUMENTEND 2318 #define SCI_DOCUMENTENDEXTEND 2319 #define SCI_PAGEUP 2320 #define SCI_PAGEUPEXTEND 2321 #define SCI_PAGEDOWN 2322 #define SCI_PAGEDOWNEXTEND 2323 #define SCI_EDITTOGGLEOVERTYPE 2324 #define SCI_CANCEL 2325 #define SCI_DELETEBACK 2326 #define SCI_TAB 2327 #define SCI_BACKTAB 2328 #define SCI_NEWLINE 2329 #define SCI_FORMFEED 2330 #define SCI_VCHOME 2331 #define SCI_VCHOMEEXTEND 2332 #define SCI_ZOOMIN 2333 #define SCI_ZOOMOUT 2334 #define SCI_DELWORDLEFT 2335 #define SCI_DELWORDRIGHT 2336 #define SCI_DELWORDRIGHTEND 2518 #define SCI_LINECUT 2337 #define SCI_LINEDELETE 2338 #define SCI_LINETRANSPOSE 2339 #define SCI_LINEDUPLICATE 2404 #define SCI_LOWERCASE 2340 #define SCI_UPPERCASE 2341 #define SCI_LINESCROLLDOWN 2342 #define SCI_LINESCROLLUP 2343 #define SCI_DELETEBACKNOTLINE 2344 #define SCI_HOMEDISPLAY 2345 #define SCI_HOMEDISPLAYEXTEND 2346 #define SCI_LINEENDDISPLAY 2347 #define SCI_LINEENDDISPLAYEXTEND 2348 #define SCI_HOMEWRAP 2349 #define SCI_HOMEWRAPEXTEND 2450 #define SCI_LINEENDWRAP 2451 #define SCI_LINEENDWRAPEXTEND 2452 #define SCI_VCHOMEWRAP 2453 #define SCI_VCHOMEWRAPEXTEND 2454 #define SCI_LINECOPY 2455 #define SCI_MOVECARETINSIDEVIEW 2401 #define SCI_LINELENGTH 2350 #define SCI_BRACEHIGHLIGHT 2351 #define SCI_BRACEHIGHLIGHTINDICATOR 2498 #define SCI_BRACEBADLIGHT 2352 #define SCI_BRACEBADLIGHTINDICATOR 2499 #define SCI_BRACEMATCH 2353 #define SCI_GETVIEWEOL 2355 #define SCI_SETVIEWEOL 2356 #define SCI_GETDOCPOINTER 2357 #define SCI_SETDOCPOINTER 2358 #define SCI_SETMODEVENTMASK 2359 #define EDGE_NONE 0 #define EDGE_LINE 1 #define EDGE_BACKGROUND 2 #define SCI_GETEDGECOLUMN 2360 #define SCI_SETEDGECOLUMN 2361 #define SCI_GETEDGEMODE 2362 #define SCI_SETEDGEMODE 2363 #define SCI_GETEDGECOLOUR 2364 #define SCI_SETEDGECOLOUR 2365 #define SCI_SEARCHANCHOR 2366 #define SCI_SEARCHNEXT 2367 #define SCI_SEARCHPREV 2368 #define SCI_LINESONSCREEN 2370 #define SCI_USEPOPUP 2371 #define SCI_SELECTIONISRECTANGLE 2372 #define SCI_SETZOOM 2373 #define SCI_GETZOOM 2374 #define SCI_CREATEDOCUMENT 2375 #define SCI_ADDREFDOCUMENT 2376 #define SCI_RELEASEDOCUMENT 2377 #define SCI_GETMODEVENTMASK 2378 #define SCI_SETFOCUS 2380 #define SCI_GETFOCUS 2381 #define SC_STATUS_OK 0 #define SC_STATUS_FAILURE 1 #define SC_STATUS_BADALLOC 2 #define SCI_SETSTATUS 2382 #define SCI_GETSTATUS 2383 #define SCI_SETMOUSEDOWNCAPTURES 2384 #define SCI_GETMOUSEDOWNCAPTURES 2385 #define SC_CURSORNORMAL -1 #define SC_CURSORARROW 2 #define SC_CURSORWAIT 4 #define SC_CURSORREVERSEARROW 7 #define SCI_SETCURSOR 2386 #define SCI_GETCURSOR 2387 #define SCI_SETCONTROLCHARSYMBOL 2388 #define SCI_GETCONTROLCHARSYMBOL 2389 #define SCI_WORDPARTLEFT 2390 #define SCI_WORDPARTLEFTEXTEND 2391 #define SCI_WORDPARTRIGHT 2392 #define SCI_WORDPARTRIGHTEXTEND 2393 #define VISIBLE_SLOP 0x01 #define VISIBLE_STRICT 0x04 #define SCI_SETVISIBLEPOLICY 2394 #define SCI_DELLINELEFT 2395 #define SCI_DELLINERIGHT 2396 #define SCI_SETXOFFSET 2397 #define SCI_GETXOFFSET 2398 #define SCI_CHOOSECARETX 2399 #define SCI_GRABFOCUS 2400 #define CARET_SLOP 0x01 #define CARET_STRICT 0x04 #define CARET_JUMPS 0x10 #define CARET_EVEN 0x08 #define SCI_SETXCARETPOLICY 2402 #define SCI_SETYCARETPOLICY 2403 #define SCI_SETPRINTWRAPMODE 2406 #define SCI_GETPRINTWRAPMODE 2407 #define SCI_SETHOTSPOTACTIVEFORE 2410 #define SCI_GETHOTSPOTACTIVEFORE 2494 #define SCI_SETHOTSPOTACTIVEBACK 2411 #define SCI_GETHOTSPOTACTIVEBACK 2495 #define SCI_SETHOTSPOTACTIVEUNDERLINE 2412 #define SCI_GETHOTSPOTACTIVEUNDERLINE 2496 #define SCI_SETHOTSPOTSINGLELINE 2421 #define SCI_GETHOTSPOTSINGLELINE 2497 #define SCI_PARADOWN 2413 #define SCI_PARADOWNEXTEND 2414 #define SCI_PARAUP 2415 #define SCI_PARAUPEXTEND 2416 #define SCI_POSITIONBEFORE 2417 #define SCI_POSITIONAFTER 2418 #define SCI_COPYRANGE 2419 #define SCI_COPYTEXT 2420 #define SC_SEL_STREAM 0 #define SC_SEL_RECTANGLE 1 #define SC_SEL_LINES 2 #define SC_SEL_THIN 3 #define SCI_SETSELECTIONMODE 2422 #define SCI_GETSELECTIONMODE 2423 #define SCI_GETLINESELSTARTPOSITION 2424 #define SCI_GETLINESELENDPOSITION 2425 #define SCI_LINEDOWNRECTEXTEND 2426 #define SCI_LINEUPRECTEXTEND 2427 #define SCI_CHARLEFTRECTEXTEND 2428 #define SCI_CHARRIGHTRECTEXTEND 2429 #define SCI_HOMERECTEXTEND 2430 #define SCI_VCHOMERECTEXTEND 2431 #define SCI_LINEENDRECTEXTEND 2432 #define SCI_PAGEUPRECTEXTEND 2433 #define SCI_PAGEDOWNRECTEXTEND 2434 #define SCI_STUTTEREDPAGEUP 2435 #define SCI_STUTTEREDPAGEUPEXTEND 2436 #define SCI_STUTTEREDPAGEDOWN 2437 #define SCI_STUTTEREDPAGEDOWNEXTEND 2438 #define SCI_WORDLEFTEND 2439 #define SCI_WORDLEFTENDEXTEND 2440 #define SCI_WORDRIGHTEND 2441 #define SCI_WORDRIGHTENDEXTEND 2442 #define SCI_SETWHITESPACECHARS 2443 #define SCI_GETWHITESPACECHARS 2647 #define SCI_SETPUNCTUATIONCHARS 2648 #define SCI_GETPUNCTUATIONCHARS 2649 #define SCI_SETCHARSDEFAULT 2444 #define SCI_AUTOCGETCURRENT 2445 #define SCI_AUTOCGETCURRENTTEXT 2610 #define SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE 0 #define SC_CASEINSENSITIVEBEHAVIOUR_IGNORECASE 1 #define SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR 2634 #define SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR 2635 #define SCI_ALLOCATE 2446 #define SCI_TARGETASUTF8 2447 #define SCI_SETLENGTHFORENCODE 2448 #define SCI_ENCODEDFROMUTF8 2449 #define SCI_FINDCOLUMN 2456 #define SCI_GETCARETSTICKY 2457 #define SCI_SETCARETSTICKY 2458 #define SC_CARETSTICKY_OFF 0 #define SC_CARETSTICKY_ON 1 #define SC_CARETSTICKY_WHITESPACE 2 #define SCI_TOGGLECARETSTICKY 2459 #define SCI_SETPASTECONVERTENDINGS 2467 #define SCI_GETPASTECONVERTENDINGS 2468 #define SCI_SELECTIONDUPLICATE 2469 #define SC_ALPHA_TRANSPARENT 0 #define SC_ALPHA_OPAQUE 255 #define SC_ALPHA_NOALPHA 256 #define SCI_SETCARETLINEBACKALPHA 2470 #define SCI_GETCARETLINEBACKALPHA 2471 #define CARETSTYLE_INVISIBLE 0 #define CARETSTYLE_LINE 1 #define CARETSTYLE_BLOCK 2 #define SCI_SETCARETSTYLE 2512 #define SCI_GETCARETSTYLE 2513 #define SCI_SETINDICATORCURRENT 2500 #define SCI_GETINDICATORCURRENT 2501 #define SCI_SETINDICATORVALUE 2502 #define SCI_GETINDICATORVALUE 2503 #define SCI_INDICATORFILLRANGE 2504 #define SCI_INDICATORCLEARRANGE 2505 #define SCI_INDICATORALLONFOR 2506 #define SCI_INDICATORVALUEAT 2507 #define SCI_INDICATORSTART 2508 #define SCI_INDICATOREND 2509 #define SCI_SETPOSITIONCACHE 2514 #define SCI_GETPOSITIONCACHE 2515 #define SCI_COPYALLOWLINE 2519 #define SCI_GETCHARACTERPOINTER 2520 #define SCI_GETRANGEPOINTER 2643 #define SCI_GETGAPPOSITION 2644 #define SCI_SETKEYSUNICODE 2521 #define SCI_GETKEYSUNICODE 2522 #define SCI_INDICSETALPHA 2523 #define SCI_INDICGETALPHA 2524 #define SCI_INDICSETOUTLINEALPHA 2558 #define SCI_INDICGETOUTLINEALPHA 2559 #define SCI_SETEXTRAASCENT 2525 #define SCI_GETEXTRAASCENT 2526 #define SCI_SETEXTRADESCENT 2527 #define SCI_GETEXTRADESCENT 2528 #define SCI_MARKERSYMBOLDEFINED 2529 #define SCI_MARGINSETTEXT 2530 #define SCI_MARGINGETTEXT 2531 #define SCI_MARGINSETSTYLE 2532 #define SCI_MARGINGETSTYLE 2533 #define SCI_MARGINSETSTYLES 2534 #define SCI_MARGINGETSTYLES 2535 #define SCI_MARGINTEXTCLEARALL 2536 #define SCI_MARGINSETSTYLEOFFSET 2537 #define SCI_MARGINGETSTYLEOFFSET 2538 #define SC_MARGINOPTION_NONE 0 #define SC_MARGINOPTION_SUBLINESELECT 1 #define SCI_SETMARGINOPTIONS 2539 #define SCI_GETMARGINOPTIONS 2557 #define SCI_ANNOTATIONSETTEXT 2540 #define SCI_ANNOTATIONGETTEXT 2541 #define SCI_ANNOTATIONSETSTYLE 2542 #define SCI_ANNOTATIONGETSTYLE 2543 #define SCI_ANNOTATIONSETSTYLES 2544 #define SCI_ANNOTATIONGETSTYLES 2545 #define SCI_ANNOTATIONGETLINES 2546 #define SCI_ANNOTATIONCLEARALL 2547 #define ANNOTATION_HIDDEN 0 #define ANNOTATION_STANDARD 1 #define ANNOTATION_BOXED 2 #define SCI_ANNOTATIONSETVISIBLE 2548 #define SCI_ANNOTATIONGETVISIBLE 2549 #define SCI_ANNOTATIONSETSTYLEOFFSET 2550 #define SCI_ANNOTATIONGETSTYLEOFFSET 2551 #define SCI_RELEASEALLEXTENDEDSTYLES 2552 #define SCI_ALLOCATEEXTENDEDSTYLES 2553 #define UNDO_MAY_COALESCE 1 #define SCI_ADDUNDOACTION 2560 #define SCI_CHARPOSITIONFROMPOINT 2561 #define SCI_CHARPOSITIONFROMPOINTCLOSE 2562 #define SCI_SETMULTIPLESELECTION 2563 #define SCI_GETMULTIPLESELECTION 2564 #define SCI_SETADDITIONALSELECTIONTYPING 2565 #define SCI_GETADDITIONALSELECTIONTYPING 2566 #define SCI_SETADDITIONALCARETSBLINK 2567 #define SCI_GETADDITIONALCARETSBLINK 2568 #define SCI_SETADDITIONALCARETSVISIBLE 2608 #define SCI_GETADDITIONALCARETSVISIBLE 2609 #define SCI_GETSELECTIONS 2570 #define SCI_GETSELECTIONEMPTY 2650 #define SCI_CLEARSELECTIONS 2571 #define SCI_SETSELECTION 2572 #define SCI_ADDSELECTION 2573 #define SCI_SETMAINSELECTION 2574 #define SCI_GETMAINSELECTION 2575 #define SCI_SETSELECTIONNCARET 2576 #define SCI_GETSELECTIONNCARET 2577 #define SCI_SETSELECTIONNANCHOR 2578 #define SCI_GETSELECTIONNANCHOR 2579 #define SCI_SETSELECTIONNCARETVIRTUALSPACE 2580 #define SCI_GETSELECTIONNCARETVIRTUALSPACE 2581 #define SCI_SETSELECTIONNANCHORVIRTUALSPACE 2582 #define SCI_GETSELECTIONNANCHORVIRTUALSPACE 2583 #define SCI_SETSELECTIONNSTART 2584 #define SCI_GETSELECTIONNSTART 2585 #define SCI_SETSELECTIONNEND 2586 #define SCI_GETSELECTIONNEND 2587 #define SCI_SETRECTANGULARSELECTIONCARET 2588 #define SCI_GETRECTANGULARSELECTIONCARET 2589 #define SCI_SETRECTANGULARSELECTIONANCHOR 2590 #define SCI_GETRECTANGULARSELECTIONANCHOR 2591 #define SCI_SETRECTANGULARSELECTIONCARETVIRTUALSPACE 2592 #define SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE 2593 #define SCI_SETRECTANGULARSELECTIONANCHORVIRTUALSPACE 2594 #define SCI_GETRECTANGULARSELECTIONANCHORVIRTUALSPACE 2595 #define SCVS_NONE 0 #define SCVS_RECTANGULARSELECTION 1 #define SCVS_USERACCESSIBLE 2 #define SCI_SETVIRTUALSPACEOPTIONS 2596 #define SCI_GETVIRTUALSPACEOPTIONS 2597 #define SCI_SETRECTANGULARSELECTIONMODIFIER 2598 #define SCI_GETRECTANGULARSELECTIONMODIFIER 2599 #define SCI_SETADDITIONALSELFORE 2600 #define SCI_SETADDITIONALSELBACK 2601 #define SCI_SETADDITIONALSELALPHA 2602 #define SCI_GETADDITIONALSELALPHA 2603 #define SCI_SETADDITIONALCARETFORE 2604 #define SCI_GETADDITIONALCARETFORE 2605 #define SCI_ROTATESELECTION 2606 #define SCI_SWAPMAINANCHORCARET 2607 #define SCI_CHANGELEXERSTATE 2617 #define SCI_CONTRACTEDFOLDNEXT 2618 #define SCI_VERTICALCENTRECARET 2619 #define SCI_MOVESELECTEDLINESUP 2620 #define SCI_MOVESELECTEDLINESDOWN 2621 #define SCI_SETIDENTIFIER 2622 #define SCI_GETIDENTIFIER 2623 #define SCI_RGBAIMAGESETWIDTH 2624 #define SCI_RGBAIMAGESETHEIGHT 2625 #define SCI_RGBAIMAGESETSCALE 2651 #define SCI_MARKERDEFINERGBAIMAGE 2626 #define SCI_REGISTERRGBAIMAGE 2627 #define SCI_SCROLLTOSTART 2628 #define SCI_SCROLLTOEND 2629 #define SC_TECHNOLOGY_DEFAULT 0 #define SC_TECHNOLOGY_DIRECTWRITE 1 #define SCI_SETTECHNOLOGY 2630 #define SCI_GETTECHNOLOGY 2631 #define SCI_CREATELOADER 2632 #define SCI_FINDINDICATORSHOW 2640 #define SCI_FINDINDICATORFLASH 2641 #define SCI_FINDINDICATORHIDE 2642 #define SCI_VCHOMEDISPLAY 2652 #define SCI_VCHOMEDISPLAYEXTEND 2653 #define SCI_GETCARETLINEVISIBLEALWAYS 2654 #define SCI_SETCARETLINEVISIBLEALWAYS 2655 #define SCI_STARTRECORD 3001 #define SCI_STOPRECORD 3002 #define SCI_SETLEXER 4001 #define SCI_GETLEXER 4002 #define SCI_COLOURISE 4003 #define SCI_SETPROPERTY 4004 #define KEYWORDSET_MAX 8 #define SCI_SETKEYWORDS 4005 #define SCI_SETLEXERLANGUAGE 4006 #define SCI_LOADLEXERLIBRARY 4007 #define SCI_GETPROPERTY 4008 #define SCI_GETPROPERTYEXPANDED 4009 #define SCI_GETPROPERTYINT 4010 #define SCI_GETSTYLEBITSNEEDED 4011 #define SCI_GETLEXERLANGUAGE 4012 #define SCI_PRIVATELEXERCALL 4013 #define SCI_PROPERTYNAMES 4014 #define SC_TYPE_BOOLEAN 0 #define SC_TYPE_INTEGER 1 #define SC_TYPE_STRING 2 #define SCI_PROPERTYTYPE 4015 #define SCI_DESCRIBEPROPERTY 4016 #define SCI_DESCRIBEKEYWORDSETS 4017 #define SC_MOD_INSERTTEXT 0x1 #define SC_MOD_DELETETEXT 0x2 #define SC_MOD_CHANGESTYLE 0x4 #define SC_MOD_CHANGEFOLD 0x8 #define SC_PERFORMED_USER 0x10 #define SC_PERFORMED_UNDO 0x20 #define SC_PERFORMED_REDO 0x40 #define SC_MULTISTEPUNDOREDO 0x80 #define SC_LASTSTEPINUNDOREDO 0x100 #define SC_MOD_CHANGEMARKER 0x200 #define SC_MOD_BEFOREINSERT 0x400 #define SC_MOD_BEFOREDELETE 0x800 #define SC_MULTILINEUNDOREDO 0x1000 #define SC_STARTACTION 0x2000 #define SC_MOD_CHANGEINDICATOR 0x4000 #define SC_MOD_CHANGELINESTATE 0x8000 #define SC_MOD_CHANGEMARGIN 0x10000 #define SC_MOD_CHANGEANNOTATION 0x20000 #define SC_MOD_CONTAINER 0x40000 #define SC_MOD_LEXERSTATE 0x80000 #define SC_MODEVENTMASKALL 0xFFFFF #define SC_UPDATE_CONTENT 0x1 #define SC_UPDATE_SELECTION 0x2 #define SC_UPDATE_V_SCROLL 0x4 #define SC_UPDATE_H_SCROLL 0x8 #define SCEN_CHANGE 768 #define SCEN_SETFOCUS 512 #define SCEN_KILLFOCUS 256 #define SCK_DOWN 300 #define SCK_UP 301 #define SCK_LEFT 302 #define SCK_RIGHT 303 #define SCK_HOME 304 #define SCK_END 305 #define SCK_PRIOR 306 #define SCK_NEXT 307 #define SCK_DELETE 308 #define SCK_INSERT 309 #define SCK_ESCAPE 7 #define SCK_BACK 8 #define SCK_TAB 9 #define SCK_RETURN 13 #define SCK_ADD 310 #define SCK_SUBTRACT 311 #define SCK_DIVIDE 312 #define SCK_WIN 313 #define SCK_RWIN 314 #define SCK_MENU 315 #define SCMOD_NORM 0 #define SCMOD_SHIFT 1 #define SCMOD_CTRL 2 #define SCMOD_ALT 4 #define SCMOD_SUPER 8 #define SCMOD_META 16 #define SCN_STYLENEEDED 2000 #define SCN_CHARADDED 2001 #define SCN_SAVEPOINTREACHED 2002 #define SCN_SAVEPOINTLEFT 2003 #define SCN_MODIFYATTEMPTRO 2004 #define SCN_KEY 2005 #define SCN_DOUBLECLICK 2006 #define SCN_UPDATEUI 2007 #define SCN_MODIFIED 2008 #define SCN_MACRORECORD 2009 #define SCN_MARGINCLICK 2010 #define SCN_NEEDSHOWN 2011 #define SCN_PAINTED 2013 #define SCN_USERLISTSELECTION 2014 #define SCN_URIDROPPED 2015 #define SCN_DWELLSTART 2016 #define SCN_DWELLEND 2017 #define SCN_ZOOM 2018 #define SCN_HOTSPOTCLICK 2019 #define SCN_HOTSPOTDOUBLECLICK 2020 #define SCN_CALLTIPCLICK 2021 #define SCN_AUTOCSELECTION 2022 #define SCN_INDICATORCLICK 2023 #define SCN_INDICATORRELEASE 2024 #define SCN_AUTOCCANCELLED 2025 #define SCN_AUTOCCHARDELETED 2026 #define SCN_HOTSPOTRELEASECLICK 2027 #ifndef SCI_DISABLE_PROVISIONAL #define SC_LINE_END_TYPE_DEFAULT 0 #define SC_LINE_END_TYPE_UNICODE 1 #define SCI_SETLINEENDTYPESALLOWED 2656 #define SCI_GETLINEENDTYPESALLOWED 2657 #define SCI_GETLINEENDTYPESACTIVE 2658 #define SCI_GETLINEENDTYPESSUPPORTED 4018 #define SCI_ALLOCATESUBSTYLES 4020 #define SCI_GETSUBSTYLESSTART 4021 #define SCI_GETSUBSTYLESLENGTH 4022 #define SCI_FREESUBSTYLES 4023 #define SCI_SETIDENTIFIERS 4024 #define SCI_DISTANCETOSECONDARYSTYLES 4025 #define SCI_GETSUBSTYLEBASES 4026 #endif /* --Autogenerated -- end of section automatically generated from Scintilla.iface */ /* These structures are defined to be exactly the same shape as the Win32 * CHARRANGE, TEXTRANGE, FINDTEXTEX, FORMATRANGE, and NMHDR structs. * So older code that treats Scintilla as a RichEdit will work. */ #ifdef SCI_NAMESPACE namespace Scintilla { #endif struct Sci_CharacterRange { long cpMin; long cpMax; }; struct Sci_TextRange { struct Sci_CharacterRange chrg; char *lpstrText; }; struct Sci_TextToFind { struct Sci_CharacterRange chrg; char *lpstrText; struct Sci_CharacterRange chrgText; }; #define CharacterRange Sci_CharacterRange #define TextRange Sci_TextRange #define TextToFind Sci_TextToFind typedef void *Sci_SurfaceID; struct Sci_Rectangle { int left; int top; int right; int bottom; }; /* This structure is used in printing and requires some of the graphics types * from Platform.h. Not needed by most client code. */ struct Sci_RangeToFormat { Sci_SurfaceID hdc; Sci_SurfaceID hdcTarget; struct Sci_Rectangle rc; struct Sci_Rectangle rcPage; struct Sci_CharacterRange chrg; }; #define RangeToFormat Sci_RangeToFormat struct Sci_NotifyHeader { /* Compatible with Windows NMHDR. * hwndFrom is really an environment specific window handle or pointer * but most clients of Scintilla.h do not have this type visible. */ void *hwndFrom; uptr_t idFrom; unsigned int code; }; #define NotifyHeader Sci_NotifyHeader struct SCNotification { struct Sci_NotifyHeader nmhdr; int position; /* SCN_STYLENEEDED, SCN_DOUBLECLICK, SCN_MODIFIED, SCN_MARGINCLICK, */ /* SCN_NEEDSHOWN, SCN_DWELLSTART, SCN_DWELLEND, SCN_CALLTIPCLICK, */ /* SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, SCN_HOTSPOTRELEASECLICK, */ /* SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */ /* SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */ int ch; /* SCN_CHARADDED, SCN_KEY */ int modifiers; /* SCN_KEY, SCN_DOUBLECLICK, SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, */ /* SCN_HOTSPOTRELEASECLICK, SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */ int modificationType; /* SCN_MODIFIED */ const char *text; /* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION, SCN_URIDROPPED */ int length; /* SCN_MODIFIED */ int linesAdded; /* SCN_MODIFIED */ int message; /* SCN_MACRORECORD */ uptr_t wParam; /* SCN_MACRORECORD */ sptr_t lParam; /* SCN_MACRORECORD */ int line; /* SCN_MODIFIED */ int foldLevelNow; /* SCN_MODIFIED */ int foldLevelPrev; /* SCN_MODIFIED */ int margin; /* SCN_MARGINCLICK */ int listType; /* SCN_USERLISTSELECTION */ int x; /* SCN_DWELLSTART, SCN_DWELLEND */ int y; /* SCN_DWELLSTART, SCN_DWELLEND */ int token; /* SCN_MODIFIED with SC_MOD_CONTAINER */ int annotationLinesAdded; /* SCN_MODIFIED with SC_MOD_CHANGEANNOTATION */ int updated; /* SCN_UPDATEUI */ }; #ifdef SCI_NAMESPACE } #endif #ifdef INCLUDE_DEPRECATED_FEATURES #define SC_CP_DBCS 1 #define SCI_SETUSEPALETTE 2039 #define SCI_GETUSEPALETTE 2139 #endif #endif |
Added include/Scintilla.iface.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 |
## First line may be used for shbang ## This file defines the interface to Scintilla ## Copyright 2000-2003 by Neil Hodgson <neilh@scintilla.org> ## The License.txt file describes the conditions under which this software may be distributed. ## A line starting with ## is a pure comment and should be stripped by readers. ## A line starting with #! is for future shbang use ## A line starting with # followed by a space is a documentation comment and refers ## to the next feature definition. ## Each feature is defined by a line starting with fun, get, set, val or evt. ## cat -> start a category ## fun -> a function ## get -> a property get function ## set -> a property set function ## val -> definition of a constant ## evt -> an event ## enu -> associate an enumeration with a set of vals with a prefix ## lex -> associate a lexer with the lexical classes it produces ## ## All other feature names should be ignored. They may be defined in the future. ## A property may have a set function, a get function or both. Each will have ## "Get" or "Set" in their names and the corresponding name will have the obvious switch. ## A property may be subscripted, in which case the first parameter is the subscript. ## fun, get, and set features have a strict syntax: ## <featureType><ws><returnType><ws><name>[=<number](<param>,<param>) ## where <ws> stands for white space. ## param may be empty (null value) or is <paramType><ws><paramName>[=<value>] ## Additional white space is allowed between elements. ## The syntax for evt is <featureType><ws><returnType><ws><name>[=<number]([<param>[,<param>]*]) ## Feature names that contain an underscore are defined by Windows, so in these ## cases, using the Windows definition is preferred where available. ## The feature numbers are stable so features will not be renumbered. ## Features may be removed but they will go through a period of deprecation ## before removal which is signalled by moving them into the Deprecated category. ## ## enu has the syntax enu<ws><enumeration>=<prefix>[<ws><prefix>]* where all the val ## features in this file starting with a given <prefix> are considered part of the ## enumeration. ## ## lex has the syntax lex<ws><name>=<lexerVal><ws><prefix>[<ws><prefix>]* ## where name is a reasonably capitalised (Python, XML) identifier or UI name, ## lexerVal is the val used to specify the lexer, and the list of prefixes is similar ## to enu. The name may not be the same as that used within the lexer so the lexerVal ## should be used to tie these entities together. ## Types: ## void ## int ## bool -> integer, 1=true, 0=false ## position -> integer position in a document ## colour -> colour integer containing red, green and blue bytes. ## string -> pointer to const character ## stringresult -> pointer to character, NULL-> return size of result ## cells -> pointer to array of cells, each cell containing a style byte and character byte ## textrange -> range of a min and a max position with an output string ## findtext -> searchrange, text -> foundposition ## keymod -> integer containing key in low half and modifiers in high half ## formatrange ## Types no longer used: ## findtextex -> searchrange ## charrange -> range of a min and a max position ## charrangeresult -> like charrange, but output param ## countedstring ## point -> x,y ## pointresult -> like point, but output param ## rectangle -> left,top,right,bottom ## Client code should ignore definitions containing types it does not understand, except ## for possibly #defining the constants ## Line numbers and positions start at 0. ## String arguments may contain NUL ('\0') characters where the calls provide a length ## argument and retrieve NUL characters. All retrieved strings except for those retrieved ## by GetLine also have a NUL appended but client code should calculate the size that ## will be returned rather than relying upon the NUL whenever possible. Allow for the ## extra NUL character when allocating buffers. The size to allocate for a stringresult ## can be determined by calling with a NULL (0) pointer. cat Basics ################################################ ## For Scintilla.h val INVALID_POSITION=-1 # Define start of Scintilla messages to be greater than all Windows edit (EM_*) messages # as many EM_ messages can be used although that use is deprecated. val SCI_START=2000 val SCI_OPTIONAL_START=3000 val SCI_LEXER_START=4000 # Add text to the document at current position. fun void AddText=2001(int length, string text) # Add array of cells to document. fun void AddStyledText=2002(int length, cells c) # Insert string at a position. fun void InsertText=2003(position pos, string text) # Delete all text in the document. fun void ClearAll=2004(,) # Delete a range of text in the document. fun void DeleteRange=2645(position pos, int deleteLength) # Set all style bytes to 0, remove all folding information. fun void ClearDocumentStyle=2005(,) # Returns the number of bytes in the document. get int GetLength=2006(,) # Returns the character byte at the position. get int GetCharAt=2007(position pos,) # Returns the position of the caret. get position GetCurrentPos=2008(,) # Returns the position of the opposite end of the selection to the caret. get position GetAnchor=2009(,) # Returns the style byte at the position. get int GetStyleAt=2010(position pos,) # Redoes the next action on the undo history. fun void Redo=2011(,) # Choose between collecting actions into the undo # history and discarding them. set void SetUndoCollection=2012(bool collectUndo,) # Select all the text in the document. fun void SelectAll=2013(,) # Remember the current position in the undo history as the position # at which the document was saved. fun void SetSavePoint=2014(,) # Retrieve a buffer of cells. # Returns the number of bytes in the buffer not including terminating NULs. fun int GetStyledText=2015(, textrange tr) # Are there any redoable actions in the undo history? fun bool CanRedo=2016(,) # Retrieve the line number at which a particular marker is located. fun int MarkerLineFromHandle=2017(int handle,) # Delete a marker. fun void MarkerDeleteHandle=2018(int handle,) # Is undo history being collected? get bool GetUndoCollection=2019(,) enu WhiteSpace=SCWS_ val SCWS_INVISIBLE=0 val SCWS_VISIBLEALWAYS=1 val SCWS_VISIBLEAFTERINDENT=2 # Are white space characters currently visible? # Returns one of SCWS_* constants. get int GetViewWS=2020(,) # Make white space characters invisible, always visible or visible outside indentation. set void SetViewWS=2021(int viewWS,) # Find the position from a point within the window. fun position PositionFromPoint=2022(int x, int y) # Find the position from a point within the window but return # INVALID_POSITION if not close to text. fun position PositionFromPointClose=2023(int x, int y) # Set caret to start of a line and ensure it is visible. fun void GotoLine=2024(int line,) # Set caret to a position and ensure it is visible. fun void GotoPos=2025(position pos,) # Set the selection anchor to a position. The anchor is the opposite # end of the selection from the caret. set void SetAnchor=2026(position posAnchor,) # Retrieve the text of the line containing the caret. # Returns the index of the caret on the line. fun int GetCurLine=2027(int length, stringresult text) # Retrieve the position of the last correctly styled character. get position GetEndStyled=2028(,) enu EndOfLine=SC_EOL_ val SC_EOL_CRLF=0 val SC_EOL_CR=1 val SC_EOL_LF=2 # Convert all line endings in the document to one mode. fun void ConvertEOLs=2029(int eolMode,) # Retrieve the current end of line mode - one of CRLF, CR, or LF. get int GetEOLMode=2030(,) # Set the current end of line mode. set void SetEOLMode=2031(int eolMode,) # Set the current styling position to pos and the styling mask to mask. # The styling mask can be used to protect some bits in each styling byte from modification. fun void StartStyling=2032(position pos, int mask) # Change style from current styling position for length characters to a style # and move the current styling position to after this newly styled segment. fun void SetStyling=2033(int length, int style) # Is drawing done first into a buffer or direct to the screen? get bool GetBufferedDraw=2034(,) # If drawing is buffered then each line of text is drawn into a bitmap buffer # before drawing it to the screen to avoid flicker. set void SetBufferedDraw=2035(bool buffered,) # Change the visible size of a tab to be a multiple of the width of a space character. set void SetTabWidth=2036(int tabWidth,) # Retrieve the visible size of a tab. get int GetTabWidth=2121(,) # The SC_CP_UTF8 value can be used to enter Unicode mode. # This is the same value as CP_UTF8 in Windows val SC_CP_UTF8=65001 # Set the code page used to interpret the bytes of the document as characters. # The SC_CP_UTF8 value can be used to enter Unicode mode. set void SetCodePage=2037(int codePage,) enu MarkerSymbol=SC_MARK_ val MARKER_MAX=31 val SC_MARK_CIRCLE=0 val SC_MARK_ROUNDRECT=1 val SC_MARK_ARROW=2 val SC_MARK_SMALLRECT=3 val SC_MARK_SHORTARROW=4 val SC_MARK_EMPTY=5 val SC_MARK_ARROWDOWN=6 val SC_MARK_MINUS=7 val SC_MARK_PLUS=8 # Shapes used for outlining column. val SC_MARK_VLINE=9 val SC_MARK_LCORNER=10 val SC_MARK_TCORNER=11 val SC_MARK_BOXPLUS=12 val SC_MARK_BOXPLUSCONNECTED=13 val SC_MARK_BOXMINUS=14 val SC_MARK_BOXMINUSCONNECTED=15 val SC_MARK_LCORNERCURVE=16 val SC_MARK_TCORNERCURVE=17 val SC_MARK_CIRCLEPLUS=18 val SC_MARK_CIRCLEPLUSCONNECTED=19 val SC_MARK_CIRCLEMINUS=20 val SC_MARK_CIRCLEMINUSCONNECTED=21 # Invisible mark that only sets the line background colour. val SC_MARK_BACKGROUND=22 val SC_MARK_DOTDOTDOT=23 val SC_MARK_ARROWS=24 val SC_MARK_PIXMAP=25 val SC_MARK_FULLRECT=26 val SC_MARK_LEFTRECT=27 val SC_MARK_AVAILABLE=28 val SC_MARK_UNDERLINE=29 val SC_MARK_RGBAIMAGE=30 val SC_MARK_CHARACTER=10000 enu MarkerOutline=SC_MARKNUM_ # Markers used for outlining column. val SC_MARKNUM_FOLDEREND=25 val SC_MARKNUM_FOLDEROPENMID=26 val SC_MARKNUM_FOLDERMIDTAIL=27 val SC_MARKNUM_FOLDERTAIL=28 val SC_MARKNUM_FOLDERSUB=29 val SC_MARKNUM_FOLDER=30 val SC_MARKNUM_FOLDEROPEN=31 val SC_MASK_FOLDERS=0xFE000000 # Set the symbol used for a particular marker number. fun void MarkerDefine=2040(int markerNumber, int markerSymbol) # Set the foreground colour used for a particular marker number. set void MarkerSetFore=2041(int markerNumber, colour fore) # Set the background colour used for a particular marker number. set void MarkerSetBack=2042(int markerNumber, colour back) # Set the background colour used for a particular marker number when its folding block is selected. set void MarkerSetBackSelected=2292(int markerNumber, colour back) # Enable/disable highlight for current folding bloc (smallest one that contains the caret) fun void MarkerEnableHighlight=2293(bool enabled,) # Add a marker to a line, returning an ID which can be used to find or delete the marker. fun int MarkerAdd=2043(int line, int markerNumber) # Delete a marker from a line. fun void MarkerDelete=2044(int line, int markerNumber) # Delete all markers with a particular number from all lines. fun void MarkerDeleteAll=2045(int markerNumber,) # Get a bit mask of all the markers set on a line. fun int MarkerGet=2046(int line,) # Find the next line at or after lineStart that includes a marker in mask. # Return -1 when no more lines. fun int MarkerNext=2047(int lineStart, int markerMask) # Find the previous line before lineStart that includes a marker in mask. fun int MarkerPrevious=2048(int lineStart, int markerMask) # Define a marker from a pixmap. fun void MarkerDefinePixmap=2049(int markerNumber, string pixmap) # Add a set of markers to a line. fun void MarkerAddSet=2466(int line, int set) # Set the alpha used for a marker that is drawn in the text area, not the margin. set void MarkerSetAlpha=2476(int markerNumber, int alpha) val SC_MAX_MARGIN=4 enu MarginType=SC_MARGIN_ val SC_MARGIN_SYMBOL=0 val SC_MARGIN_NUMBER=1 val SC_MARGIN_BACK=2 val SC_MARGIN_FORE=3 val SC_MARGIN_TEXT=4 val SC_MARGIN_RTEXT=5 # Set a margin to be either numeric or symbolic. set void SetMarginTypeN=2240(int margin, int marginType) # Retrieve the type of a margin. get int GetMarginTypeN=2241(int margin,) # Set the width of a margin to a width expressed in pixels. set void SetMarginWidthN=2242(int margin, int pixelWidth) # Retrieve the width of a margin in pixels. get int GetMarginWidthN=2243(int margin,) # Set a mask that determines which markers are displayed in a margin. set void SetMarginMaskN=2244(int margin, int mask) # Retrieve the marker mask of a margin. get int GetMarginMaskN=2245(int margin,) # Make a margin sensitive or insensitive to mouse clicks. set void SetMarginSensitiveN=2246(int margin, bool sensitive) # Retrieve the mouse click sensitivity of a margin. get bool GetMarginSensitiveN=2247(int margin,) # Set the cursor shown when the mouse is inside a margin. set void SetMarginCursorN=2248(int margin, int cursor) # Retrieve the cursor shown in a margin. get int GetMarginCursorN=2249(int margin,) # Styles in range 32..38 are predefined for parts of the UI and are not used as normal styles. # Style 39 is for future use. enu StylesCommon=STYLE_ val STYLE_DEFAULT=32 val STYLE_LINENUMBER=33 val STYLE_BRACELIGHT=34 val STYLE_BRACEBAD=35 val STYLE_CONTROLCHAR=36 val STYLE_INDENTGUIDE=37 val STYLE_CALLTIP=38 val STYLE_LASTPREDEFINED=39 val STYLE_MAX=255 # Character set identifiers are used in StyleSetCharacterSet. # The values are the same as the Windows *_CHARSET values. enu CharacterSet=SC_CHARSET_ val SC_CHARSET_ANSI=0 val SC_CHARSET_DEFAULT=1 val SC_CHARSET_BALTIC=186 val SC_CHARSET_CHINESEBIG5=136 val SC_CHARSET_EASTEUROPE=238 val SC_CHARSET_GB2312=134 val SC_CHARSET_GREEK=161 val SC_CHARSET_HANGUL=129 val SC_CHARSET_MAC=77 val SC_CHARSET_OEM=255 val SC_CHARSET_RUSSIAN=204 val SC_CHARSET_CYRILLIC=1251 val SC_CHARSET_SHIFTJIS=128 val SC_CHARSET_SYMBOL=2 val SC_CHARSET_TURKISH=162 val SC_CHARSET_JOHAB=130 val SC_CHARSET_HEBREW=177 val SC_CHARSET_ARABIC=178 val SC_CHARSET_VIETNAMESE=163 val SC_CHARSET_THAI=222 val SC_CHARSET_8859_15=1000 # Clear all the styles and make equivalent to the global default style. fun void StyleClearAll=2050(,) # Set the foreground colour of a style. set void StyleSetFore=2051(int style, colour fore) # Set the background colour of a style. set void StyleSetBack=2052(int style, colour back) # Set a style to be bold or not. set void StyleSetBold=2053(int style, bool bold) # Set a style to be italic or not. set void StyleSetItalic=2054(int style, bool italic) # Set the size of characters of a style. set void StyleSetSize=2055(int style, int sizePoints) # Set the font of a style. set void StyleSetFont=2056(int style, string fontName) # Set a style to have its end of line filled or not. set void StyleSetEOLFilled=2057(int style, bool filled) # Reset the default style to its state at startup fun void StyleResetDefault=2058(,) # Set a style to be underlined or not. set void StyleSetUnderline=2059(int style, bool underline) enu CaseVisible=SC_CASE_ val SC_CASE_MIXED=0 val SC_CASE_UPPER=1 val SC_CASE_LOWER=2 # Get the foreground colour of a style. get colour StyleGetFore=2481(int style,) # Get the background colour of a style. get colour StyleGetBack=2482(int style,) # Get is a style bold or not. get bool StyleGetBold=2483(int style,) # Get is a style italic or not. get bool StyleGetItalic=2484(int style,) # Get the size of characters of a style. get int StyleGetSize=2485(int style,) # Get the font of a style. # Returns the length of the fontName get int StyleGetFont=2486(int style, stringresult fontName) # Get is a style to have its end of line filled or not. get bool StyleGetEOLFilled=2487(int style,) # Get is a style underlined or not. get bool StyleGetUnderline=2488(int style,) # Get is a style mixed case, or to force upper or lower case. get int StyleGetCase=2489(int style,) # Get the character get of the font in a style. get int StyleGetCharacterSet=2490(int style,) # Get is a style visible or not. get bool StyleGetVisible=2491(int style,) # Get is a style changeable or not (read only). # Experimental feature, currently buggy. get bool StyleGetChangeable=2492(int style,) # Get is a style a hotspot or not. get bool StyleGetHotSpot=2493(int style,) # Set a style to be mixed case, or to force upper or lower case. set void StyleSetCase=2060(int style, int caseForce) val SC_FONT_SIZE_MULTIPLIER=100 # Set the size of characters of a style. Size is in points multiplied by 100. set void StyleSetSizeFractional=2061(int style, int caseForce) # Get the size of characters of a style in points multiplied by 100 get int StyleGetSizeFractional=2062(int style,) enu FontWeight=SC_WEIGHT_ val SC_WEIGHT_NORMAL=400 val SC_WEIGHT_SEMIBOLD=600 val SC_WEIGHT_BOLD=700 # Set the weight of characters of a style. set void StyleSetWeight=2063(int style, int weight) # Get the weight of characters of a style. get int StyleGetWeight=2064(int style,) # Set the character set of the font in a style. set void StyleSetCharacterSet=2066(int style, int characterSet) # Set a style to be a hotspot or not. set void StyleSetHotSpot=2409(int style, bool hotspot) # Set the foreground colour of the main and additional selections and whether to use this setting. fun void SetSelFore=2067(bool useSetting, colour fore) # Set the background colour of the main and additional selections and whether to use this setting. fun void SetSelBack=2068(bool useSetting, colour back) # Get the alpha of the selection. get int GetSelAlpha=2477(,) # Set the alpha of the selection. set void SetSelAlpha=2478(int alpha,) # Is the selection end of line filled? get bool GetSelEOLFilled=2479(,) # Set the selection to have its end of line filled or not. set void SetSelEOLFilled=2480(bool filled,) # Set the foreground colour of the caret. set void SetCaretFore=2069(colour fore,) # When key+modifier combination km is pressed perform msg. fun void AssignCmdKey=2070(keymod km, int msg) # When key+modifier combination km is pressed do nothing. fun void ClearCmdKey=2071(keymod km,) # Drop all key mappings. fun void ClearAllCmdKeys=2072(,) # Set the styles for a segment of the document. fun void SetStylingEx=2073(int length, string styles) # Set a style to be visible or not. set void StyleSetVisible=2074(int style, bool visible) # Get the time in milliseconds that the caret is on and off. get int GetCaretPeriod=2075(,) # Get the time in milliseconds that the caret is on and off. 0 = steady on. set void SetCaretPeriod=2076(int periodMilliseconds,) # Set the set of characters making up words for when moving or selecting by word. # First sets defaults like SetCharsDefault. set void SetWordChars=2077(, string characters) # Get the set of characters making up words for when moving or selecting by word. # Retuns the number of characters get int GetWordChars=2646(, stringresult characters) # Start a sequence of actions that is undone and redone as a unit. # May be nested. fun void BeginUndoAction=2078(,) # End a sequence of actions that is undone and redone as a unit. fun void EndUndoAction=2079(,) # Indicator style enumeration and some constants enu IndicatorStyle=INDIC_ val INDIC_PLAIN=0 val INDIC_SQUIGGLE=1 val INDIC_TT=2 val INDIC_DIAGONAL=3 val INDIC_STRIKE=4 val INDIC_HIDDEN=5 val INDIC_BOX=6 val INDIC_ROUNDBOX=7 val INDIC_STRAIGHTBOX=8 val INDIC_DASH=9 val INDIC_DOTS=10 val INDIC_SQUIGGLELOW=11 val INDIC_DOTBOX=12 val INDIC_SQUIGGLEPIXMAP=13 val INDIC_MAX=31 val INDIC_CONTAINER=8 val INDIC0_MASK=0x20 val INDIC1_MASK=0x40 val INDIC2_MASK=0x80 val INDICS_MASK=0xE0 # Set an indicator to plain, squiggle or TT. set void IndicSetStyle=2080(int indic, int style) # Retrieve the style of an indicator. get int IndicGetStyle=2081(int indic,) # Set the foreground colour of an indicator. set void IndicSetFore=2082(int indic, colour fore) # Retrieve the foreground colour of an indicator. get colour IndicGetFore=2083(int indic,) # Set an indicator to draw under text or over(default). set void IndicSetUnder=2510(int indic, bool under) # Retrieve whether indicator drawn under or over text. get bool IndicGetUnder=2511(int indic,) # Set the foreground colour of all whitespace and whether to use this setting. fun void SetWhitespaceFore=2084(bool useSetting, colour fore) # Set the background colour of all whitespace and whether to use this setting. fun void SetWhitespaceBack=2085(bool useSetting, colour back) # Set the size of the dots used to mark space characters. set void SetWhitespaceSize=2086(int size,) # Get the size of the dots used to mark space characters. get int GetWhitespaceSize=2087(,) # Divide each styling byte into lexical class bits (default: 5) and indicator # bits (default: 3). If a lexer requires more than 32 lexical states, then this # is used to expand the possible states. set void SetStyleBits=2090(int bits,) # Retrieve number of bits in style bytes used to hold the lexical state. get int GetStyleBits=2091(,) # Used to hold extra styling information for each line. set void SetLineState=2092(int line, int state) # Retrieve the extra styling information for a line. get int GetLineState=2093(int line,) # Retrieve the last line number that has line state. get int GetMaxLineState=2094(,) # Is the background of the line containing the caret in a different colour? get bool GetCaretLineVisible=2095(,) # Display the background of the line containing the caret in a different colour. set void SetCaretLineVisible=2096(bool show,) # Get the colour of the background of the line containing the caret. get colour GetCaretLineBack=2097(,) # Set the colour of the background of the line containing the caret. set void SetCaretLineBack=2098(colour back,) # Set a style to be changeable or not (read only). # Experimental feature, currently buggy. set void StyleSetChangeable=2099(int style, bool changeable) # Display a auto-completion list. # The lenEntered parameter indicates how many characters before # the caret should be used to provide context. fun void AutoCShow=2100(int lenEntered, string itemList) # Remove the auto-completion list from the screen. fun void AutoCCancel=2101(,) # Is there an auto-completion list visible? fun bool AutoCActive=2102(,) # Retrieve the position of the caret when the auto-completion list was displayed. fun position AutoCPosStart=2103(,) # User has selected an item so remove the list and insert the selection. fun void AutoCComplete=2104(,) # Define a set of character that when typed cancel the auto-completion list. fun void AutoCStops=2105(, string characterSet) # Change the separator character in the string setting up an auto-completion list. # Default is space but can be changed if items contain space. set void AutoCSetSeparator=2106(int separatorCharacter,) # Retrieve the auto-completion list separator character. get int AutoCGetSeparator=2107(,) # Select the item in the auto-completion list that starts with a string. fun void AutoCSelect=2108(, string text) # Should the auto-completion list be cancelled if the user backspaces to a # position before where the box was created. set void AutoCSetCancelAtStart=2110(bool cancel,) # Retrieve whether auto-completion cancelled by backspacing before start. get bool AutoCGetCancelAtStart=2111(,) # Define a set of characters that when typed will cause the autocompletion to # choose the selected item. set void AutoCSetFillUps=2112(, string characterSet) # Should a single item auto-completion list automatically choose the item. set void AutoCSetChooseSingle=2113(bool chooseSingle,) # Retrieve whether a single item auto-completion list automatically choose the item. get bool AutoCGetChooseSingle=2114(,) # Set whether case is significant when performing auto-completion searches. set void AutoCSetIgnoreCase=2115(bool ignoreCase,) # Retrieve state of ignore case flag. get bool AutoCGetIgnoreCase=2116(,) # Display a list of strings and send notification when user chooses one. fun void UserListShow=2117(int listType, string itemList) # Set whether or not autocompletion is hidden automatically when nothing matches. set void AutoCSetAutoHide=2118(bool autoHide,) # Retrieve whether or not autocompletion is hidden automatically when nothing matches. get bool AutoCGetAutoHide=2119(,) # Set whether or not autocompletion deletes any word characters # after the inserted text upon completion. set void AutoCSetDropRestOfWord=2270(bool dropRestOfWord,) # Retrieve whether or not autocompletion deletes any word characters # after the inserted text upon completion. get bool AutoCGetDropRestOfWord=2271(,) # Register an XPM image for use in autocompletion lists. fun void RegisterImage=2405(int type, string xpmData) # Clear all the registered XPM images. fun void ClearRegisteredImages=2408(,) # Retrieve the auto-completion list type-separator character. get int AutoCGetTypeSeparator=2285(,) # Change the type-separator character in the string setting up an auto-completion list. # Default is '?' but can be changed if items contain '?'. set void AutoCSetTypeSeparator=2286(int separatorCharacter,) # Set the maximum width, in characters, of auto-completion and user lists. # Set to 0 to autosize to fit longest item, which is the default. set void AutoCSetMaxWidth=2208(int characterCount,) # Get the maximum width, in characters, of auto-completion and user lists. get int AutoCGetMaxWidth=2209(,) # Set the maximum height, in rows, of auto-completion and user lists. # The default is 5 rows. set void AutoCSetMaxHeight=2210(int rowCount,) # Set the maximum height, in rows, of auto-completion and user lists. get int AutoCGetMaxHeight=2211(,) # Set the number of spaces used for one level of indentation. set void SetIndent=2122(int indentSize,) # Retrieve indentation size. get int GetIndent=2123(,) # Indentation will only use space characters if useTabs is false, otherwise # it will use a combination of tabs and spaces. set void SetUseTabs=2124(bool useTabs,) # Retrieve whether tabs will be used in indentation. get bool GetUseTabs=2125(,) # Change the indentation of a line to a number of columns. set void SetLineIndentation=2126(int line, int indentSize) # Retrieve the number of columns that a line is indented. get int GetLineIndentation=2127(int line,) # Retrieve the position before the first non indentation character on a line. get position GetLineIndentPosition=2128(int line,) # Retrieve the column number of a position, taking tab width into account. get int GetColumn=2129(position pos,) # Count characters between two positions. fun int CountCharacters=2633(int startPos, int endPos) # Show or hide the horizontal scroll bar. set void SetHScrollBar=2130(bool show,) # Is the horizontal scroll bar visible? get bool GetHScrollBar=2131(,) enu IndentView=SC_IV_ val SC_IV_NONE=0 val SC_IV_REAL=1 val SC_IV_LOOKFORWARD=2 val SC_IV_LOOKBOTH=3 # Show or hide indentation guides. set void SetIndentationGuides=2132(int indentView,) # Are the indentation guides visible? get int GetIndentationGuides=2133(,) # Set the highlighted indentation guide column. # 0 = no highlighted guide. set void SetHighlightGuide=2134(int column,) # Get the highlighted indentation guide column. get int GetHighlightGuide=2135(,) # Get the position after the last visible characters on a line. get position GetLineEndPosition=2136(int line,) # Get the code page used to interpret the bytes of the document as characters. get int GetCodePage=2137(,) # Get the foreground colour of the caret. get colour GetCaretFore=2138(,) # In read-only mode? get bool GetReadOnly=2140(,) # Sets the position of the caret. set void SetCurrentPos=2141(position pos,) # Sets the position that starts the selection - this becomes the anchor. set void SetSelectionStart=2142(position pos,) # Returns the position at the start of the selection. get position GetSelectionStart=2143(,) # Sets the position that ends the selection - this becomes the currentPosition. set void SetSelectionEnd=2144(position pos,) # Returns the position at the end of the selection. get position GetSelectionEnd=2145(,) # Set caret to a position, while removing any existing selection. fun void SetEmptySelection=2556(position pos,) # Sets the print magnification added to the point size of each style for printing. set void SetPrintMagnification=2146(int magnification,) # Returns the print magnification. get int GetPrintMagnification=2147(,) enu PrintOption=SC_PRINT_ # PrintColourMode - use same colours as screen. val SC_PRINT_NORMAL=0 # PrintColourMode - invert the light value of each style for printing. val SC_PRINT_INVERTLIGHT=1 # PrintColourMode - force black text on white background for printing. val SC_PRINT_BLACKONWHITE=2 # PrintColourMode - text stays coloured, but all background is forced to be white for printing. val SC_PRINT_COLOURONWHITE=3 # PrintColourMode - only the default-background is forced to be white for printing. val SC_PRINT_COLOURONWHITEDEFAULTBG=4 # Modify colours when printing for clearer printed text. set void SetPrintColourMode=2148(int mode,) # Returns the print colour mode. get int GetPrintColourMode=2149(,) enu FindOption=SCFIND_ val SCFIND_WHOLEWORD=2 val SCFIND_MATCHCASE=4 val SCFIND_WORDSTART=0x00100000 val SCFIND_REGEXP=0x00200000 val SCFIND_POSIX=0x00400000 # Find some text in the document. fun position FindText=2150(int flags, findtext ft) # On Windows, will draw the document into a display context such as a printer. fun position FormatRange=2151(bool draw, formatrange fr) # Retrieve the display line at the top of the display. get int GetFirstVisibleLine=2152(,) # Retrieve the contents of a line. # Returns the length of the line. fun int GetLine=2153(int line, stringresult text) # Returns the number of lines in the document. There is always at least one. get int GetLineCount=2154(,) # Sets the size in pixels of the left margin. set void SetMarginLeft=2155(, int pixelWidth) # Returns the size in pixels of the left margin. get int GetMarginLeft=2156(,) # Sets the size in pixels of the right margin. set void SetMarginRight=2157(, int pixelWidth) # Returns the size in pixels of the right margin. get int GetMarginRight=2158(,) # Is the document different from when it was last saved? get bool GetModify=2159(,) # Select a range of text. fun void SetSel=2160(position start, position end) # Retrieve the selected text. # Return the length of the text. fun int GetSelText=2161(, stringresult text) # Retrieve a range of text. # Return the length of the text. fun int GetTextRange=2162(, textrange tr) # Draw the selection in normal style or with selection highlighted. fun void HideSelection=2163(bool normal,) # Retrieve the x value of the point in the window where a position is displayed. fun int PointXFromPosition=2164(, position pos) # Retrieve the y value of the point in the window where a position is displayed. fun int PointYFromPosition=2165(, position pos) # Retrieve the line containing a position. fun int LineFromPosition=2166(position pos,) # Retrieve the position at the start of a line. fun position PositionFromLine=2167(int line,) # Scroll horizontally and vertically. fun void LineScroll=2168(int columns, int lines) # Ensure the caret is visible. fun void ScrollCaret=2169(,) # Scroll the argument positions and the range between them into view giving # priority to the primary position then the secondary position. # This may be used to make a search match visible. fun void ScrollRange=2569(position secondary, position primary) # Replace the selected text with the argument text. fun void ReplaceSel=2170(, string text) # Set to read only or read write. set void SetReadOnly=2171(bool readOnly,) # Null operation. fun void Null=2172(,) # Will a paste succeed? fun bool CanPaste=2173(,) # Are there any undoable actions in the undo history? fun bool CanUndo=2174(,) # Delete the undo history. fun void EmptyUndoBuffer=2175(,) # Undo one action in the undo history. fun void Undo=2176(,) # Cut the selection to the clipboard. fun void Cut=2177(,) # Copy the selection to the clipboard. fun void Copy=2178(,) # Paste the contents of the clipboard into the document replacing the selection. fun void Paste=2179(,) # Clear the selection. fun void Clear=2180(,) # Replace the contents of the document with the argument text. fun void SetText=2181(, string text) # Retrieve all the text in the document. # Returns number of characters retrieved. fun int GetText=2182(int length, stringresult text) # Retrieve the number of characters in the document. get int GetTextLength=2183(,) # Retrieve a pointer to a function that processes messages for this Scintilla. get int GetDirectFunction=2184(,) # Retrieve a pointer value to use as the first argument when calling # the function returned by GetDirectFunction. get int GetDirectPointer=2185(,) # Set to overtype (true) or insert mode. set void SetOvertype=2186(bool overtype,) # Returns true if overtype mode is active otherwise false is returned. get bool GetOvertype=2187(,) # Set the width of the insert mode caret. set void SetCaretWidth=2188(int pixelWidth,) # Returns the width of the insert mode caret. get int GetCaretWidth=2189(,) # Sets the position that starts the target which is used for updating the # document without affecting the scroll position. set void SetTargetStart=2190(position pos,) # Get the position that starts the target. get position GetTargetStart=2191(,) # Sets the position that ends the target which is used for updating the # document without affecting the scroll position. set void SetTargetEnd=2192(position pos,) # Get the position that ends the target. get position GetTargetEnd=2193(,) # Replace the target text with the argument text. # Text is counted so it can contain NULs. # Returns the length of the replacement text. fun int ReplaceTarget=2194(int length, string text) # Replace the target text with the argument text after \d processing. # Text is counted so it can contain NULs. # Looks for \d where d is between 1 and 9 and replaces these with the strings # matched in the last search operation which were surrounded by \( and \). # Returns the length of the replacement text including any change # caused by processing the \d patterns. fun int ReplaceTargetRE=2195(int length, string text) # Search for a counted string in the target and set the target to the found # range. Text is counted so it can contain NULs. # Returns length of range or -1 for failure in which case target is not moved. fun int SearchInTarget=2197(int length, string text) # Set the search flags used by SearchInTarget. set void SetSearchFlags=2198(int flags,) # Get the search flags used by SearchInTarget. get int GetSearchFlags=2199(,) # Show a call tip containing a definition near position pos. fun void CallTipShow=2200(position pos, string definition) # Remove the call tip from the screen. fun void CallTipCancel=2201(,) # Is there an active call tip? fun bool CallTipActive=2202(,) # Retrieve the position where the caret was before displaying the call tip. fun position CallTipPosStart=2203(,) # Highlight a segment of the definition. fun void CallTipSetHlt=2204(int start, int end) # Set the background colour for the call tip. set void CallTipSetBack=2205(colour back,) # Set the foreground colour for the call tip. set void CallTipSetFore=2206(colour fore,) # Set the foreground colour for the highlighted part of the call tip. set void CallTipSetForeHlt=2207(colour fore,) # Enable use of STYLE_CALLTIP and set call tip tab size in pixels. set void CallTipUseStyle=2212(int tabSize,) # Set position of calltip, above or below text. set void CallTipSetPosition=2213(bool above,) # Find the display line of a document line taking hidden lines into account. fun int VisibleFromDocLine=2220(int line,) # Find the document line of a display line taking hidden lines into account. fun int DocLineFromVisible=2221(int lineDisplay,) # The number of display lines needed to wrap a document line fun int WrapCount=2235(int line,) enu FoldLevel=SC_FOLDLEVEL val SC_FOLDLEVELBASE=0x400 val SC_FOLDLEVELWHITEFLAG=0x1000 val SC_FOLDLEVELHEADERFLAG=0x2000 val SC_FOLDLEVELNUMBERMASK=0x0FFF # Set the fold level of a line. # This encodes an integer level along with flags indicating whether the # line is a header and whether it is effectively white space. set void SetFoldLevel=2222(int line, int level) # Retrieve the fold level of a line. get int GetFoldLevel=2223(int line,) # Find the last child line of a header line. get int GetLastChild=2224(int line, int level) # Find the parent line of a child line. get int GetFoldParent=2225(int line,) # Make a range of lines visible. fun void ShowLines=2226(int lineStart, int lineEnd) # Make a range of lines invisible. fun void HideLines=2227(int lineStart, int lineEnd) # Is a line visible? get bool GetLineVisible=2228(int line,) # Are all lines visible? get bool GetAllLinesVisible=2236(,) # Show the children of a header line. set void SetFoldExpanded=2229(int line, bool expanded) # Is a header line expanded? get bool GetFoldExpanded=2230(int line,) # Switch a header line between expanded and contracted. fun void ToggleFold=2231(int line,) # Ensure a particular line is visible by expanding any header line hiding it. fun void EnsureVisible=2232(int line,) enu FoldFlag=SC_FOLDFLAG_ val SC_FOLDFLAG_LINEBEFORE_EXPANDED=0x0002 val SC_FOLDFLAG_LINEBEFORE_CONTRACTED=0x0004 val SC_FOLDFLAG_LINEAFTER_EXPANDED=0x0008 val SC_FOLDFLAG_LINEAFTER_CONTRACTED=0x0010 val SC_FOLDFLAG_LEVELNUMBERS=0x0040 # Set some style options for folding. set void SetFoldFlags=2233(int flags,) # Ensure a particular line is visible by expanding any header line hiding it. # Use the currently set visibility policy to determine which range to display. fun void EnsureVisibleEnforcePolicy=2234(int line,) # Sets whether a tab pressed when caret is within indentation indents. set void SetTabIndents=2260(bool tabIndents,) # Does a tab pressed when caret is within indentation indent? get bool GetTabIndents=2261(,) # Sets whether a backspace pressed when caret is within indentation unindents. set void SetBackSpaceUnIndents=2262(bool bsUnIndents,) # Does a backspace pressed when caret is within indentation unindent? get bool GetBackSpaceUnIndents=2263(,) val SC_TIME_FOREVER=10000000 # Sets the time the mouse must sit still to generate a mouse dwell event. set void SetMouseDwellTime=2264(int periodMilliseconds,) # Retrieve the time the mouse must sit still to generate a mouse dwell event. get int GetMouseDwellTime=2265(,) # Get position of start of word. fun int WordStartPosition=2266(position pos, bool onlyWordCharacters) # Get position of end of word. fun int WordEndPosition=2267(position pos, bool onlyWordCharacters) enu Wrap=SC_WRAP_ val SC_WRAP_NONE=0 val SC_WRAP_WORD=1 val SC_WRAP_CHAR=2 # Sets whether text is word wrapped. set void SetWrapMode=2268(int mode,) # Retrieve whether text is word wrapped. get int GetWrapMode=2269(,) enu WrapVisualFlag=SC_WRAPVISUALFLAG_ val SC_WRAPVISUALFLAG_NONE=0x0000 val SC_WRAPVISUALFLAG_END=0x0001 val SC_WRAPVISUALFLAG_START=0x0002 val SC_WRAPVISUALFLAG_MARGIN=0x0004 # Set the display mode of visual flags for wrapped lines. set void SetWrapVisualFlags=2460(int wrapVisualFlags,) # Retrive the display mode of visual flags for wrapped lines. get int GetWrapVisualFlags=2461(,) enu WrapVisualLocation=SC_WRAPVISUALFLAGLOC_ val SC_WRAPVISUALFLAGLOC_DEFAULT=0x0000 val SC_WRAPVISUALFLAGLOC_END_BY_TEXT=0x0001 val SC_WRAPVISUALFLAGLOC_START_BY_TEXT=0x0002 # Set the location of visual flags for wrapped lines. set void SetWrapVisualFlagsLocation=2462(int wrapVisualFlagsLocation,) # Retrive the location of visual flags for wrapped lines. get int GetWrapVisualFlagsLocation=2463(,) # Set the start indent for wrapped lines. set void SetWrapStartIndent=2464(int indent,) # Retrive the start indent for wrapped lines. get int GetWrapStartIndent=2465(,) enu WrapIndentMode=SC_WRAPINDENT_ val SC_WRAPINDENT_FIXED=0 val SC_WRAPINDENT_SAME=1 val SC_WRAPINDENT_INDENT=2 # Sets how wrapped sublines are placed. Default is fixed. set void SetWrapIndentMode=2472(int mode,) # Retrieve how wrapped sublines are placed. Default is fixed. get int GetWrapIndentMode=2473(,) enu LineCache=SC_CACHE_ val SC_CACHE_NONE=0 val SC_CACHE_CARET=1 val SC_CACHE_PAGE=2 val SC_CACHE_DOCUMENT=3 # Sets the degree of caching of layout information. set void SetLayoutCache=2272(int mode,) # Retrieve the degree of caching of layout information. get int GetLayoutCache=2273(,) # Sets the document width assumed for scrolling. set void SetScrollWidth=2274(int pixelWidth,) # Retrieve the document width assumed for scrolling. get int GetScrollWidth=2275(,) # Sets whether the maximum width line displayed is used to set scroll width. set void SetScrollWidthTracking=2516(bool tracking,) # Retrieve whether the scroll width tracks wide lines. get bool GetScrollWidthTracking=2517(,) # Measure the pixel width of some text in a particular style. # NUL terminated text argument. # Does not handle tab or control characters. fun int TextWidth=2276(int style, string text) # Sets the scroll range so that maximum scroll position has # the last line at the bottom of the view (default). # Setting this to false allows scrolling one page below the last line. set void SetEndAtLastLine=2277(bool endAtLastLine,) # Retrieve whether the maximum scroll position has the last # line at the bottom of the view. get bool GetEndAtLastLine=2278(,) # Retrieve the height of a particular line of text in pixels. fun int TextHeight=2279(int line,) # Show or hide the vertical scroll bar. set void SetVScrollBar=2280(bool show,) # Is the vertical scroll bar visible? get bool GetVScrollBar=2281(,) # Append a string to the end of the document without changing the selection. fun void AppendText=2282(int length, string text) # Is drawing done in two phases with backgrounds drawn before faoregrounds? get bool GetTwoPhaseDraw=2283(,) # In twoPhaseDraw mode, drawing is performed in two phases, first the background # and then the foreground. This avoids chopping off characters that overlap the next run. set void SetTwoPhaseDraw=2284(bool twoPhase,) # Control font anti-aliasing. enu FontQuality=SC_EFF_ val SC_EFF_QUALITY_MASK=0xF val SC_EFF_QUALITY_DEFAULT=0 val SC_EFF_QUALITY_NON_ANTIALIASED=1 val SC_EFF_QUALITY_ANTIALIASED=2 val SC_EFF_QUALITY_LCD_OPTIMIZED=3 # Choose the quality level for text from the FontQuality enumeration. set void SetFontQuality=2611(int fontQuality,) # Retrieve the quality level for text. get int GetFontQuality=2612(,) # Scroll so that a display line is at the top of the display. set void SetFirstVisibleLine=2613(int lineDisplay,) enu MultiPaste=SC_MULTIPASTE_ val SC_MULTIPASTE_ONCE=0 val SC_MULTIPASTE_EACH=1 # Change the effect of pasting when there are multiple selections. set void SetMultiPaste=2614(int multiPaste,) # Retrieve the effect of pasting when there are multiple selections.. get int GetMultiPaste=2615(,) # Retrieve the value of a tag from a regular expression search. get int GetTag=2616(int tagNumber, stringresult tagValue) # Make the target range start and end be the same as the selection range start and end. fun void TargetFromSelection=2287(,) # Join the lines in the target. fun void LinesJoin=2288(,) # Split the lines in the target into lines that are less wide than pixelWidth # where possible. fun void LinesSplit=2289(int pixelWidth,) # Set the colours used as a chequerboard pattern in the fold margin fun void SetFoldMarginColour=2290(bool useSetting, colour back) fun void SetFoldMarginHiColour=2291(bool useSetting, colour fore) ## New messages go here ## Start of key messages # Move caret down one line. fun void LineDown=2300(,) # Move caret down one line extending selection to new caret position. fun void LineDownExtend=2301(,) # Move caret up one line. fun void LineUp=2302(,) # Move caret up one line extending selection to new caret position. fun void LineUpExtend=2303(,) # Move caret left one character. fun void CharLeft=2304(,) # Move caret left one character extending selection to new caret position. fun void CharLeftExtend=2305(,) # Move caret right one character. fun void CharRight=2306(,) # Move caret right one character extending selection to new caret position. fun void CharRightExtend=2307(,) # Move caret left one word. fun void WordLeft=2308(,) # Move caret left one word extending selection to new caret position. fun void WordLeftExtend=2309(,) # Move caret right one word. fun void WordRight=2310(,) # Move caret right one word extending selection to new caret position. fun void WordRightExtend=2311(,) # Move caret to first position on line. fun void Home=2312(,) # Move caret to first position on line extending selection to new caret position. fun void HomeExtend=2313(,) # Move caret to last position on line. fun void LineEnd=2314(,) # Move caret to last position on line extending selection to new caret position. fun void LineEndExtend=2315(,) # Move caret to first position in document. fun void DocumentStart=2316(,) # Move caret to first position in document extending selection to new caret position. fun void DocumentStartExtend=2317(,) # Move caret to last position in document. fun void DocumentEnd=2318(,) # Move caret to last position in document extending selection to new caret position. fun void DocumentEndExtend=2319(,) # Move caret one page up. fun void PageUp=2320(,) # Move caret one page up extending selection to new caret position. fun void PageUpExtend=2321(,) # Move caret one page down. fun void PageDown=2322(,) # Move caret one page down extending selection to new caret position. fun void PageDownExtend=2323(,) # Switch from insert to overtype mode or the reverse. fun void EditToggleOvertype=2324(,) # Cancel any modes such as call tip or auto-completion list display. fun void Cancel=2325(,) # Delete the selection or if no selection, the character before the caret. fun void DeleteBack=2326(,) # If selection is empty or all on one line replace the selection with a tab character. # If more than one line selected, indent the lines. fun void Tab=2327(,) # Dedent the selected lines. fun void BackTab=2328(,) # Insert a new line, may use a CRLF, CR or LF depending on EOL mode. fun void NewLine=2329(,) # Insert a Form Feed character. fun void FormFeed=2330(,) # Move caret to before first visible character on line. # If already there move to first character on line. fun void VCHome=2331(,) # Like VCHome but extending selection to new caret position. fun void VCHomeExtend=2332(,) # Magnify the displayed text by increasing the sizes by 1 point. fun void ZoomIn=2333(,) # Make the displayed text smaller by decreasing the sizes by 1 point. fun void ZoomOut=2334(,) # Delete the word to the left of the caret. fun void DelWordLeft=2335(,) # Delete the word to the right of the caret. fun void DelWordRight=2336(,) # Delete the word to the right of the caret, but not the trailing non-word characters. fun void DelWordRightEnd=2518(,) # Cut the line containing the caret. fun void LineCut=2337(,) # Delete the line containing the caret. fun void LineDelete=2338(,) # Switch the current line with the previous. fun void LineTranspose=2339(,) # Duplicate the current line. fun void LineDuplicate=2404(,) # Transform the selection to lower case. fun void LowerCase=2340(,) # Transform the selection to upper case. fun void UpperCase=2341(,) # Scroll the document down, keeping the caret visible. fun void LineScrollDown=2342(,) # Scroll the document up, keeping the caret visible. fun void LineScrollUp=2343(,) # Delete the selection or if no selection, the character before the caret. # Will not delete the character before at the start of a line. fun void DeleteBackNotLine=2344(,) # Move caret to first position on display line. fun void HomeDisplay=2345(,) # Move caret to first position on display line extending selection to # new caret position. fun void HomeDisplayExtend=2346(,) # Move caret to last position on display line. fun void LineEndDisplay=2347(,) # Move caret to last position on display line extending selection to new # caret position. fun void LineEndDisplayExtend=2348(,) # These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)? # except they behave differently when word-wrap is enabled: # They go first to the start / end of the display line, like (Home|LineEnd)Display # The difference is that, the cursor is already at the point, it goes on to the start # or end of the document line, as appropriate for (Home|LineEnd|VCHome)(Extend)?. fun void HomeWrap=2349(,) fun void HomeWrapExtend=2450(,) fun void LineEndWrap=2451(,) fun void LineEndWrapExtend=2452(,) fun void VCHomeWrap=2453(,) fun void VCHomeWrapExtend=2454(,) # Copy the line containing the caret. fun void LineCopy=2455(,) # Move the caret inside current view if it's not there already. fun void MoveCaretInsideView=2401(,) # How many characters are on a line, including end of line characters? fun int LineLength=2350(int line,) # Highlight the characters at two positions. fun void BraceHighlight=2351(position pos1, position pos2) # Use specified indicator to highlight matching braces instead of changing their style. fun void BraceHighlightIndicator=2498(bool useBraceHighlightIndicator, int indicator) # Highlight the character at a position indicating there is no matching brace. fun void BraceBadLight=2352(position pos,) # Use specified indicator to highlight non matching brace instead of changing its style. fun void BraceBadLightIndicator=2499(bool useBraceBadLightIndicator, int indicator) # Find the position of a matching brace or INVALID_POSITION if no match. fun position BraceMatch=2353(position pos,) # Are the end of line characters visible? get bool GetViewEOL=2355(,) # Make the end of line characters visible or invisible. set void SetViewEOL=2356(bool visible,) # Retrieve a pointer to the document object. get int GetDocPointer=2357(,) # Change the document object used. set void SetDocPointer=2358(, int pointer) # Set which document modification events are sent to the container. set void SetModEventMask=2359(int mask,) enu EdgeVisualStyle=EDGE_ val EDGE_NONE=0 val EDGE_LINE=1 val EDGE_BACKGROUND=2 # Retrieve the column number which text should be kept within. get int GetEdgeColumn=2360(,) # Set the column number of the edge. # If text goes past the edge then it is highlighted. set void SetEdgeColumn=2361(int column,) # Retrieve the edge highlight mode. get int GetEdgeMode=2362(,) # The edge may be displayed by a line (EDGE_LINE) or by highlighting text that # goes beyond it (EDGE_BACKGROUND) or not displayed at all (EDGE_NONE). set void SetEdgeMode=2363(int mode,) # Retrieve the colour used in edge indication. get colour GetEdgeColour=2364(,) # Change the colour used in edge indication. set void SetEdgeColour=2365(colour edgeColour,) # Sets the current caret position to be the search anchor. fun void SearchAnchor=2366(,) # Find some text starting at the search anchor. # Does not ensure the selection is visible. fun int SearchNext=2367(int flags, string text) # Find some text starting at the search anchor and moving backwards. # Does not ensure the selection is visible. fun int SearchPrev=2368(int flags, string text) # Retrieves the number of lines completely visible. get int LinesOnScreen=2370(,) # Set whether a pop up menu is displayed automatically when the user presses # the wrong mouse button. fun void UsePopUp=2371(bool allowPopUp,) # Is the selection rectangular? The alternative is the more common stream selection. get bool SelectionIsRectangle=2372(,) # Set the zoom level. This number of points is added to the size of all fonts. # It may be positive to magnify or negative to reduce. set void SetZoom=2373(int zoom,) # Retrieve the zoom level. get int GetZoom=2374(,) # Create a new document object. # Starts with reference count of 1 and not selected into editor. fun int CreateDocument=2375(,) # Extend life of document. fun void AddRefDocument=2376(, int doc) # Release a reference to the document, deleting document if it fades to black. fun void ReleaseDocument=2377(, int doc) # Get which document modification events are sent to the container. get int GetModEventMask=2378(,) # Change internal focus flag. set void SetFocus=2380(bool focus,) # Get internal focus flag. get bool GetFocus=2381(,) enu Status=SC_STATUS_ val SC_STATUS_OK=0 val SC_STATUS_FAILURE=1 val SC_STATUS_BADALLOC=2 # Change error status - 0 = OK. set void SetStatus=2382(int statusCode,) # Get error status. get int GetStatus=2383(,) # Set whether the mouse is captured when its button is pressed. set void SetMouseDownCaptures=2384(bool captures,) # Get whether mouse gets captured. get bool GetMouseDownCaptures=2385(,) enu CursorShape=SC_CURSOR val SC_CURSORNORMAL=-1 val SC_CURSORARROW=2 val SC_CURSORWAIT=4 val SC_CURSORREVERSEARROW=7 # Sets the cursor to one of the SC_CURSOR* values. set void SetCursor=2386(int cursorType,) # Get cursor type. get int GetCursor=2387(,) # Change the way control characters are displayed: # If symbol is < 32, keep the drawn way, else, use the given character. set void SetControlCharSymbol=2388(int symbol,) # Get the way control characters are displayed. get int GetControlCharSymbol=2389(,) # Move to the previous change in capitalisation. fun void WordPartLeft=2390(,) # Move to the previous change in capitalisation extending selection # to new caret position. fun void WordPartLeftExtend=2391(,) # Move to the change next in capitalisation. fun void WordPartRight=2392(,) # Move to the next change in capitalisation extending selection # to new caret position. fun void WordPartRightExtend=2393(,) # Constants for use with SetVisiblePolicy, similar to SetCaretPolicy. val VISIBLE_SLOP=0x01 val VISIBLE_STRICT=0x04 # Set the way the display area is determined when a particular line # is to be moved to by Find, FindNext, GotoLine, etc. fun void SetVisiblePolicy=2394(int visiblePolicy, int visibleSlop) # Delete back from the current position to the start of the line. fun void DelLineLeft=2395(,) # Delete forwards from the current position to the end of the line. fun void DelLineRight=2396(,) # Get and Set the xOffset (ie, horizontal scroll position). set void SetXOffset=2397(int newOffset,) get int GetXOffset=2398(,) # Set the last x chosen value to be the caret x position. fun void ChooseCaretX=2399(,) # Set the focus to this Scintilla widget. fun void GrabFocus=2400(,) enu CaretPolicy=CARET_ # Caret policy, used by SetXCaretPolicy and SetYCaretPolicy. # If CARET_SLOP is set, we can define a slop value: caretSlop. # This value defines an unwanted zone (UZ) where the caret is... unwanted. # This zone is defined as a number of pixels near the vertical margins, # and as a number of lines near the horizontal margins. # By keeping the caret away from the edges, it is seen within its context, # so it is likely that the identifier that the caret is on can be completely seen, # and that the current line is seen with some of the lines following it which are # often dependent on that line. val CARET_SLOP=0x01 # If CARET_STRICT is set, the policy is enforced... strictly. # The caret is centred on the display if slop is not set, # and cannot go in the UZ if slop is set. val CARET_STRICT=0x04 # If CARET_JUMPS is set, the display is moved more energetically # so the caret can move in the same direction longer before the policy is applied again. val CARET_JUMPS=0x10 # If CARET_EVEN is not set, instead of having symmetrical UZs, # the left and bottom UZs are extended up to right and top UZs respectively. # This way, we favour the displaying of useful information: the begining of lines, # where most code reside, and the lines after the caret, eg. the body of a function. val CARET_EVEN=0x08 # Set the way the caret is kept visible when going sideways. # The exclusion zone is given in pixels. fun void SetXCaretPolicy=2402(int caretPolicy, int caretSlop) # Set the way the line the caret is on is kept visible. # The exclusion zone is given in lines. fun void SetYCaretPolicy=2403(int caretPolicy, int caretSlop) # Set printing to line wrapped (SC_WRAP_WORD) or not line wrapped (SC_WRAP_NONE). set void SetPrintWrapMode=2406(int mode,) # Is printing line wrapped? get int GetPrintWrapMode=2407(,) # Set a fore colour for active hotspots. set void SetHotspotActiveFore=2410(bool useSetting, colour fore) # Get the fore colour for active hotspots. get colour GetHotspotActiveFore=2494(,) # Set a back colour for active hotspots. set void SetHotspotActiveBack=2411(bool useSetting, colour back) # Get the back colour for active hotspots. get colour GetHotspotActiveBack=2495(,) # Enable / Disable underlining active hotspots. set void SetHotspotActiveUnderline=2412(bool underline,) # Get whether underlining for active hotspots. get bool GetHotspotActiveUnderline=2496(,) # Limit hotspots to single line so hotspots on two lines don't merge. set void SetHotspotSingleLine=2421(bool singleLine,) # Get the HotspotSingleLine property get bool GetHotspotSingleLine=2497(,) # Move caret between paragraphs (delimited by empty lines). fun void ParaDown=2413(,) fun void ParaDownExtend=2414(,) fun void ParaUp=2415(,) fun void ParaUpExtend=2416(,) # Given a valid document position, return the previous position taking code # page into account. Returns 0 if passed 0. fun position PositionBefore=2417(position pos,) # Given a valid document position, return the next position taking code # page into account. Maximum value returned is the last position in the document. fun position PositionAfter=2418(position pos,) # Copy a range of text to the clipboard. Positions are clipped into the document. fun void CopyRange=2419(position start, position end) # Copy argument text to the clipboard. fun void CopyText=2420(int length, string text) enu SelectionMode=SC_SEL_ val SC_SEL_STREAM=0 val SC_SEL_RECTANGLE=1 val SC_SEL_LINES=2 val SC_SEL_THIN=3 # Set the selection mode to stream (SC_SEL_STREAM) or rectangular (SC_SEL_RECTANGLE/SC_SEL_THIN) or # by lines (SC_SEL_LINES). set void SetSelectionMode=2422(int mode,) # Get the mode of the current selection. get int GetSelectionMode=2423(,) # Retrieve the position of the start of the selection at the given line (INVALID_POSITION if no selection on this line). fun position GetLineSelStartPosition=2424(int line,) # Retrieve the position of the end of the selection at the given line (INVALID_POSITION if no selection on this line). fun position GetLineSelEndPosition=2425(int line,) ## RectExtended rectangular selection moves # Move caret down one line, extending rectangular selection to new caret position. fun void LineDownRectExtend=2426(,) # Move caret up one line, extending rectangular selection to new caret position. fun void LineUpRectExtend=2427(,) # Move caret left one character, extending rectangular selection to new caret position. fun void CharLeftRectExtend=2428(,) # Move caret right one character, extending rectangular selection to new caret position. fun void CharRightRectExtend=2429(,) # Move caret to first position on line, extending rectangular selection to new caret position. fun void HomeRectExtend=2430(,) # Move caret to before first visible character on line. # If already there move to first character on line. # In either case, extend rectangular selection to new caret position. fun void VCHomeRectExtend=2431(,) # Move caret to last position on line, extending rectangular selection to new caret position. fun void LineEndRectExtend=2432(,) # Move caret one page up, extending rectangular selection to new caret position. fun void PageUpRectExtend=2433(,) # Move caret one page down, extending rectangular selection to new caret position. fun void PageDownRectExtend=2434(,) # Move caret to top of page, or one page up if already at top of page. fun void StutteredPageUp=2435(,) # Move caret to top of page, or one page up if already at top of page, extending selection to new caret position. fun void StutteredPageUpExtend=2436(,) # Move caret to bottom of page, or one page down if already at bottom of page. fun void StutteredPageDown=2437(,) # Move caret to bottom of page, or one page down if already at bottom of page, extending selection to new caret position. fun void StutteredPageDownExtend=2438(,) # Move caret left one word, position cursor at end of word. fun void WordLeftEnd=2439(,) # Move caret left one word, position cursor at end of word, extending selection to new caret position. fun void WordLeftEndExtend=2440(,) # Move caret right one word, position cursor at end of word. fun void WordRightEnd=2441(,) # Move caret right one word, position cursor at end of word, extending selection to new caret position. fun void WordRightEndExtend=2442(,) # Set the set of characters making up whitespace for when moving or selecting by word. # Should be called after SetWordChars. set void SetWhitespaceChars=2443(, string characters) # Get the set of characters making up whitespace for when moving or selecting by word. get int GetWhitespaceChars=2647(, stringresult characters) # Set the set of characters making up punctuation characters # Should be called after SetWordChars. set void SetPunctuationChars=2648(, string characters) # Get the set of characters making up punctuation characters get int GetPunctuationChars=2649(, stringresult characters) # Reset the set of characters for whitespace and word characters to the defaults. fun void SetCharsDefault=2444(,) # Get currently selected item position in the auto-completion list get int AutoCGetCurrent=2445(,) # Get currently selected item text in the auto-completion list # Returns the length of the item text get int AutoCGetCurrentText=2610(, stringresult s) enu CaseInsensitiveBehaviour=SC_CASEINSENSITIVEBEHAVIOUR_ val SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE=0 val SC_CASEINSENSITIVEBEHAVIOUR_IGNORECASE=1 # Set auto-completion case insensitive behaviour to either prefer case-sensitive matches or have no preference. set void AutoCSetCaseInsensitiveBehaviour=2634(int behaviour,) # Get auto-completion case insensitive behaviour. get int AutoCGetCaseInsensitiveBehaviour=2635(,) # Enlarge the document to a particular size of text bytes. fun void Allocate=2446(int bytes,) # Returns the target converted to UTF8. # Return the length in bytes. fun int TargetAsUTF8=2447(, stringresult s) # Set the length of the utf8 argument for calling EncodedFromUTF8. # Set to -1 and the string will be measured to the first nul. fun void SetLengthForEncode=2448(int bytes,) # Translates a UTF8 string into the document encoding. # Return the length of the result in bytes. # On error return 0. fun int EncodedFromUTF8=2449(string utf8, stringresult encoded) # Find the position of a column on a line taking into account tabs and # multi-byte characters. If beyond end of line, return line end position. fun int FindColumn=2456(int line, int column) # Can the caret preferred x position only be changed by explicit movement commands? get int GetCaretSticky=2457(,) # Stop the caret preferred x position changing when the user types. set void SetCaretSticky=2458(int useCaretStickyBehaviour,) enu CaretSticky=SC_CARETSTICKY_ val SC_CARETSTICKY_OFF=0 val SC_CARETSTICKY_ON=1 val SC_CARETSTICKY_WHITESPACE=2 # Switch between sticky and non-sticky: meant to be bound to a key. fun void ToggleCaretSticky=2459(,) # Enable/Disable convert-on-paste for line endings set void SetPasteConvertEndings=2467(bool convert,) # Get convert-on-paste setting get bool GetPasteConvertEndings=2468(,) # Duplicate the selection. If selection empty duplicate the line containing the caret. fun void SelectionDuplicate=2469(,) val SC_ALPHA_TRANSPARENT=0 val SC_ALPHA_OPAQUE=255 val SC_ALPHA_NOALPHA=256 # Set background alpha of the caret line. set void SetCaretLineBackAlpha=2470(int alpha,) # Get the background alpha of the caret line. get int GetCaretLineBackAlpha=2471(,) enu CaretStyle=CARETSTYLE_ val CARETSTYLE_INVISIBLE=0 val CARETSTYLE_LINE=1 val CARETSTYLE_BLOCK=2 # Set the style of the caret to be drawn. set void SetCaretStyle=2512(int caretStyle,) # Returns the current style of the caret. get int GetCaretStyle=2513(,) # Set the indicator used for IndicatorFillRange and IndicatorClearRange set void SetIndicatorCurrent=2500(int indicator,) # Get the current indicator get int GetIndicatorCurrent=2501(,) # Set the value used for IndicatorFillRange set void SetIndicatorValue=2502(int value,) # Get the current indicator value get int GetIndicatorValue=2503(,) # Turn a indicator on over a range. fun void IndicatorFillRange=2504(int position, int fillLength) # Turn a indicator off over a range. fun void IndicatorClearRange=2505(int position, int clearLength) # Are any indicators present at position? fun int IndicatorAllOnFor=2506(int position,) # What value does a particular indicator have at at a position? fun int IndicatorValueAt=2507(int indicator, int position) # Where does a particular indicator start? fun int IndicatorStart=2508(int indicator, int position) # Where does a particular indicator end? fun int IndicatorEnd=2509(int indicator, int position) # Set number of entries in position cache set void SetPositionCache=2514(int size,) # How many entries are allocated to the position cache? get int GetPositionCache=2515(,) # Copy the selection, if selection empty copy the line with the caret fun void CopyAllowLine=2519(,) # Compact the document buffer and return a read-only pointer to the # characters in the document. get int GetCharacterPointer=2520(,) # Return a read-only pointer to a range of characters in the document. # May move the gap so that the range is contiguous, but will only move up # to rangeLength bytes. get int GetRangePointer=2643(int position, int rangeLength) # Return a position which, to avoid performance costs, should not be within # the range of a call to GetRangePointer. get position GetGapPosition=2644(,) # Always interpret keyboard input as Unicode set void SetKeysUnicode=2521(bool keysUnicode,) # Are keys always interpreted as Unicode? get bool GetKeysUnicode=2522(,) # Set the alpha fill colour of the given indicator. set void IndicSetAlpha=2523(int indicator, int alpha) # Get the alpha fill colour of the given indicator. get int IndicGetAlpha=2524(int indicator,) # Set the alpha outline colour of the given indicator. set void IndicSetOutlineAlpha=2558(int indicator, int alpha) # Get the alpha outline colour of the given indicator. get int IndicGetOutlineAlpha=2559(int indicator,) # Set extra ascent for each line set void SetExtraAscent=2525(int extraAscent,) # Get extra ascent for each line get int GetExtraAscent=2526(,) # Set extra descent for each line set void SetExtraDescent=2527(int extraDescent,) # Get extra descent for each line get int GetExtraDescent=2528(,) # Which symbol was defined for markerNumber with MarkerDefine fun int MarkerSymbolDefined=2529(int markerNumber,) # Set the text in the text margin for a line set void MarginSetText=2530(int line, string text) # Get the text in the text margin for a line get int MarginGetText=2531(int line, stringresult text) # Set the style number for the text margin for a line set void MarginSetStyle=2532(int line, int style) # Get the style number for the text margin for a line get int MarginGetStyle=2533(int line,) # Set the style in the text margin for a line set void MarginSetStyles=2534(int line, string styles) # Get the styles in the text margin for a line get int MarginGetStyles=2535(int line, stringresult styles) # Clear the margin text on all lines fun void MarginTextClearAll=2536(,) # Get the start of the range of style numbers used for margin text set void MarginSetStyleOffset=2537(int style,) # Get the start of the range of style numbers used for margin text get int MarginGetStyleOffset=2538(,) enu MarginOption=SC_MARGINOPTION_ val SC_MARGINOPTION_NONE=0 val SC_MARGINOPTION_SUBLINESELECT=1 # Set the margin options. set void SetMarginOptions=2539(int marginOptions,) # Get the margin options. get int GetMarginOptions=2557(,) # Set the annotation text for a line set void AnnotationSetText=2540(int line, string text) # Get the annotation text for a line get int AnnotationGetText=2541(int line, stringresult text) # Set the style number for the annotations for a line set void AnnotationSetStyle=2542(int line, int style) # Get the style number for the annotations for a line get int AnnotationGetStyle=2543(int line,) # Set the annotation styles for a line set void AnnotationSetStyles=2544(int line, string styles) # Get the annotation styles for a line get int AnnotationGetStyles=2545(int line, stringresult styles) # Get the number of annotation lines for a line get int AnnotationGetLines=2546(int line,) # Clear the annotations from all lines fun void AnnotationClearAll=2547(,) enu AnnotationVisible=ANNOTATION_ val ANNOTATION_HIDDEN=0 val ANNOTATION_STANDARD=1 val ANNOTATION_BOXED=2 # Set the visibility for the annotations for a view set void AnnotationSetVisible=2548(int visible,) # Get the visibility for the annotations for a view get int AnnotationGetVisible=2549(,) # Get the start of the range of style numbers used for annotations set void AnnotationSetStyleOffset=2550(int style,) # Get the start of the range of style numbers used for annotations get int AnnotationGetStyleOffset=2551(,) # Release all extended (>255) style numbers fun void ReleaseAllExtendedStyles=2552(,) # Allocate some extended (>255) style numbers and return the start of the range fun int AllocateExtendedStyles=2553(int numberStyles,) val UNDO_MAY_COALESCE=1 # Add a container action to the undo stack fun void AddUndoAction=2560(int token, int flags) # Find the position of a character from a point within the window. fun position CharPositionFromPoint=2561(int x, int y) # Find the position of a character from a point within the window. # Return INVALID_POSITION if not close to text. fun position CharPositionFromPointClose=2562(int x, int y) # Set whether multiple selections can be made set void SetMultipleSelection=2563(bool multipleSelection,) # Whether multiple selections can be made get bool GetMultipleSelection=2564(,) # Set whether typing can be performed into multiple selections set void SetAdditionalSelectionTyping=2565(bool additionalSelectionTyping,) # Whether typing can be performed into multiple selections get bool GetAdditionalSelectionTyping=2566(,) # Set whether additional carets will blink set void SetAdditionalCaretsBlink=2567(bool additionalCaretsBlink,) # Whether additional carets will blink get bool GetAdditionalCaretsBlink=2568(,) # Set whether additional carets are visible set void SetAdditionalCaretsVisible=2608(bool additionalCaretsBlink,) # Whether additional carets are visible get bool GetAdditionalCaretsVisible=2609(,) # How many selections are there? get int GetSelections=2570(,) # Is every selected range empty? get bool GetSelectionEmpty=2650(,) # Clear selections to a single empty stream selection fun void ClearSelections=2571(,) # Set a simple selection fun int SetSelection=2572(int caret, int anchor) # Add a selection fun int AddSelection=2573(int caret, int anchor) # Set the main selection set void SetMainSelection=2574(int selection,) # Which selection is the main selection get int GetMainSelection=2575(,) set void SetSelectionNCaret=2576(int selection, position pos) get position GetSelectionNCaret=2577(int selection,) set void SetSelectionNAnchor=2578(int selection, position posAnchor) get position GetSelectionNAnchor=2579(int selection,) set void SetSelectionNCaretVirtualSpace=2580(int selection, int space) get int GetSelectionNCaretVirtualSpace=2581(int selection,) set void SetSelectionNAnchorVirtualSpace=2582(int selection, int space) get int GetSelectionNAnchorVirtualSpace=2583(int selection,) # Sets the position that starts the selection - this becomes the anchor. set void SetSelectionNStart=2584(int selection, position pos) # Returns the position at the start of the selection. get position GetSelectionNStart=2585(int selection,) # Sets the position that ends the selection - this becomes the currentPosition. set void SetSelectionNEnd=2586(int selection, position pos) # Returns the position at the end of the selection. get position GetSelectionNEnd=2587(int selection,) set void SetRectangularSelectionCaret=2588(position pos,) get position GetRectangularSelectionCaret=2589(,) set void SetRectangularSelectionAnchor=2590(position posAnchor,) get position GetRectangularSelectionAnchor=2591(,) set void SetRectangularSelectionCaretVirtualSpace=2592(int space,) get int GetRectangularSelectionCaretVirtualSpace=2593(,) set void SetRectangularSelectionAnchorVirtualSpace=2594(int space,) get int GetRectangularSelectionAnchorVirtualSpace=2595(,) enu VirtualSpace=SCVS_ val SCVS_NONE=0 val SCVS_RECTANGULARSELECTION=1 val SCVS_USERACCESSIBLE=2 set void SetVirtualSpaceOptions=2596(int virtualSpaceOptions,) get int GetVirtualSpaceOptions=2597(,) # On GTK+, allow selecting the modifier key to use for mouse-based # rectangular selection. Often the window manager requires Alt+Mouse Drag # for moving windows. # Valid values are SCMOD_CTRL(default), SCMOD_ALT, or SCMOD_SUPER. set void SetRectangularSelectionModifier=2598(int modifier,) # Get the modifier key used for rectangular selection. get int GetRectangularSelectionModifier=2599(,) # Set the foreground colour of additional selections. # Must have previously called SetSelFore with non-zero first argument for this to have an effect. set void SetAdditionalSelFore=2600(colour fore,) # Set the background colour of additional selections. # Must have previously called SetSelBack with non-zero first argument for this to have an effect. set void SetAdditionalSelBack=2601(colour back,) # Set the alpha of the selection. set void SetAdditionalSelAlpha=2602(int alpha,) # Get the alpha of the selection. get int GetAdditionalSelAlpha=2603(,) # Set the foreground colour of additional carets. set void SetAdditionalCaretFore=2604(colour fore,) # Get the foreground colour of additional carets. get colour GetAdditionalCaretFore=2605(,) # Set the main selection to the next selection. fun void RotateSelection=2606(,) # Swap that caret and anchor of the main selection. fun void SwapMainAnchorCaret=2607(,) # Indicate that the internal state of a lexer has changed over a range and therefore # there may be a need to redraw. fun int ChangeLexerState=2617(position start, position end) # Find the next line at or after lineStart that is a contracted fold header line. # Return -1 when no more lines. fun int ContractedFoldNext=2618(int lineStart,) # Centre current line in window. fun void VerticalCentreCaret=2619(,) # Move the selected lines up one line, shifting the line above after the selection fun void MoveSelectedLinesUp=2620(,) # Move the selected lines down one line, shifting the line below before the selection fun void MoveSelectedLinesDown=2621(,) # Set the identifier reported as idFrom in notification messages. set void SetIdentifier=2622(int identifier,) # Get the identifier. get int GetIdentifier=2623(,) # Set the width for future RGBA image data. set void RGBAImageSetWidth=2624(int width,) # Set the height for future RGBA image data. set void RGBAImageSetHeight=2625(int height,) # Set the scale factor in percent for future RGBA image data. set void RGBAImageSetScale=2651(int scalePercent,) # Define a marker from RGBA data. # It has the width and height from RGBAImageSetWidth/Height fun void MarkerDefineRGBAImage=2626(int markerNumber, string pixels) # Register an RGBA image for use in autocompletion lists. # It has the width and height from RGBAImageSetWidth/Height fun void RegisterRGBAImage=2627(int type, string pixels) # Scroll to start of document. fun void ScrollToStart=2628(,) # Scroll to end of document. fun void ScrollToEnd=2629(,) val SC_TECHNOLOGY_DEFAULT=0 val SC_TECHNOLOGY_DIRECTWRITE=1 # Set the technology used. set void SetTechnology=2630(int technology,) # Get the tech. get int GetTechnology=2631(,) # Create an ILoader*. fun int CreateLoader=2632(int bytes,) # On OS X, show a find indicator. fun void FindIndicatorShow=2640(position start, position end) # On OS X, flash a find indicator, then fade out. fun void FindIndicatorFlash=2641(position start, position end) # On OS X, hide the find indicator. fun void FindIndicatorHide=2642(,) # Move caret to before first visible character on display line. # If already there move to first character on display line. fun void VCHomeDisplay=2652(,) # Like VCHomeDisplay but extending selection to new caret position. fun void VCHomeDisplayExtend=2653(,) # Is the caret line always visible? get bool GetCaretLineVisibleAlways=2654(,) # Sets the caret line to always visible. set void SetCaretLineVisibleAlways=2655(bool alwaysVisible,) # Start notifying the container of all key presses and commands. fun void StartRecord=3001(,) # Stop notifying the container of all key presses and commands. fun void StopRecord=3002(,) # Set the lexing language of the document. set void SetLexer=4001(int lexer,) # Retrieve the lexing language of the document. get int GetLexer=4002(,) # Colourise a segment of the document using the current lexing language. fun void Colourise=4003(position start, position end) # Set up a value that may be used by a lexer for some optional feature. set void SetProperty=4004(string key, string value) # Maximum value of keywordSet parameter of SetKeyWords. val KEYWORDSET_MAX=8 # Set up the key words used by the lexer. set void SetKeyWords=4005(int keywordSet, string keyWords) # Set the lexing language of the document based on string name. set void SetLexerLanguage=4006(, string language) # Load a lexer library (dll / so). fun void LoadLexerLibrary=4007(, string path) # Retrieve a "property" value previously set with SetProperty. get int GetProperty=4008(string key, stringresult buf) # Retrieve a "property" value previously set with SetProperty, # with "$()" variable replacement on returned buffer. get int GetPropertyExpanded=4009(string key, stringresult buf) # Retrieve a "property" value previously set with SetProperty, # interpreted as an int AFTER any "$()" variable replacement. get int GetPropertyInt=4010(string key,) # Retrieve the number of bits the current lexer needs for styling. get int GetStyleBitsNeeded=4011(,) # Retrieve the name of the lexer. # Return the length of the text. get int GetLexerLanguage=4012(, stringresult text) # For private communication between an application and a known lexer. fun int PrivateLexerCall=4013(int operation, int pointer) # Retrieve a '\n' separated list of properties understood by the current lexer. fun int PropertyNames=4014(, stringresult names) enu TypeProperty=SC_TYPE_ val SC_TYPE_BOOLEAN=0 val SC_TYPE_INTEGER=1 val SC_TYPE_STRING=2 # Retrieve the type of a property. fun int PropertyType=4015(string name,) # Describe a property. fun int DescribeProperty=4016(string name, stringresult description) # Retrieve a '\n' separated list of descriptions of the keyword sets understood by the current lexer. fun int DescribeKeyWordSets=4017(, stringresult descriptions) # Notifications # Type of modification and the action which caused the modification. # These are defined as a bit mask to make it easy to specify which notifications are wanted. # One bit is set from each of SC_MOD_* and SC_PERFORMED_*. enu ModificationFlags=SC_MOD_ SC_PERFORMED_ SC_MULTISTEPUNDOREDO SC_LASTSTEPINUNDOREDO SC_MULTILINEUNDOREDO SC_STARTACTION SC_MODEVENTMASKALL val SC_MOD_INSERTTEXT=0x1 val SC_MOD_DELETETEXT=0x2 val SC_MOD_CHANGESTYLE=0x4 val SC_MOD_CHANGEFOLD=0x8 val SC_PERFORMED_USER=0x10 val SC_PERFORMED_UNDO=0x20 val SC_PERFORMED_REDO=0x40 val SC_MULTISTEPUNDOREDO=0x80 val SC_LASTSTEPINUNDOREDO=0x100 val SC_MOD_CHANGEMARKER=0x200 val SC_MOD_BEFOREINSERT=0x400 val SC_MOD_BEFOREDELETE=0x800 val SC_MULTILINEUNDOREDO=0x1000 val SC_STARTACTION=0x2000 val SC_MOD_CHANGEINDICATOR=0x4000 val SC_MOD_CHANGELINESTATE=0x8000 val SC_MOD_CHANGEMARGIN=0x10000 val SC_MOD_CHANGEANNOTATION=0x20000 val SC_MOD_CONTAINER=0x40000 val SC_MOD_LEXERSTATE=0x80000 val SC_MODEVENTMASKALL=0xFFFFF enu Update=SC_UPDATE_ val SC_UPDATE_CONTENT=0x1 val SC_UPDATE_SELECTION=0x2 val SC_UPDATE_V_SCROLL=0x4 val SC_UPDATE_H_SCROLL=0x8 # For compatibility, these go through the COMMAND notification rather than NOTIFY # and should have had exactly the same values as the EN_* constants. # Unfortunately the SETFOCUS and KILLFOCUS are flipped over from EN_* # As clients depend on these constants, this will not be changed. val SCEN_CHANGE=768 val SCEN_SETFOCUS=512 val SCEN_KILLFOCUS=256 # Symbolic key codes and modifier flags. # ASCII and other printable characters below 256. # Extended keys above 300. enu Keys=SCK_ val SCK_DOWN=300 val SCK_UP=301 val SCK_LEFT=302 val SCK_RIGHT=303 val SCK_HOME=304 val SCK_END=305 val SCK_PRIOR=306 val SCK_NEXT=307 val SCK_DELETE=308 val SCK_INSERT=309 val SCK_ESCAPE=7 val SCK_BACK=8 val SCK_TAB=9 val SCK_RETURN=13 val SCK_ADD=310 val SCK_SUBTRACT=311 val SCK_DIVIDE=312 val SCK_WIN=313 val SCK_RWIN=314 val SCK_MENU=315 enu KeyMod=SCMOD_ val SCMOD_NORM=0 val SCMOD_SHIFT=1 val SCMOD_CTRL=2 val SCMOD_ALT=4 val SCMOD_SUPER=8 val SCMOD_META=16 ################################################ # For SciLexer.h enu Lexer=SCLEX_ val SCLEX_CONTAINER=0 val SCLEX_NULL=1 val SCLEX_PYTHON=2 val SCLEX_CPP=3 val SCLEX_HTML=4 val SCLEX_XML=5 val SCLEX_PERL=6 val SCLEX_SQL=7 val SCLEX_VB=8 val SCLEX_PROPERTIES=9 val SCLEX_ERRORLIST=10 val SCLEX_MAKEFILE=11 val SCLEX_BATCH=12 val SCLEX_XCODE=13 val SCLEX_LATEX=14 val SCLEX_LUA=15 val SCLEX_DIFF=16 val SCLEX_CONF=17 val SCLEX_PASCAL=18 val SCLEX_AVE=19 val SCLEX_ADA=20 val SCLEX_LISP=21 val SCLEX_RUBY=22 val SCLEX_EIFFEL=23 val SCLEX_EIFFELKW=24 val SCLEX_TCL=25 val SCLEX_NNCRONTAB=26 val SCLEX_BULLANT=27 val SCLEX_VBSCRIPT=28 val SCLEX_BAAN=31 val SCLEX_MATLAB=32 val SCLEX_SCRIPTOL=33 val SCLEX_ASM=34 val SCLEX_CPPNOCASE=35 val SCLEX_FORTRAN=36 val SCLEX_F77=37 val SCLEX_CSS=38 val SCLEX_POV=39 val SCLEX_LOUT=40 val SCLEX_ESCRIPT=41 val SCLEX_PS=42 val SCLEX_NSIS=43 val SCLEX_MMIXAL=44 val SCLEX_CLW=45 val SCLEX_CLWNOCASE=46 val SCLEX_LOT=47 val SCLEX_YAML=48 val SCLEX_TEX=49 val SCLEX_METAPOST=50 val SCLEX_POWERBASIC=51 val SCLEX_FORTH=52 val SCLEX_ERLANG=53 val SCLEX_OCTAVE=54 val SCLEX_MSSQL=55 val SCLEX_VERILOG=56 val SCLEX_KIX=57 val SCLEX_GUI4CLI=58 val SCLEX_SPECMAN=59 val SCLEX_AU3=60 val SCLEX_APDL=61 val SCLEX_BASH=62 val SCLEX_ASN1=63 val SCLEX_VHDL=64 val SCLEX_CAML=65 val SCLEX_BLITZBASIC=66 val SCLEX_PUREBASIC=67 val SCLEX_HASKELL=68 val SCLEX_PHPSCRIPT=69 val SCLEX_TADS3=70 val SCLEX_REBOL=71 val SCLEX_SMALLTALK=72 val SCLEX_FLAGSHIP=73 val SCLEX_CSOUND=74 val SCLEX_FREEBASIC=75 val SCLEX_INNOSETUP=76 val SCLEX_OPAL=77 val SCLEX_SPICE=78 val SCLEX_D=79 val SCLEX_CMAKE=80 val SCLEX_GAP=81 val SCLEX_PLM=82 val SCLEX_PROGRESS=83 val SCLEX_ABAQUS=84 val SCLEX_ASYMPTOTE=85 val SCLEX_R=86 val SCLEX_MAGIK=87 val SCLEX_POWERSHELL=88 val SCLEX_MYSQL=89 val SCLEX_PO=90 val SCLEX_TAL=91 val SCLEX_COBOL=92 val SCLEX_TACL=93 val SCLEX_SORCUS=94 val SCLEX_POWERPRO=95 val SCLEX_NIMROD=96 val SCLEX_SML=97 val SCLEX_MARKDOWN=98 val SCLEX_TXT2TAGS=99 val SCLEX_A68K=100 val SCLEX_MODULA=101 val SCLEX_COFFEESCRIPT=102 val SCLEX_TCMD=103 val SCLEX_AVS=104 val SCLEX_ECL=105 val SCLEX_OSCRIPT=106 val SCLEX_VISUALPROLOG=107 # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a # value assigned in sequence from SCLEX_AUTOMATIC+1. val SCLEX_AUTOMATIC=1000 # Lexical states for SCLEX_PYTHON lex Python=SCLEX_PYTHON SCE_P_ lex Nimrod=SCLEX_NIMROD SCE_P_ val SCE_P_DEFAULT=0 val SCE_P_COMMENTLINE=1 val SCE_P_NUMBER=2 val SCE_P_STRING=3 val SCE_P_CHARACTER=4 val SCE_P_WORD=5 val SCE_P_TRIPLE=6 val SCE_P_TRIPLEDOUBLE=7 val SCE_P_CLASSNAME=8 val SCE_P_DEFNAME=9 val SCE_P_OPERATOR=10 val SCE_P_IDENTIFIER=11 val SCE_P_COMMENTBLOCK=12 val SCE_P_STRINGEOL=13 val SCE_P_WORD2=14 val SCE_P_DECORATOR=15 # Lexical states for SCLEX_CPP lex Cpp=SCLEX_CPP SCE_C_ lex BullAnt=SCLEX_BULLANT SCE_C_ val SCE_C_DEFAULT=0 val SCE_C_COMMENT=1 val SCE_C_COMMENTLINE=2 val SCE_C_COMMENTDOC=3 val SCE_C_NUMBER=4 val SCE_C_WORD=5 val SCE_C_STRING=6 val SCE_C_CHARACTER=7 val SCE_C_UUID=8 val SCE_C_PREPROCESSOR=9 val SCE_C_OPERATOR=10 val SCE_C_IDENTIFIER=11 val SCE_C_STRINGEOL=12 val SCE_C_VERBATIM=13 val SCE_C_REGEX=14 val SCE_C_COMMENTLINEDOC=15 val SCE_C_WORD2=16 val SCE_C_COMMENTDOCKEYWORD=17 val SCE_C_COMMENTDOCKEYWORDERROR=18 val SCE_C_GLOBALCLASS=19 val SCE_C_STRINGRAW=20 val SCE_C_TRIPLEVERBATIM=21 val SCE_C_HASHQUOTEDSTRING=22 val SCE_C_PREPROCESSORCOMMENT=23 # Lexical states for SCLEX_D lex D=SCLEX_D SCE_D_ val SCE_D_DEFAULT=0 val SCE_D_COMMENT=1 val SCE_D_COMMENTLINE=2 val SCE_D_COMMENTDOC=3 val SCE_D_COMMENTNESTED=4 val SCE_D_NUMBER=5 val SCE_D_WORD=6 val SCE_D_WORD2=7 val SCE_D_WORD3=8 val SCE_D_TYPEDEF=9 val SCE_D_STRING=10 val SCE_D_STRINGEOL=11 val SCE_D_CHARACTER=12 val SCE_D_OPERATOR=13 val SCE_D_IDENTIFIER=14 val SCE_D_COMMENTLINEDOC=15 val SCE_D_COMMENTDOCKEYWORD=16 val SCE_D_COMMENTDOCKEYWORDERROR=17 val SCE_D_STRINGB=18 val SCE_D_STRINGR=19 val SCE_D_WORD5=20 val SCE_D_WORD6=21 val SCE_D_WORD7=22 # Lexical states for SCLEX_TCL lex TCL=SCLEX_TCL SCE_TCL_ val SCE_TCL_DEFAULT=0 val SCE_TCL_COMMENT=1 val SCE_TCL_COMMENTLINE=2 val SCE_TCL_NUMBER=3 val SCE_TCL_WORD_IN_QUOTE=4 val SCE_TCL_IN_QUOTE=5 val SCE_TCL_OPERATOR=6 val SCE_TCL_IDENTIFIER=7 val SCE_TCL_SUBSTITUTION=8 val SCE_TCL_SUB_BRACE=9 val SCE_TCL_MODIFIER=10 val SCE_TCL_EXPAND=11 val SCE_TCL_WORD=12 val SCE_TCL_WORD2=13 val SCE_TCL_WORD3=14 val SCE_TCL_WORD4=15 val SCE_TCL_WORD5=16 val SCE_TCL_WORD6=17 val SCE_TCL_WORD7=18 val SCE_TCL_WORD8=19 val SCE_TCL_COMMENT_BOX=20 val SCE_TCL_BLOCK_COMMENT=21 # Lexical states for SCLEX_HTML, SCLEX_XML lex HTML=SCLEX_HTML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_ lex XML=SCLEX_XML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_ lex ASP=SCLEX_ASP SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_ lex PHP=SCLEX_PHP SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_ val SCE_H_DEFAULT=0 val SCE_H_TAG=1 val SCE_H_TAGUNKNOWN=2 val SCE_H_ATTRIBUTE=3 val SCE_H_ATTRIBUTEUNKNOWN=4 val SCE_H_NUMBER=5 val SCE_H_DOUBLESTRING=6 val SCE_H_SINGLESTRING=7 val SCE_H_OTHER=8 val SCE_H_COMMENT=9 val SCE_H_ENTITY=10 # XML and ASP val SCE_H_TAGEND=11 val SCE_H_XMLSTART=12 val SCE_H_XMLEND=13 val SCE_H_SCRIPT=14 val SCE_H_ASP=15 val SCE_H_ASPAT=16 val SCE_H_CDATA=17 val SCE_H_QUESTION=18 # More HTML val SCE_H_VALUE=19 # X-Code val SCE_H_XCCOMMENT=20 # SGML val SCE_H_SGML_DEFAULT=21 val SCE_H_SGML_COMMAND=22 val SCE_H_SGML_1ST_PARAM=23 val SCE_H_SGML_DOUBLESTRING=24 val SCE_H_SGML_SIMPLESTRING=25 val SCE_H_SGML_ERROR=26 val SCE_H_SGML_SPECIAL=27 val SCE_H_SGML_ENTITY=28 val SCE_H_SGML_COMMENT=29 val SCE_H_SGML_1ST_PARAM_COMMENT=30 val SCE_H_SGML_BLOCK_DEFAULT=31 # Embedded Javascript val SCE_HJ_START=40 val SCE_HJ_DEFAULT=41 val SCE_HJ_COMMENT=42 val SCE_HJ_COMMENTLINE=43 val SCE_HJ_COMMENTDOC=44 val SCE_HJ_NUMBER=45 val SCE_HJ_WORD=46 val SCE_HJ_KEYWORD=47 val SCE_HJ_DOUBLESTRING=48 val SCE_HJ_SINGLESTRING=49 val SCE_HJ_SYMBOLS=50 val SCE_HJ_STRINGEOL=51 val SCE_HJ_REGEX=52 # ASP Javascript val SCE_HJA_START=55 val SCE_HJA_DEFAULT=56 val SCE_HJA_COMMENT=57 val SCE_HJA_COMMENTLINE=58 val SCE_HJA_COMMENTDOC=59 val SCE_HJA_NUMBER=60 val SCE_HJA_WORD=61 val SCE_HJA_KEYWORD=62 val SCE_HJA_DOUBLESTRING=63 val SCE_HJA_SINGLESTRING=64 val SCE_HJA_SYMBOLS=65 val SCE_HJA_STRINGEOL=66 val SCE_HJA_REGEX=67 # Embedded VBScript val SCE_HB_START=70 val SCE_HB_DEFAULT=71 val SCE_HB_COMMENTLINE=72 val SCE_HB_NUMBER=73 val SCE_HB_WORD=74 val SCE_HB_STRING=75 val SCE_HB_IDENTIFIER=76 val SCE_HB_STRINGEOL=77 # ASP VBScript val SCE_HBA_START=80 val SCE_HBA_DEFAULT=81 val SCE_HBA_COMMENTLINE=82 val SCE_HBA_NUMBER=83 val SCE_HBA_WORD=84 val SCE_HBA_STRING=85 val SCE_HBA_IDENTIFIER=86 val SCE_HBA_STRINGEOL=87 # Embedded Python val SCE_HP_START=90 val SCE_HP_DEFAULT=91 val SCE_HP_COMMENTLINE=92 val SCE_HP_NUMBER=93 val SCE_HP_STRING=94 val SCE_HP_CHARACTER=95 val SCE_HP_WORD=96 val SCE_HP_TRIPLE=97 val SCE_HP_TRIPLEDOUBLE=98 val SCE_HP_CLASSNAME=99 val SCE_HP_DEFNAME=100 val SCE_HP_OPERATOR=101 val SCE_HP_IDENTIFIER=102 # PHP val SCE_HPHP_COMPLEX_VARIABLE=104 # ASP Python val SCE_HPA_START=105 val SCE_HPA_DEFAULT=106 val SCE_HPA_COMMENTLINE=107 val SCE_HPA_NUMBER=108 val SCE_HPA_STRING=109 val SCE_HPA_CHARACTER=110 val SCE_HPA_WORD=111 val SCE_HPA_TRIPLE=112 val SCE_HPA_TRIPLEDOUBLE=113 val SCE_HPA_CLASSNAME=114 val SCE_HPA_DEFNAME=115 val SCE_HPA_OPERATOR=116 val SCE_HPA_IDENTIFIER=117 # PHP val SCE_HPHP_DEFAULT=118 val SCE_HPHP_HSTRING=119 val SCE_HPHP_SIMPLESTRING=120 val SCE_HPHP_WORD=121 val SCE_HPHP_NUMBER=122 val SCE_HPHP_VARIABLE=123 val SCE_HPHP_COMMENT=124 val SCE_HPHP_COMMENTLINE=125 val SCE_HPHP_HSTRING_VARIABLE=126 val SCE_HPHP_OPERATOR=127 # Lexical states for SCLEX_PERL lex Perl=SCLEX_PERL SCE_PL_ val SCE_PL_DEFAULT=0 val SCE_PL_ERROR=1 val SCE_PL_COMMENTLINE=2 val SCE_PL_POD=3 val SCE_PL_NUMBER=4 val SCE_PL_WORD=5 val SCE_PL_STRING=6 val SCE_PL_CHARACTER=7 val SCE_PL_PUNCTUATION=8 val SCE_PL_PREPROCESSOR=9 val SCE_PL_OPERATOR=10 val SCE_PL_IDENTIFIER=11 val SCE_PL_SCALAR=12 val SCE_PL_ARRAY=13 val SCE_PL_HASH=14 val SCE_PL_SYMBOLTABLE=15 val SCE_PL_VARIABLE_INDEXER=16 val SCE_PL_REGEX=17 val SCE_PL_REGSUBST=18 val SCE_PL_LONGQUOTE=19 val SCE_PL_BACKTICKS=20 val SCE_PL_DATASECTION=21 val SCE_PL_HERE_DELIM=22 val SCE_PL_HERE_Q=23 val SCE_PL_HERE_QQ=24 val SCE_PL_HERE_QX=25 val SCE_PL_STRING_Q=26 val SCE_PL_STRING_QQ=27 val SCE_PL_STRING_QX=28 val SCE_PL_STRING_QR=29 val SCE_PL_STRING_QW=30 val SCE_PL_POD_VERB=31 val SCE_PL_SUB_PROTOTYPE=40 val SCE_PL_FORMAT_IDENT=41 val SCE_PL_FORMAT=42 val SCE_PL_STRING_VAR=43 val SCE_PL_XLAT=44 val SCE_PL_REGEX_VAR=54 val SCE_PL_REGSUBST_VAR=55 val SCE_PL_BACKTICKS_VAR=57 val SCE_PL_HERE_QQ_VAR=61 val SCE_PL_HERE_QX_VAR=62 val SCE_PL_STRING_QQ_VAR=64 val SCE_PL_STRING_QX_VAR=65 val SCE_PL_STRING_QR_VAR=66 # Lexical states for SCLEX_RUBY lex Ruby=SCLEX_RUBY SCE_RB_ val SCE_RB_DEFAULT=0 val SCE_RB_ERROR=1 val SCE_RB_COMMENTLINE=2 val SCE_RB_POD=3 val SCE_RB_NUMBER=4 val SCE_RB_WORD=5 val SCE_RB_STRING=6 val SCE_RB_CHARACTER=7 val SCE_RB_CLASSNAME=8 val SCE_RB_DEFNAME=9 val SCE_RB_OPERATOR=10 val SCE_RB_IDENTIFIER=11 val SCE_RB_REGEX=12 val SCE_RB_GLOBAL=13 val SCE_RB_SYMBOL=14 val SCE_RB_MODULE_NAME=15 val SCE_RB_INSTANCE_VAR=16 val SCE_RB_CLASS_VAR=17 val SCE_RB_BACKTICKS=18 val SCE_RB_DATASECTION=19 val SCE_RB_HERE_DELIM=20 val SCE_RB_HERE_Q=21 val SCE_RB_HERE_QQ=22 val SCE_RB_HERE_QX=23 val SCE_RB_STRING_Q=24 val SCE_RB_STRING_QQ=25 val SCE_RB_STRING_QX=26 val SCE_RB_STRING_QR=27 val SCE_RB_STRING_QW=28 val SCE_RB_WORD_DEMOTED=29 val SCE_RB_STDIN=30 val SCE_RB_STDOUT=31 val SCE_RB_STDERR=40 val SCE_RB_UPPER_BOUND=41 # Lexical states for SCLEX_VB, SCLEX_VBSCRIPT, SCLEX_POWERBASIC lex VB=SCLEX_VB SCE_B_ lex VBScript=SCLEX_VBSCRIPT SCE_B_ lex PowerBasic=SCLEX_POWERBASIC SCE_B_ val SCE_B_DEFAULT=0 val SCE_B_COMMENT=1 val SCE_B_NUMBER=2 val SCE_B_KEYWORD=3 val SCE_B_STRING=4 val SCE_B_PREPROCESSOR=5 val SCE_B_OPERATOR=6 val SCE_B_IDENTIFIER=7 val SCE_B_DATE=8 val SCE_B_STRINGEOL=9 val SCE_B_KEYWORD2=10 val SCE_B_KEYWORD3=11 val SCE_B_KEYWORD4=12 val SCE_B_CONSTANT=13 val SCE_B_ASM=14 val SCE_B_LABEL=15 val SCE_B_ERROR=16 val SCE_B_HEXNUMBER=17 val SCE_B_BINNUMBER=18 # Lexical states for SCLEX_PROPERTIES lex Properties=SCLEX_PROPERTIES SCE_PROPS_ val SCE_PROPS_DEFAULT=0 val SCE_PROPS_COMMENT=1 val SCE_PROPS_SECTION=2 val SCE_PROPS_ASSIGNMENT=3 val SCE_PROPS_DEFVAL=4 val SCE_PROPS_KEY=5 # Lexical states for SCLEX_LATEX lex LaTeX=SCLEX_LATEX SCE_L_ val SCE_L_DEFAULT=0 val SCE_L_COMMAND=1 val SCE_L_TAG=2 val SCE_L_MATH=3 val SCE_L_COMMENT=4 val SCE_L_TAG2=5 val SCE_L_MATH2=6 val SCE_L_COMMENT2=7 val SCE_L_VERBATIM=8 val SCE_L_SHORTCMD=9 val SCE_L_SPECIAL=10 val SCE_L_CMDOPT=11 val SCE_L_ERROR=12 # Lexical states for SCLEX_LUA lex Lua=SCLEX_LUA SCE_LUA_ val SCE_LUA_DEFAULT=0 val SCE_LUA_COMMENT=1 val SCE_LUA_COMMENTLINE=2 val SCE_LUA_COMMENTDOC=3 val SCE_LUA_NUMBER=4 val SCE_LUA_WORD=5 val SCE_LUA_STRING=6 val SCE_LUA_CHARACTER=7 val SCE_LUA_LITERALSTRING=8 val SCE_LUA_PREPROCESSOR=9 val SCE_LUA_OPERATOR=10 val SCE_LUA_IDENTIFIER=11 val SCE_LUA_STRINGEOL=12 val SCE_LUA_WORD2=13 val SCE_LUA_WORD3=14 val SCE_LUA_WORD4=15 val SCE_LUA_WORD5=16 val SCE_LUA_WORD6=17 val SCE_LUA_WORD7=18 val SCE_LUA_WORD8=19 val SCE_LUA_LABEL=20 # Lexical states for SCLEX_ERRORLIST lex ErrorList=SCLEX_ERRORLIST SCE_ERR_ val SCE_ERR_DEFAULT=0 val SCE_ERR_PYTHON=1 val SCE_ERR_GCC=2 val SCE_ERR_MS=3 val SCE_ERR_CMD=4 val SCE_ERR_BORLAND=5 val SCE_ERR_PERL=6 val SCE_ERR_NET=7 val SCE_ERR_LUA=8 val SCE_ERR_CTAG=9 val SCE_ERR_DIFF_CHANGED=10 val SCE_ERR_DIFF_ADDITION=11 val SCE_ERR_DIFF_DELETION=12 val SCE_ERR_DIFF_MESSAGE=13 val SCE_ERR_PHP=14 val SCE_ERR_ELF=15 val SCE_ERR_IFC=16 val SCE_ERR_IFORT=17 val SCE_ERR_ABSF=18 val SCE_ERR_TIDY=19 val SCE_ERR_JAVA_STACK=20 val SCE_ERR_VALUE=21 val SCE_ERR_GCC_INCLUDED_FROM=22 # Lexical states for SCLEX_BATCH lex Batch=SCLEX_BATCH SCE_BAT_ val SCE_BAT_DEFAULT=0 val SCE_BAT_COMMENT=1 val SCE_BAT_WORD=2 val SCE_BAT_LABEL=3 val SCE_BAT_HIDE=4 val SCE_BAT_COMMAND=5 val SCE_BAT_IDENTIFIER=6 val SCE_BAT_OPERATOR=7 # Lexical states for SCLEX_TCMD lex TCMD=SCLEX_TCMD SCE_TCMD_ val SCE_TCMD_DEFAULT=0 val SCE_TCMD_COMMENT=1 val SCE_TCMD_WORD=2 val SCE_TCMD_LABEL=3 val SCE_TCMD_HIDE=4 val SCE_TCMD_COMMAND=5 val SCE_TCMD_IDENTIFIER=6 val SCE_TCMD_OPERATOR=7 val SCE_TCMD_ENVIRONMENT=8 val SCE_TCMD_EXPANSION=9 val SCE_TCMD_CLABEL=10 # Lexical states for SCLEX_MAKEFILE lex MakeFile=SCLEX_MAKEFILE SCE_MAKE_ val SCE_MAKE_DEFAULT=0 val SCE_MAKE_COMMENT=1 val SCE_MAKE_PREPROCESSOR=2 val SCE_MAKE_IDENTIFIER=3 val SCE_MAKE_OPERATOR=4 val SCE_MAKE_TARGET=5 val SCE_MAKE_IDEOL=9 # Lexical states for SCLEX_DIFF lex Diff=SCLEX_DIFF SCE_DIFF_ val SCE_DIFF_DEFAULT=0 val SCE_DIFF_COMMENT=1 val SCE_DIFF_COMMAND=2 val SCE_DIFF_HEADER=3 val SCE_DIFF_POSITION=4 val SCE_DIFF_DELETED=5 val SCE_DIFF_ADDED=6 val SCE_DIFF_CHANGED=7 # Lexical states for SCLEX_CONF (Apache Configuration Files Lexer) lex Conf=SCLEX_CONF SCE_CONF_ val SCE_CONF_DEFAULT=0 val SCE_CONF_COMMENT=1 val SCE_CONF_NUMBER=2 val SCE_CONF_IDENTIFIER=3 val SCE_CONF_EXTENSION=4 val SCE_CONF_PARAMETER=5 val SCE_CONF_STRING=6 val SCE_CONF_OPERATOR=7 val SCE_CONF_IP=8 val SCE_CONF_DIRECTIVE=9 # Lexical states for SCLEX_AVE, Avenue lex Avenue=SCLEX_AVE SCE_AVE_ val SCE_AVE_DEFAULT=0 val SCE_AVE_COMMENT=1 val SCE_AVE_NUMBER=2 val SCE_AVE_WORD=3 val SCE_AVE_STRING=6 val SCE_AVE_ENUM=7 val SCE_AVE_STRINGEOL=8 val SCE_AVE_IDENTIFIER=9 val SCE_AVE_OPERATOR=10 val SCE_AVE_WORD1=11 val SCE_AVE_WORD2=12 val SCE_AVE_WORD3=13 val SCE_AVE_WORD4=14 val SCE_AVE_WORD5=15 val SCE_AVE_WORD6=16 # Lexical states for SCLEX_ADA lex Ada=SCLEX_ADA SCE_ADA_ val SCE_ADA_DEFAULT=0 val SCE_ADA_WORD=1 val SCE_ADA_IDENTIFIER=2 val SCE_ADA_NUMBER=3 val SCE_ADA_DELIMITER=4 val SCE_ADA_CHARACTER=5 val SCE_ADA_CHARACTEREOL=6 val SCE_ADA_STRING=7 val SCE_ADA_STRINGEOL=8 val SCE_ADA_LABEL=9 val SCE_ADA_COMMENTLINE=10 val SCE_ADA_ILLEGAL=11 # Lexical states for SCLEX_BAAN lex Baan=SCLEX_BAAN SCE_BAAN_ val SCE_BAAN_DEFAULT=0 val SCE_BAAN_COMMENT=1 val SCE_BAAN_COMMENTDOC=2 val SCE_BAAN_NUMBER=3 val SCE_BAAN_WORD=4 val SCE_BAAN_STRING=5 val SCE_BAAN_PREPROCESSOR=6 val SCE_BAAN_OPERATOR=7 val SCE_BAAN_IDENTIFIER=8 val SCE_BAAN_STRINGEOL=9 val SCE_BAAN_WORD2=10 # Lexical states for SCLEX_LISP lex Lisp=SCLEX_LISP SCE_LISP_ val SCE_LISP_DEFAULT=0 val SCE_LISP_COMMENT=1 val SCE_LISP_NUMBER=2 val SCE_LISP_KEYWORD=3 val SCE_LISP_KEYWORD_KW=4 val SCE_LISP_SYMBOL=5 val SCE_LISP_STRING=6 val SCE_LISP_STRINGEOL=8 val SCE_LISP_IDENTIFIER=9 val SCE_LISP_OPERATOR=10 val SCE_LISP_SPECIAL=11 val SCE_LISP_MULTI_COMMENT=12 # Lexical states for SCLEX_EIFFEL and SCLEX_EIFFELKW lex Eiffel=SCLEX_EIFFEL SCE_EIFFEL_ lex EiffelKW=SCLEX_EIFFELKW SCE_EIFFEL_ val SCE_EIFFEL_DEFAULT=0 val SCE_EIFFEL_COMMENTLINE=1 val SCE_EIFFEL_NUMBER=2 val SCE_EIFFEL_WORD=3 val SCE_EIFFEL_STRING=4 val SCE_EIFFEL_CHARACTER=5 val SCE_EIFFEL_OPERATOR=6 val SCE_EIFFEL_IDENTIFIER=7 val SCE_EIFFEL_STRINGEOL=8 # Lexical states for SCLEX_NNCRONTAB (nnCron crontab Lexer) lex NNCronTab=SCLEX_NNCRONTAB SCE_NNCRONTAB_ val SCE_NNCRONTAB_DEFAULT=0 val SCE_NNCRONTAB_COMMENT=1 val SCE_NNCRONTAB_TASK=2 val SCE_NNCRONTAB_SECTION=3 val SCE_NNCRONTAB_KEYWORD=4 val SCE_NNCRONTAB_MODIFIER=5 val SCE_NNCRONTAB_ASTERISK=6 val SCE_NNCRONTAB_NUMBER=7 val SCE_NNCRONTAB_STRING=8 val SCE_NNCRONTAB_ENVIRONMENT=9 val SCE_NNCRONTAB_IDENTIFIER=10 # Lexical states for SCLEX_FORTH (Forth Lexer) lex Forth=SCLEX_FORTH SCE_FORTH_ val SCE_FORTH_DEFAULT=0 val SCE_FORTH_COMMENT=1 val SCE_FORTH_COMMENT_ML=2 val SCE_FORTH_IDENTIFIER=3 val SCE_FORTH_CONTROL=4 val SCE_FORTH_KEYWORD=5 val SCE_FORTH_DEFWORD=6 val SCE_FORTH_PREWORD1=7 val SCE_FORTH_PREWORD2=8 val SCE_FORTH_NUMBER=9 val SCE_FORTH_STRING=10 val SCE_FORTH_LOCALE=11 # Lexical states for SCLEX_MATLAB lex MatLab=SCLEX_MATLAB SCE_MATLAB_ val SCE_MATLAB_DEFAULT=0 val SCE_MATLAB_COMMENT=1 val SCE_MATLAB_COMMAND=2 val SCE_MATLAB_NUMBER=3 val SCE_MATLAB_KEYWORD=4 # single quoted string val SCE_MATLAB_STRING=5 val SCE_MATLAB_OPERATOR=6 val SCE_MATLAB_IDENTIFIER=7 val SCE_MATLAB_DOUBLEQUOTESTRING=8 # Lexical states for SCLEX_SCRIPTOL lex Sol=SCLEX_SCRIPTOL SCE_SCRIPTOL_ val SCE_SCRIPTOL_DEFAULT=0 val SCE_SCRIPTOL_WHITE=1 val SCE_SCRIPTOL_COMMENTLINE=2 val SCE_SCRIPTOL_PERSISTENT=3 val SCE_SCRIPTOL_CSTYLE=4 val SCE_SCRIPTOL_COMMENTBLOCK=5 val SCE_SCRIPTOL_NUMBER=6 val SCE_SCRIPTOL_STRING=7 val SCE_SCRIPTOL_CHARACTER=8 val SCE_SCRIPTOL_STRINGEOL=9 val SCE_SCRIPTOL_KEYWORD=10 val SCE_SCRIPTOL_OPERATOR=11 val SCE_SCRIPTOL_IDENTIFIER=12 val SCE_SCRIPTOL_TRIPLE=13 val SCE_SCRIPTOL_CLASSNAME=14 val SCE_SCRIPTOL_PREPROCESSOR=15 # Lexical states for SCLEX_ASM lex Asm=SCLEX_ASM SCE_ASM_ val SCE_ASM_DEFAULT=0 val SCE_ASM_COMMENT=1 val SCE_ASM_NUMBER=2 val SCE_ASM_STRING=3 val SCE_ASM_OPERATOR=4 val SCE_ASM_IDENTIFIER=5 val SCE_ASM_CPUINSTRUCTION=6 val SCE_ASM_MATHINSTRUCTION=7 val SCE_ASM_REGISTER=8 val SCE_ASM_DIRECTIVE=9 val SCE_ASM_DIRECTIVEOPERAND=10 val SCE_ASM_COMMENTBLOCK=11 val SCE_ASM_CHARACTER=12 val SCE_ASM_STRINGEOL=13 val SCE_ASM_EXTINSTRUCTION=14 val SCE_ASM_COMMENTDIRECTIVE=15 # Lexical states for SCLEX_FORTRAN lex Fortran=SCLEX_FORTRAN SCE_F_ lex F77=SCLEX_F77 SCE_F_ val SCE_F_DEFAULT=0 val SCE_F_COMMENT=1 val SCE_F_NUMBER=2 val SCE_F_STRING1=3 val SCE_F_STRING2=4 val SCE_F_STRINGEOL=5 val SCE_F_OPERATOR=6 val SCE_F_IDENTIFIER=7 val SCE_F_WORD=8 val SCE_F_WORD2=9 val SCE_F_WORD3=10 val SCE_F_PREPROCESSOR=11 val SCE_F_OPERATOR2=12 val SCE_F_LABEL=13 val SCE_F_CONTINUATION=14 # Lexical states for SCLEX_CSS lex CSS=SCLEX_CSS SCE_CSS_ val SCE_CSS_DEFAULT=0 val SCE_CSS_TAG=1 val SCE_CSS_CLASS=2 val SCE_CSS_PSEUDOCLASS=3 val SCE_CSS_UNKNOWN_PSEUDOCLASS=4 val SCE_CSS_OPERATOR=5 val SCE_CSS_IDENTIFIER=6 val SCE_CSS_UNKNOWN_IDENTIFIER=7 val SCE_CSS_VALUE=8 val SCE_CSS_COMMENT=9 val SCE_CSS_ID=10 val SCE_CSS_IMPORTANT=11 val SCE_CSS_DIRECTIVE=12 val SCE_CSS_DOUBLESTRING=13 val SCE_CSS_SINGLESTRING=14 val SCE_CSS_IDENTIFIER2=15 val SCE_CSS_ATTRIBUTE=16 val SCE_CSS_IDENTIFIER3=17 val SCE_CSS_PSEUDOELEMENT=18 val SCE_CSS_EXTENDED_IDENTIFIER=19 val SCE_CSS_EXTENDED_PSEUDOCLASS=20 val SCE_CSS_EXTENDED_PSEUDOELEMENT=21 val SCE_CSS_MEDIA=22 val SCE_CSS_VARIABLE=23 # Lexical states for SCLEX_POV lex POV=SCLEX_POV SCE_POV_ val SCE_POV_DEFAULT=0 val SCE_POV_COMMENT=1 val SCE_POV_COMMENTLINE=2 val SCE_POV_NUMBER=3 val SCE_POV_OPERATOR=4 val SCE_POV_IDENTIFIER=5 val SCE_POV_STRING=6 val SCE_POV_STRINGEOL=7 val SCE_POV_DIRECTIVE=8 val SCE_POV_BADDIRECTIVE=9 val SCE_POV_WORD2=10 val SCE_POV_WORD3=11 val SCE_POV_WORD4=12 val SCE_POV_WORD5=13 val SCE_POV_WORD6=14 val SCE_POV_WORD7=15 val SCE_POV_WORD8=16 # Lexical states for SCLEX_LOUT lex LOUT=SCLEX_LOUT SCE_LOUT_ val SCE_LOUT_DEFAULT=0 val SCE_LOUT_COMMENT=1 val SCE_LOUT_NUMBER=2 val SCE_LOUT_WORD=3 val SCE_LOUT_WORD2=4 val SCE_LOUT_WORD3=5 val SCE_LOUT_WORD4=6 val SCE_LOUT_STRING=7 val SCE_LOUT_OPERATOR=8 val SCE_LOUT_IDENTIFIER=9 val SCE_LOUT_STRINGEOL=10 # Lexical states for SCLEX_ESCRIPT lex ESCRIPT=SCLEX_ESCRIPT SCE_ESCRIPT_ val SCE_ESCRIPT_DEFAULT=0 val SCE_ESCRIPT_COMMENT=1 val SCE_ESCRIPT_COMMENTLINE=2 val SCE_ESCRIPT_COMMENTDOC=3 val SCE_ESCRIPT_NUMBER=4 val SCE_ESCRIPT_WORD=5 val SCE_ESCRIPT_STRING=6 val SCE_ESCRIPT_OPERATOR=7 val SCE_ESCRIPT_IDENTIFIER=8 val SCE_ESCRIPT_BRACE=9 val SCE_ESCRIPT_WORD2=10 val SCE_ESCRIPT_WORD3=11 # Lexical states for SCLEX_PS lex PS=SCLEX_PS SCE_PS_ val SCE_PS_DEFAULT=0 val SCE_PS_COMMENT=1 val SCE_PS_DSC_COMMENT=2 val SCE_PS_DSC_VALUE=3 val SCE_PS_NUMBER=4 val SCE_PS_NAME=5 val SCE_PS_KEYWORD=6 val SCE_PS_LITERAL=7 val SCE_PS_IMMEVAL=8 val SCE_PS_PAREN_ARRAY=9 val SCE_PS_PAREN_DICT=10 val SCE_PS_PAREN_PROC=11 val SCE_PS_TEXT=12 val SCE_PS_HEXSTRING=13 val SCE_PS_BASE85STRING=14 val SCE_PS_BADSTRINGCHAR=15 # Lexical states for SCLEX_NSIS lex NSIS=SCLEX_NSIS SCE_NSIS_ val SCE_NSIS_DEFAULT=0 val SCE_NSIS_COMMENT=1 val SCE_NSIS_STRINGDQ=2 val SCE_NSIS_STRINGLQ=3 val SCE_NSIS_STRINGRQ=4 val SCE_NSIS_FUNCTION=5 val SCE_NSIS_VARIABLE=6 val SCE_NSIS_LABEL=7 val SCE_NSIS_USERDEFINED=8 val SCE_NSIS_SECTIONDEF=9 val SCE_NSIS_SUBSECTIONDEF=10 val SCE_NSIS_IFDEFINEDEF=11 val SCE_NSIS_MACRODEF=12 val SCE_NSIS_STRINGVAR=13 val SCE_NSIS_NUMBER=14 val SCE_NSIS_SECTIONGROUP=15 val SCE_NSIS_PAGEEX=16 val SCE_NSIS_FUNCTIONDEF=17 val SCE_NSIS_COMMENTBOX=18 # Lexical states for SCLEX_MMIXAL lex MMIXAL=SCLEX_MMIXAL SCE_MMIXAL_ val SCE_MMIXAL_LEADWS=0 val SCE_MMIXAL_COMMENT=1 val SCE_MMIXAL_LABEL=2 val SCE_MMIXAL_OPCODE=3 val SCE_MMIXAL_OPCODE_PRE=4 val SCE_MMIXAL_OPCODE_VALID=5 val SCE_MMIXAL_OPCODE_UNKNOWN=6 val SCE_MMIXAL_OPCODE_POST=7 val SCE_MMIXAL_OPERANDS=8 val SCE_MMIXAL_NUMBER=9 val SCE_MMIXAL_REF=10 val SCE_MMIXAL_CHAR=11 val SCE_MMIXAL_STRING=12 val SCE_MMIXAL_REGISTER=13 val SCE_MMIXAL_HEX=14 val SCE_MMIXAL_OPERATOR=15 val SCE_MMIXAL_SYMBOL=16 val SCE_MMIXAL_INCLUDE=17 # Lexical states for SCLEX_CLW lex Clarion=SCLEX_CLW SCE_CLW_ val SCE_CLW_DEFAULT=0 val SCE_CLW_LABEL=1 val SCE_CLW_COMMENT=2 val SCE_CLW_STRING=3 val SCE_CLW_USER_IDENTIFIER=4 val SCE_CLW_INTEGER_CONSTANT=5 val SCE_CLW_REAL_CONSTANT=6 val SCE_CLW_PICTURE_STRING=7 val SCE_CLW_KEYWORD=8 val SCE_CLW_COMPILER_DIRECTIVE=9 val SCE_CLW_RUNTIME_EXPRESSIONS=10 val SCE_CLW_BUILTIN_PROCEDURES_FUNCTION=11 val SCE_CLW_STRUCTURE_DATA_TYPE=12 val SCE_CLW_ATTRIBUTE=13 val SCE_CLW_STANDARD_EQUATE=14 val SCE_CLW_ERROR=15 val SCE_CLW_DEPRECATED=16 # Lexical states for SCLEX_LOT lex LOT=SCLEX_LOT SCE_LOT_ val SCE_LOT_DEFAULT=0 val SCE_LOT_HEADER=1 val SCE_LOT_BREAK=2 val SCE_LOT_SET=3 val SCE_LOT_PASS=4 val SCE_LOT_FAIL=5 val SCE_LOT_ABORT=6 # Lexical states for SCLEX_YAML lex YAML=SCLEX_YAML SCE_YAML_ val SCE_YAML_DEFAULT=0 val SCE_YAML_COMMENT=1 val SCE_YAML_IDENTIFIER=2 val SCE_YAML_KEYWORD=3 val SCE_YAML_NUMBER=4 val SCE_YAML_REFERENCE=5 val SCE_YAML_DOCUMENT=6 val SCE_YAML_TEXT=7 val SCE_YAML_ERROR=8 val SCE_YAML_OPERATOR=9 # Lexical states for SCLEX_TEX lex TeX=SCLEX_TEX SCE_TEX_ val SCE_TEX_DEFAULT=0 val SCE_TEX_SPECIAL=1 val SCE_TEX_GROUP=2 val SCE_TEX_SYMBOL=3 val SCE_TEX_COMMAND=4 val SCE_TEX_TEXT=5 lex Metapost=SCLEX_METAPOST SCE_METAPOST_ val SCE_METAPOST_DEFAULT=0 val SCE_METAPOST_SPECIAL=1 val SCE_METAPOST_GROUP=2 val SCE_METAPOST_SYMBOL=3 val SCE_METAPOST_COMMAND=4 val SCE_METAPOST_TEXT=5 val SCE_METAPOST_EXTRA=6 # Lexical states for SCLEX_ERLANG lex Erlang=SCLEX_ERLANG SCE_ERLANG_ val SCE_ERLANG_DEFAULT=0 val SCE_ERLANG_COMMENT=1 val SCE_ERLANG_VARIABLE=2 val SCE_ERLANG_NUMBER=3 val SCE_ERLANG_KEYWORD=4 val SCE_ERLANG_STRING=5 val SCE_ERLANG_OPERATOR=6 val SCE_ERLANG_ATOM=7 val SCE_ERLANG_FUNCTION_NAME=8 val SCE_ERLANG_CHARACTER=9 val SCE_ERLANG_MACRO=10 val SCE_ERLANG_RECORD=11 val SCE_ERLANG_PREPROC=12 val SCE_ERLANG_NODE_NAME=13 val SCE_ERLANG_COMMENT_FUNCTION=14 val SCE_ERLANG_COMMENT_MODULE=15 val SCE_ERLANG_COMMENT_DOC=16 val SCE_ERLANG_COMMENT_DOC_MACRO=17 val SCE_ERLANG_ATOM_QUOTED=18 val SCE_ERLANG_MACRO_QUOTED=19 val SCE_ERLANG_RECORD_QUOTED=20 val SCE_ERLANG_NODE_NAME_QUOTED=21 val SCE_ERLANG_BIFS=22 val SCE_ERLANG_MODULES=23 val SCE_ERLANG_MODULES_ATT=24 val SCE_ERLANG_UNKNOWN=31 # Lexical states for SCLEX_OCTAVE are identical to MatLab lex Octave=SCLEX_OCTAVE SCE_MATLAB_ # Lexical states for SCLEX_MSSQL lex MSSQL=SCLEX_MSSQL SCE_MSSQL_ val SCE_MSSQL_DEFAULT=0 val SCE_MSSQL_COMMENT=1 val SCE_MSSQL_LINE_COMMENT=2 val SCE_MSSQL_NUMBER=3 val SCE_MSSQL_STRING=4 val SCE_MSSQL_OPERATOR=5 val SCE_MSSQL_IDENTIFIER=6 val SCE_MSSQL_VARIABLE=7 val SCE_MSSQL_COLUMN_NAME=8 val SCE_MSSQL_STATEMENT=9 val SCE_MSSQL_DATATYPE=10 val SCE_MSSQL_SYSTABLE=11 val SCE_MSSQL_GLOBAL_VARIABLE=12 val SCE_MSSQL_FUNCTION=13 val SCE_MSSQL_STORED_PROCEDURE=14 val SCE_MSSQL_DEFAULT_PREF_DATATYPE=15 val SCE_MSSQL_COLUMN_NAME_2=16 # Lexical states for SCLEX_VERILOG lex Verilog=SCLEX_VERILOG SCE_V_ val SCE_V_DEFAULT=0 val SCE_V_COMMENT=1 val SCE_V_COMMENTLINE=2 val SCE_V_COMMENTLINEBANG=3 val SCE_V_NUMBER=4 val SCE_V_WORD=5 val SCE_V_STRING=6 val SCE_V_WORD2=7 val SCE_V_WORD3=8 val SCE_V_PREPROCESSOR=9 val SCE_V_OPERATOR=10 val SCE_V_IDENTIFIER=11 val SCE_V_STRINGEOL=12 val SCE_V_USER=19 # Lexical states for SCLEX_KIX lex Kix=SCLEX_KIX SCE_KIX_ val SCE_KIX_DEFAULT=0 val SCE_KIX_COMMENT=1 val SCE_KIX_STRING1=2 val SCE_KIX_STRING2=3 val SCE_KIX_NUMBER=4 val SCE_KIX_VAR=5 val SCE_KIX_MACRO=6 val SCE_KIX_KEYWORD=7 val SCE_KIX_FUNCTIONS=8 val SCE_KIX_OPERATOR=9 val SCE_KIX_IDENTIFIER=31 # Lexical states for SCLEX_GUI4CLI lex Gui4Cli=SCLEX_GUI4CLI SCE_GC_ val SCE_GC_DEFAULT=0 val SCE_GC_COMMENTLINE=1 val SCE_GC_COMMENTBLOCK=2 val SCE_GC_GLOBAL=3 val SCE_GC_EVENT=4 val SCE_GC_ATTRIBUTE=5 val SCE_GC_CONTROL=6 val SCE_GC_COMMAND=7 val SCE_GC_STRING=8 val SCE_GC_OPERATOR=9 # Lexical states for SCLEX_SPECMAN lex Specman=SCLEX_SPECMAN SCE_SN_ val SCE_SN_DEFAULT=0 val SCE_SN_CODE=1 val SCE_SN_COMMENTLINE=2 val SCE_SN_COMMENTLINEBANG=3 val SCE_SN_NUMBER=4 val SCE_SN_WORD=5 val SCE_SN_STRING=6 val SCE_SN_WORD2=7 val SCE_SN_WORD3=8 val SCE_SN_PREPROCESSOR=9 val SCE_SN_OPERATOR=10 val SCE_SN_IDENTIFIER=11 val SCE_SN_STRINGEOL=12 val SCE_SN_REGEXTAG=13 val SCE_SN_SIGNAL=14 val SCE_SN_USER=19 # Lexical states for SCLEX_AU3 lex Au3=SCLEX_AU3 SCE_AU3_ val SCE_AU3_DEFAULT=0 val SCE_AU3_COMMENT=1 val SCE_AU3_COMMENTBLOCK=2 val SCE_AU3_NUMBER=3 val SCE_AU3_FUNCTION=4 val SCE_AU3_KEYWORD=5 val SCE_AU3_MACRO=6 val SCE_AU3_STRING=7 val SCE_AU3_OPERATOR=8 val SCE_AU3_VARIABLE=9 val SCE_AU3_SENT=10 val SCE_AU3_PREPROCESSOR=11 val SCE_AU3_SPECIAL=12 val SCE_AU3_EXPAND=13 val SCE_AU3_COMOBJ=14 val SCE_AU3_UDF=15 # Lexical states for SCLEX_APDL lex APDL=SCLEX_APDL SCE_APDL_ val SCE_APDL_DEFAULT=0 val SCE_APDL_COMMENT=1 val SCE_APDL_COMMENTBLOCK=2 val SCE_APDL_NUMBER=3 val SCE_APDL_STRING=4 val SCE_APDL_OPERATOR=5 val SCE_APDL_WORD=6 val SCE_APDL_PROCESSOR=7 val SCE_APDL_COMMAND=8 val SCE_APDL_SLASHCOMMAND=9 val SCE_APDL_STARCOMMAND=10 val SCE_APDL_ARGUMENT=11 val SCE_APDL_FUNCTION=12 # Lexical states for SCLEX_BASH lex Bash=SCLEX_BASH SCE_SH_ val SCE_SH_DEFAULT=0 val SCE_SH_ERROR=1 val SCE_SH_COMMENTLINE=2 val SCE_SH_NUMBER=3 val SCE_SH_WORD=4 val SCE_SH_STRING=5 val SCE_SH_CHARACTER=6 val SCE_SH_OPERATOR=7 val SCE_SH_IDENTIFIER=8 val SCE_SH_SCALAR=9 val SCE_SH_PARAM=10 val SCE_SH_BACKTICKS=11 val SCE_SH_HERE_DELIM=12 val SCE_SH_HERE_Q=13 # Lexical states for SCLEX_ASN1 lex Asn1=SCLEX_ASN1 SCE_ASN1_ val SCE_ASN1_DEFAULT=0 val SCE_ASN1_COMMENT=1 val SCE_ASN1_IDENTIFIER=2 val SCE_ASN1_STRING=3 val SCE_ASN1_OID=4 val SCE_ASN1_SCALAR=5 val SCE_ASN1_KEYWORD=6 val SCE_ASN1_ATTRIBUTE=7 val SCE_ASN1_DESCRIPTOR=8 val SCE_ASN1_TYPE=9 val SCE_ASN1_OPERATOR=10 # Lexical states for SCLEX_VHDL lex VHDL=SCLEX_VHDL SCE_VHDL_ val SCE_VHDL_DEFAULT=0 val SCE_VHDL_COMMENT=1 val SCE_VHDL_COMMENTLINEBANG=2 val SCE_VHDL_NUMBER=3 val SCE_VHDL_STRING=4 val SCE_VHDL_OPERATOR=5 val SCE_VHDL_IDENTIFIER=6 val SCE_VHDL_STRINGEOL=7 val SCE_VHDL_KEYWORD=8 val SCE_VHDL_STDOPERATOR=9 val SCE_VHDL_ATTRIBUTE=10 val SCE_VHDL_STDFUNCTION=11 val SCE_VHDL_STDPACKAGE=12 val SCE_VHDL_STDTYPE=13 val SCE_VHDL_USERWORD=14 # Lexical states for SCLEX_CAML lex Caml=SCLEX_CAML SCE_CAML_ val SCE_CAML_DEFAULT=0 val SCE_CAML_IDENTIFIER=1 val SCE_CAML_TAGNAME=2 val SCE_CAML_KEYWORD=3 val SCE_CAML_KEYWORD2=4 val SCE_CAML_KEYWORD3=5 val SCE_CAML_LINENUM=6 val SCE_CAML_OPERATOR=7 val SCE_CAML_NUMBER=8 val SCE_CAML_CHAR=9 val SCE_CAML_WHITE=10 val SCE_CAML_STRING=11 val SCE_CAML_COMMENT=12 val SCE_CAML_COMMENT1=13 val SCE_CAML_COMMENT2=14 val SCE_CAML_COMMENT3=15 # Lexical states for SCLEX_HASKELL lex Haskell=SCLEX_HASKELL SCE_HA_ val SCE_HA_DEFAULT=0 val SCE_HA_IDENTIFIER=1 val SCE_HA_KEYWORD=2 val SCE_HA_NUMBER=3 val SCE_HA_STRING=4 val SCE_HA_CHARACTER=5 val SCE_HA_CLASS=6 val SCE_HA_MODULE=7 val SCE_HA_CAPITAL=8 val SCE_HA_DATA=9 val SCE_HA_IMPORT=10 val SCE_HA_OPERATOR=11 val SCE_HA_INSTANCE=12 val SCE_HA_COMMENTLINE=13 val SCE_HA_COMMENTBLOCK=14 val SCE_HA_COMMENTBLOCK2=15 val SCE_HA_COMMENTBLOCK3=16 # Lexical states of SCLEX_TADS3 lex TADS3=SCLEX_TADS3 SCE_T3_ val SCE_T3_DEFAULT=0 val SCE_T3_X_DEFAULT=1 val SCE_T3_PREPROCESSOR=2 val SCE_T3_BLOCK_COMMENT=3 val SCE_T3_LINE_COMMENT=4 val SCE_T3_OPERATOR=5 val SCE_T3_KEYWORD=6 val SCE_T3_NUMBER=7 val SCE_T3_IDENTIFIER=8 val SCE_T3_S_STRING=9 val SCE_T3_D_STRING=10 val SCE_T3_X_STRING=11 val SCE_T3_LIB_DIRECTIVE=12 val SCE_T3_MSG_PARAM=13 val SCE_T3_HTML_TAG=14 val SCE_T3_HTML_DEFAULT=15 val SCE_T3_HTML_STRING=16 val SCE_T3_USER1=17 val SCE_T3_USER2=18 val SCE_T3_USER3=19 val SCE_T3_BRACE=20 # Lexical states for SCLEX_REBOL lex Rebol=SCLEX_REBOL SCE_REBOL_ val SCE_REBOL_DEFAULT=0 val SCE_REBOL_COMMENTLINE=1 val SCE_REBOL_COMMENTBLOCK=2 val SCE_REBOL_PREFACE=3 val SCE_REBOL_OPERATOR=4 val SCE_REBOL_CHARACTER=5 val SCE_REBOL_QUOTEDSTRING=6 val SCE_REBOL_BRACEDSTRING=7 val SCE_REBOL_NUMBER=8 val SCE_REBOL_PAIR=9 val SCE_REBOL_TUPLE=10 val SCE_REBOL_BINARY=11 val SCE_REBOL_MONEY=12 val SCE_REBOL_ISSUE=13 val SCE_REBOL_TAG=14 val SCE_REBOL_FILE=15 val SCE_REBOL_EMAIL=16 val SCE_REBOL_URL=17 val SCE_REBOL_DATE=18 val SCE_REBOL_TIME=19 val SCE_REBOL_IDENTIFIER=20 val SCE_REBOL_WORD=21 val SCE_REBOL_WORD2=22 val SCE_REBOL_WORD3=23 val SCE_REBOL_WORD4=24 val SCE_REBOL_WORD5=25 val SCE_REBOL_WORD6=26 val SCE_REBOL_WORD7=27 val SCE_REBOL_WORD8=28 # Lexical states for SCLEX_SQL lex SQL=SCLEX_SQL SCE_SQL_ val SCE_SQL_DEFAULT=0 val SCE_SQL_COMMENT=1 val SCE_SQL_COMMENTLINE=2 val SCE_SQL_COMMENTDOC=3 val SCE_SQL_NUMBER=4 val SCE_SQL_WORD=5 val SCE_SQL_STRING=6 val SCE_SQL_CHARACTER=7 val SCE_SQL_SQLPLUS=8 val SCE_SQL_SQLPLUS_PROMPT=9 val SCE_SQL_OPERATOR=10 val SCE_SQL_IDENTIFIER=11 val SCE_SQL_SQLPLUS_COMMENT=13 val SCE_SQL_COMMENTLINEDOC=15 val SCE_SQL_WORD2=16 val SCE_SQL_COMMENTDOCKEYWORD=17 val SCE_SQL_COMMENTDOCKEYWORDERROR=18 val SCE_SQL_USER1=19 val SCE_SQL_USER2=20 val SCE_SQL_USER3=21 val SCE_SQL_USER4=22 val SCE_SQL_QUOTEDIDENTIFIER=23 # Lexical states for SCLEX_SMALLTALK lex Smalltalk=SCLEX_SMALLTALK SCE_ST_ val SCE_ST_DEFAULT=0 val SCE_ST_STRING=1 val SCE_ST_NUMBER=2 val SCE_ST_COMMENT=3 val SCE_ST_SYMBOL=4 val SCE_ST_BINARY=5 val SCE_ST_BOOL=6 val SCE_ST_SELF=7 val SCE_ST_SUPER=8 val SCE_ST_NIL=9 val SCE_ST_GLOBAL=10 val SCE_ST_RETURN=11 val SCE_ST_SPECIAL=12 val SCE_ST_KWSEND=13 val SCE_ST_ASSIGN=14 val SCE_ST_CHARACTER=15 val SCE_ST_SPEC_SEL=16 # Lexical states for SCLEX_FLAGSHIP (clipper) lex FlagShip=SCLEX_FLAGSHIP SCE_FS_ val SCE_FS_DEFAULT=0 val SCE_FS_COMMENT=1 val SCE_FS_COMMENTLINE=2 val SCE_FS_COMMENTDOC=3 val SCE_FS_COMMENTLINEDOC=4 val SCE_FS_COMMENTDOCKEYWORD=5 val SCE_FS_COMMENTDOCKEYWORDERROR=6 val SCE_FS_KEYWORD=7 val SCE_FS_KEYWORD2=8 val SCE_FS_KEYWORD3=9 val SCE_FS_KEYWORD4=10 val SCE_FS_NUMBER=11 val SCE_FS_STRING=12 val SCE_FS_PREPROCESSOR=13 val SCE_FS_OPERATOR=14 val SCE_FS_IDENTIFIER=15 val SCE_FS_DATE=16 val SCE_FS_STRINGEOL=17 val SCE_FS_CONSTANT=18 val SCE_FS_WORDOPERATOR=19 val SCE_FS_DISABLEDCODE=20 val SCE_FS_DEFAULT_C=21 val SCE_FS_COMMENTDOC_C=22 val SCE_FS_COMMENTLINEDOC_C=23 val SCE_FS_KEYWORD_C=24 val SCE_FS_KEYWORD2_C=25 val SCE_FS_NUMBER_C=26 val SCE_FS_STRING_C=27 val SCE_FS_PREPROCESSOR_C=28 val SCE_FS_OPERATOR_C=29 val SCE_FS_IDENTIFIER_C=30 val SCE_FS_STRINGEOL_C=31 # Lexical states for SCLEX_CSOUND lex Csound=SCLEX_CSOUND SCE_CSOUND_ val SCE_CSOUND_DEFAULT=0 val SCE_CSOUND_COMMENT=1 val SCE_CSOUND_NUMBER=2 val SCE_CSOUND_OPERATOR=3 val SCE_CSOUND_INSTR=4 val SCE_CSOUND_IDENTIFIER=5 val SCE_CSOUND_OPCODE=6 val SCE_CSOUND_HEADERSTMT=7 val SCE_CSOUND_USERKEYWORD=8 val SCE_CSOUND_COMMENTBLOCK=9 val SCE_CSOUND_PARAM=10 val SCE_CSOUND_ARATE_VAR=11 val SCE_CSOUND_KRATE_VAR=12 val SCE_CSOUND_IRATE_VAR=13 val SCE_CSOUND_GLOBAL_VAR=14 val SCE_CSOUND_STRINGEOL=15 # Lexical states for SCLEX_INNOSETUP lex Inno=SCLEX_INNOSETUP SCE_INNO_ val SCE_INNO_DEFAULT=0 val SCE_INNO_COMMENT=1 val SCE_INNO_KEYWORD=2 val SCE_INNO_PARAMETER=3 val SCE_INNO_SECTION=4 val SCE_INNO_PREPROC=5 val SCE_INNO_INLINE_EXPANSION=6 val SCE_INNO_COMMENT_PASCAL=7 val SCE_INNO_KEYWORD_PASCAL=8 val SCE_INNO_KEYWORD_USER=9 val SCE_INNO_STRING_DOUBLE=10 val SCE_INNO_STRING_SINGLE=11 val SCE_INNO_IDENTIFIER=12 # Lexical states for SCLEX_OPAL lex Opal=SCLEX_OPAL SCE_OPAL_ val SCE_OPAL_SPACE=0 val SCE_OPAL_COMMENT_BLOCK=1 val SCE_OPAL_COMMENT_LINE=2 val SCE_OPAL_INTEGER=3 val SCE_OPAL_KEYWORD=4 val SCE_OPAL_SORT=5 val SCE_OPAL_STRING=6 val SCE_OPAL_PAR=7 val SCE_OPAL_BOOL_CONST=8 val SCE_OPAL_DEFAULT=32 # Lexical states for SCLEX_SPICE lex Spice=SCLEX_SPICE SCE_SPICE_ val SCE_SPICE_DEFAULT=0 val SCE_SPICE_IDENTIFIER=1 val SCE_SPICE_KEYWORD=2 val SCE_SPICE_KEYWORD2=3 val SCE_SPICE_KEYWORD3=4 val SCE_SPICE_NUMBER=5 val SCE_SPICE_DELIMITER=6 val SCE_SPICE_VALUE=7 val SCE_SPICE_COMMENTLINE=8 # Lexical states for SCLEX_CMAKE lex CMAKE=SCLEX_CMAKE SCE_CMAKE_ val SCE_CMAKE_DEFAULT=0 val SCE_CMAKE_COMMENT=1 val SCE_CMAKE_STRINGDQ=2 val SCE_CMAKE_STRINGLQ=3 val SCE_CMAKE_STRINGRQ=4 val SCE_CMAKE_COMMANDS=5 val SCE_CMAKE_PARAMETERS=6 val SCE_CMAKE_VARIABLE=7 val SCE_CMAKE_USERDEFINED=8 val SCE_CMAKE_WHILEDEF=9 val SCE_CMAKE_FOREACHDEF=10 val SCE_CMAKE_IFDEFINEDEF=11 val SCE_CMAKE_MACRODEF=12 val SCE_CMAKE_STRINGVAR=13 val SCE_CMAKE_NUMBER=14 # Lexical states for SCLEX_GAP lex Gap=SCLEX_GAP SCE_GAP_ val SCE_GAP_DEFAULT=0 val SCE_GAP_IDENTIFIER=1 val SCE_GAP_KEYWORD=2 val SCE_GAP_KEYWORD2=3 val SCE_GAP_KEYWORD3=4 val SCE_GAP_KEYWORD4=5 val SCE_GAP_STRING=6 val SCE_GAP_CHAR=7 val SCE_GAP_OPERATOR=8 val SCE_GAP_COMMENT=9 val SCE_GAP_NUMBER=10 val SCE_GAP_STRINGEOL=11 # Lexical state for SCLEX_PLM lex PLM=SCLEX_PLM SCE_PLM_ val SCE_PLM_DEFAULT=0 val SCE_PLM_COMMENT=1 val SCE_PLM_STRING=2 val SCE_PLM_NUMBER=3 val SCE_PLM_IDENTIFIER=4 val SCE_PLM_OPERATOR=5 val SCE_PLM_CONTROL=6 val SCE_PLM_KEYWORD=7 # Lexical state for SCLEX_PROGRESS lex Progress=SCLEX_PROGRESS SCE_4GL_ val SCE_4GL_DEFAULT=0 val SCE_4GL_NUMBER=1 val SCE_4GL_WORD=2 val SCE_4GL_STRING=3 val SCE_4GL_CHARACTER=4 val SCE_4GL_PREPROCESSOR=5 val SCE_4GL_OPERATOR=6 val SCE_4GL_IDENTIFIER=7 val SCE_4GL_BLOCK=8 val SCE_4GL_END=9 val SCE_4GL_COMMENT1=10 val SCE_4GL_COMMENT2=11 val SCE_4GL_COMMENT3=12 val SCE_4GL_COMMENT4=13 val SCE_4GL_COMMENT5=14 val SCE_4GL_COMMENT6=15 val SCE_4GL_DEFAULT_=16 val SCE_4GL_NUMBER_=17 val SCE_4GL_WORD_=18 val SCE_4GL_STRING_=19 val SCE_4GL_CHARACTER_=20 val SCE_4GL_PREPROCESSOR_=21 val SCE_4GL_OPERATOR_=22 val SCE_4GL_IDENTIFIER_=23 val SCE_4GL_BLOCK_=24 val SCE_4GL_END_=25 val SCE_4GL_COMMENT1_=26 val SCE_4GL_COMMENT2_=27 val SCE_4GL_COMMENT3_=28 val SCE_4GL_COMMENT4_=29 val SCE_4GL_COMMENT5_=30 val SCE_4GL_COMMENT6_=31 # Lexical states for SCLEX_ABAQUS lex ABAQUS=SCLEX_ABAQUS SCE_ABAQUS_ val SCE_ABAQUS_DEFAULT=0 val SCE_ABAQUS_COMMENT=1 val SCE_ABAQUS_COMMENTBLOCK=2 val SCE_ABAQUS_NUMBER=3 val SCE_ABAQUS_STRING=4 val SCE_ABAQUS_OPERATOR=5 val SCE_ABAQUS_WORD=6 val SCE_ABAQUS_PROCESSOR=7 val SCE_ABAQUS_COMMAND=8 val SCE_ABAQUS_SLASHCOMMAND=9 val SCE_ABAQUS_STARCOMMAND=10 val SCE_ABAQUS_ARGUMENT=11 val SCE_ABAQUS_FUNCTION=12 # Lexical states for SCLEX_ASYMPTOTE lex Asymptote=SCLEX_ASYMPTOTE SCE_ASY_ val SCE_ASY_DEFAULT=0 val SCE_ASY_COMMENT=1 val SCE_ASY_COMMENTLINE=2 val SCE_ASY_NUMBER=3 val SCE_ASY_WORD=4 val SCE_ASY_STRING=5 val SCE_ASY_CHARACTER=6 val SCE_ASY_OPERATOR=7 val SCE_ASY_IDENTIFIER=8 val SCE_ASY_STRINGEOL=9 val SCE_ASY_COMMENTLINEDOC=10 val SCE_ASY_WORD2=11 # Lexical states for SCLEX_R lex R=SCLEX_R SCE_R_ val SCE_R_DEFAULT=0 val SCE_R_COMMENT=1 val SCE_R_KWORD=2 val SCE_R_BASEKWORD=3 val SCE_R_OTHERKWORD=4 val SCE_R_NUMBER=5 val SCE_R_STRING=6 val SCE_R_STRING2=7 val SCE_R_OPERATOR=8 val SCE_R_IDENTIFIER=9 val SCE_R_INFIX=10 val SCE_R_INFIXEOL=11 # Lexical state for SCLEX_MAGIKSF lex MagikSF=SCLEX_MAGIKSF SCE_MAGIK_ val SCE_MAGIK_DEFAULT=0 val SCE_MAGIK_COMMENT=1 val SCE_MAGIK_HYPER_COMMENT=16 val SCE_MAGIK_STRING=2 val SCE_MAGIK_CHARACTER=3 val SCE_MAGIK_NUMBER=4 val SCE_MAGIK_IDENTIFIER=5 val SCE_MAGIK_OPERATOR=6 val SCE_MAGIK_FLOW=7 val SCE_MAGIK_CONTAINER=8 val SCE_MAGIK_BRACKET_BLOCK=9 val SCE_MAGIK_BRACE_BLOCK=10 val SCE_MAGIK_SQBRACKET_BLOCK=11 val SCE_MAGIK_UNKNOWN_KEYWORD=12 val SCE_MAGIK_KEYWORD=13 val SCE_MAGIK_PRAGMA=14 val SCE_MAGIK_SYMBOL=15 # Lexical state for SCLEX_POWERSHELL lex PowerShell=SCLEX_POWERSHELL SCE_POWERSHELL_ val SCE_POWERSHELL_DEFAULT=0 val SCE_POWERSHELL_COMMENT=1 val SCE_POWERSHELL_STRING=2 val SCE_POWERSHELL_CHARACTER=3 val SCE_POWERSHELL_NUMBER=4 val SCE_POWERSHELL_VARIABLE=5 val SCE_POWERSHELL_OPERATOR=6 val SCE_POWERSHELL_IDENTIFIER=7 val SCE_POWERSHELL_KEYWORD=8 val SCE_POWERSHELL_CMDLET=9 val SCE_POWERSHELL_ALIAS=10 val SCE_POWERSHELL_FUNCTION=11 val SCE_POWERSHELL_USER1=12 val SCE_POWERSHELL_COMMENTSTREAM=13 # Lexical state for SCLEX_MYSQL lex MySQL=SCLEX_MYSQL SCE_MYSQL_ val SCE_MYSQL_DEFAULT=0 val SCE_MYSQL_COMMENT=1 val SCE_MYSQL_COMMENTLINE=2 val SCE_MYSQL_VARIABLE=3 val SCE_MYSQL_SYSTEMVARIABLE=4 val SCE_MYSQL_KNOWNSYSTEMVARIABLE=5 val SCE_MYSQL_NUMBER=6 val SCE_MYSQL_MAJORKEYWORD=7 val SCE_MYSQL_KEYWORD=8 val SCE_MYSQL_DATABASEOBJECT=9 val SCE_MYSQL_PROCEDUREKEYWORD=10 val SCE_MYSQL_STRING=11 val SCE_MYSQL_SQSTRING=12 val SCE_MYSQL_DQSTRING=13 val SCE_MYSQL_OPERATOR=14 val SCE_MYSQL_FUNCTION=15 val SCE_MYSQL_IDENTIFIER=16 val SCE_MYSQL_QUOTEDIDENTIFIER=17 val SCE_MYSQL_USER1=18 val SCE_MYSQL_USER2=19 val SCE_MYSQL_USER3=20 val SCE_MYSQL_HIDDENCOMMAND=21 val SCE_MYSQL_PLACEHOLDER=22 # Lexical state for SCLEX_PO lex Po=SCLEX_PO SCE_PO_ val SCE_PO_DEFAULT=0 val SCE_PO_COMMENT=1 val SCE_PO_MSGID=2 val SCE_PO_MSGID_TEXT=3 val SCE_PO_MSGSTR=4 val SCE_PO_MSGSTR_TEXT=5 val SCE_PO_MSGCTXT=6 val SCE_PO_MSGCTXT_TEXT=7 val SCE_PO_FUZZY=8 val SCE_PO_PROGRAMMER_COMMENT=9 val SCE_PO_REFERENCE=10 val SCE_PO_FLAGS=11 val SCE_PO_MSGID_TEXT_EOL=12 val SCE_PO_MSGSTR_TEXT_EOL=13 val SCE_PO_MSGCTXT_TEXT_EOL=14 val SCE_PO_ERROR=15 # Lexical states for SCLEX_PASCAL lex Pascal=SCLEX_PASCAL SCE_PAS_ val SCE_PAS_DEFAULT=0 val SCE_PAS_IDENTIFIER=1 val SCE_PAS_COMMENT=2 val SCE_PAS_COMMENT2=3 val SCE_PAS_COMMENTLINE=4 val SCE_PAS_PREPROCESSOR=5 val SCE_PAS_PREPROCESSOR2=6 val SCE_PAS_NUMBER=7 val SCE_PAS_HEXNUMBER=8 val SCE_PAS_WORD=9 val SCE_PAS_STRING=10 val SCE_PAS_STRINGEOL=11 val SCE_PAS_CHARACTER=12 val SCE_PAS_OPERATOR=13 val SCE_PAS_ASM=14 # Lexical state for SCLEX_SORCUS lex SORCUS=SCLEX_SORCUS SCE_SORCUS_ val SCE_SORCUS_DEFAULT=0 val SCE_SORCUS_COMMAND=1 val SCE_SORCUS_PARAMETER=2 val SCE_SORCUS_COMMENTLINE=3 val SCE_SORCUS_STRING=4 val SCE_SORCUS_STRINGEOL=5 val SCE_SORCUS_IDENTIFIER=6 val SCE_SORCUS_OPERATOR=7 val SCE_SORCUS_NUMBER=8 val SCE_SORCUS_CONSTANT=9 # Lexical state for SCLEX_POWERPRO lex PowerPro=SCLEX_POWERPRO SCE_POWERPRO_ val SCE_POWERPRO_DEFAULT=0 val SCE_POWERPRO_COMMENTBLOCK=1 val SCE_POWERPRO_COMMENTLINE=2 val SCE_POWERPRO_NUMBER=3 val SCE_POWERPRO_WORD=4 val SCE_POWERPRO_WORD2=5 val SCE_POWERPRO_WORD3=6 val SCE_POWERPRO_WORD4=7 val SCE_POWERPRO_DOUBLEQUOTEDSTRING=8 val SCE_POWERPRO_SINGLEQUOTEDSTRING=9 val SCE_POWERPRO_LINECONTINUE=10 val SCE_POWERPRO_OPERATOR=11 val SCE_POWERPRO_IDENTIFIER=12 val SCE_POWERPRO_STRINGEOL=13 val SCE_POWERPRO_VERBATIM=14 val SCE_POWERPRO_ALTQUOTE=15 val SCE_POWERPRO_FUNCTION=16 # Lexical states for SCLEX_SML lex SML=SCLEX_SML SCE_SML_ val SCE_SML_DEFAULT=0 val SCE_SML_IDENTIFIER=1 val SCE_SML_TAGNAME=2 val SCE_SML_KEYWORD=3 val SCE_SML_KEYWORD2=4 val SCE_SML_KEYWORD3=5 val SCE_SML_LINENUM=6 val SCE_SML_OPERATOR=7 val SCE_SML_NUMBER=8 val SCE_SML_CHAR=9 val SCE_SML_STRING=11 val SCE_SML_COMMENT=12 val SCE_SML_COMMENT1=13 val SCE_SML_COMMENT2=14 val SCE_SML_COMMENT3=15 # Lexical state for SCLEX_MARKDOWN lex Markdown=SCLEX_MARKDOWN SCE_MARKDOWN_ val SCE_MARKDOWN_DEFAULT=0 val SCE_MARKDOWN_LINE_BEGIN=1 val SCE_MARKDOWN_STRONG1=2 val SCE_MARKDOWN_STRONG2=3 val SCE_MARKDOWN_EM1=4 val SCE_MARKDOWN_EM2=5 val SCE_MARKDOWN_HEADER1=6 val SCE_MARKDOWN_HEADER2=7 val SCE_MARKDOWN_HEADER3=8 val SCE_MARKDOWN_HEADER4=9 val SCE_MARKDOWN_HEADER5=10 val SCE_MARKDOWN_HEADER6=11 val SCE_MARKDOWN_PRECHAR=12 val SCE_MARKDOWN_ULIST_ITEM=13 val SCE_MARKDOWN_OLIST_ITEM=14 val SCE_MARKDOWN_BLOCKQUOTE=15 val SCE_MARKDOWN_STRIKEOUT=16 val SCE_MARKDOWN_HRULE=17 val SCE_MARKDOWN_LINK=18 val SCE_MARKDOWN_CODE=19 val SCE_MARKDOWN_CODE2=20 val SCE_MARKDOWN_CODEBK=21 # Lexical state for SCLEX_TXT2TAGS lex Txt2tags=SCLEX_TXT2TAGS SCE_TXT2TAGS_ val SCE_TXT2TAGS_DEFAULT=0 val SCE_TXT2TAGS_LINE_BEGIN=1 val SCE_TXT2TAGS_STRONG1=2 val SCE_TXT2TAGS_STRONG2=3 val SCE_TXT2TAGS_EM1=4 val SCE_TXT2TAGS_EM2=5 val SCE_TXT2TAGS_HEADER1=6 val SCE_TXT2TAGS_HEADER2=7 val SCE_TXT2TAGS_HEADER3=8 val SCE_TXT2TAGS_HEADER4=9 val SCE_TXT2TAGS_HEADER5=10 val SCE_TXT2TAGS_HEADER6=11 val SCE_TXT2TAGS_PRECHAR=12 val SCE_TXT2TAGS_ULIST_ITEM=13 val SCE_TXT2TAGS_OLIST_ITEM=14 val SCE_TXT2TAGS_BLOCKQUOTE=15 val SCE_TXT2TAGS_STRIKEOUT=16 val SCE_TXT2TAGS_HRULE=17 val SCE_TXT2TAGS_LINK=18 val SCE_TXT2TAGS_CODE=19 val SCE_TXT2TAGS_CODE2=20 val SCE_TXT2TAGS_CODEBK=21 val SCE_TXT2TAGS_COMMENT=22 val SCE_TXT2TAGS_OPTION=23 val SCE_TXT2TAGS_PREPROC=24 val SCE_TXT2TAGS_POSTPROC=25 # Lexical states for SCLEX_A68K lex A68k=SCLEX_A68K SCE_A68K_ val SCE_A68K_DEFAULT=0 val SCE_A68K_COMMENT=1 val SCE_A68K_NUMBER_DEC=2 val SCE_A68K_NUMBER_BIN=3 val SCE_A68K_NUMBER_HEX=4 val SCE_A68K_STRING1=5 val SCE_A68K_OPERATOR=6 val SCE_A68K_CPUINSTRUCTION=7 val SCE_A68K_EXTINSTRUCTION=8 val SCE_A68K_REGISTER=9 val SCE_A68K_DIRECTIVE=10 val SCE_A68K_MACRO_ARG=11 val SCE_A68K_LABEL=12 val SCE_A68K_STRING2=13 val SCE_A68K_IDENTIFIER=14 val SCE_A68K_MACRO_DECLARATION=15 val SCE_A68K_COMMENT_WORD=16 val SCE_A68K_COMMENT_SPECIAL=17 val SCE_A68K_COMMENT_DOXYGEN=18 # Lexical states for SCLEX_MODULA lex Modula=SCLEX_MODULA SCE_MODULA_ val SCE_MODULA_DEFAULT=0 val SCE_MODULA_COMMENT=1 val SCE_MODULA_DOXYCOMM=2 val SCE_MODULA_DOXYKEY=3 val SCE_MODULA_KEYWORD=4 val SCE_MODULA_RESERVED=5 val SCE_MODULA_NUMBER=6 val SCE_MODULA_BASENUM=7 val SCE_MODULA_FLOAT=8 val SCE_MODULA_STRING=9 val SCE_MODULA_STRSPEC=10 val SCE_MODULA_CHAR=11 val SCE_MODULA_CHARSPEC=12 val SCE_MODULA_PROC=13 val SCE_MODULA_PRAGMA=14 val SCE_MODULA_PRGKEY=15 val SCE_MODULA_OPERATOR=16 val SCE_MODULA_BADSTR=17 # Lexical states for SCLEX_COFFEESCRIPT lex CoffeeScript=SCLEX_COFFEESCRIPT SCE_COFFEESCRIPT_ val SCE_COFFEESCRIPT_DEFAULT=0 val SCE_COFFEESCRIPT_COMMENT=1 val SCE_COFFEESCRIPT_COMMENTLINE=2 val SCE_COFFEESCRIPT_COMMENTDOC=3 val SCE_COFFEESCRIPT_NUMBER=4 val SCE_COFFEESCRIPT_WORD=5 val SCE_COFFEESCRIPT_STRING=6 val SCE_COFFEESCRIPT_CHARACTER=7 val SCE_COFFEESCRIPT_UUID=8 val SCE_COFFEESCRIPT_PREPROCESSOR=9 val SCE_COFFEESCRIPT_OPERATOR=10 val SCE_COFFEESCRIPT_IDENTIFIER=11 val SCE_COFFEESCRIPT_STRINGEOL=12 val SCE_COFFEESCRIPT_VERBATIM=13 val SCE_COFFEESCRIPT_REGEX=14 val SCE_COFFEESCRIPT_COMMENTLINEDOC=15 val SCE_COFFEESCRIPT_WORD2=16 val SCE_COFFEESCRIPT_COMMENTDOCKEYWORD=17 val SCE_COFFEESCRIPT_COMMENTDOCKEYWORDERROR=18 val SCE_COFFEESCRIPT_GLOBALCLASS=19 val SCE_COFFEESCRIPT_STRINGRAW=20 val SCE_COFFEESCRIPT_TRIPLEVERBATIM=21 val SCE_COFFEESCRIPT_HASHQUOTEDSTRING=22 val SCE_COFFEESCRIPT_COMMENTBLOCK=22 val SCE_COFFEESCRIPT_VERBOSE_REGEX=23 val SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT=24 # Lexical states for SCLEX_AVS lex AVS=SCLEX_AVS SCE_AVS_ val SCE_AVS_DEFAULT=0 val SCE_AVS_COMMENTBLOCK=1 val SCE_AVS_COMMENTBLOCKN=2 val SCE_AVS_COMMENTLINE=3 val SCE_AVS_NUMBER=4 val SCE_AVS_OPERATOR=5 val SCE_AVS_IDENTIFIER=6 val SCE_AVS_STRING=7 val SCE_AVS_TRIPLESTRING=8 val SCE_AVS_KEYWORD=9 val SCE_AVS_FILTER=10 val SCE_AVS_PLUGIN=11 val SCE_AVS_FUNCTION=12 val SCE_AVS_CLIPPROP=13 val SCE_AVS_USERDFN=14 # Lexical states for SCLEX_ECL lex ECL=SCLEX_ECL SCE_ECL_ val SCE_ECL_DEFAULT=0 val SCE_ECL_COMMENT=1 val SCE_ECL_COMMENTLINE=2 val SCE_ECL_NUMBER=3 val SCE_ECL_STRING=4 val SCE_ECL_WORD0=5 val SCE_ECL_OPERATOR=6 val SCE_ECL_CHARACTER=7 val SCE_ECL_UUID=8 val SCE_ECL_PREPROCESSOR=9 val SCE_ECL_UNKNOWN=10 val SCE_ECL_IDENTIFIER=11 val SCE_ECL_STRINGEOL=12 val SCE_ECL_VERBATIM=13 val SCE_ECL_REGEX=14 val SCE_ECL_COMMENTLINEDOC=15 val SCE_ECL_WORD1=16 val SCE_ECL_COMMENTDOCKEYWORD=17 val SCE_ECL_COMMENTDOCKEYWORDERROR=18 val SCE_ECL_WORD2=19 val SCE_ECL_WORD3=20 val SCE_ECL_WORD4=21 val SCE_ECL_WORD5=22 val SCE_ECL_COMMENTDOC=23 val SCE_ECL_ADDED=24 val SCE_ECL_DELETED=25 val SCE_ECL_CHANGED=26 val SCE_ECL_MOVED=27 # Lexical states for SCLEX_OSCRIPT lex OScript=SCLEX_OSCRIPT SCE_OSCRIPT_ val SCE_OSCRIPT_DEFAULT=0 val SCE_OSCRIPT_LINE_COMMENT=1 val SCE_OSCRIPT_BLOCK_COMMENT=2 val SCE_OSCRIPT_DOC_COMMENT=3 val SCE_OSCRIPT_PREPROCESSOR=4 val SCE_OSCRIPT_NUMBER=5 val SCE_OSCRIPT_SINGLEQUOTE_STRING=6 val SCE_OSCRIPT_DOUBLEQUOTE_STRING=7 val SCE_OSCRIPT_CONSTANT=8 val SCE_OSCRIPT_IDENTIFIER=9 val SCE_OSCRIPT_GLOBAL=10 val SCE_OSCRIPT_KEYWORD=11 val SCE_OSCRIPT_OPERATOR=12 val SCE_OSCRIPT_LABEL=13 val SCE_OSCRIPT_TYPE=14 val SCE_OSCRIPT_FUNCTION=15 val SCE_OSCRIPT_OBJECT=16 val SCE_OSCRIPT_PROPERTY=17 val SCE_OSCRIPT_METHOD=18 # Lexical states for SCLEX_VISUALPROLOG lex VisualProlog=SCLEX_VISUALPROLOG SCE_VISUALPROLOG_ val SCE_VISUALPROLOG_DEFAULT=0 val SCE_VISUALPROLOG_KEY_MAJOR=1 val SCE_VISUALPROLOG_KEY_MINOR=2 val SCE_VISUALPROLOG_KEY_DIRECTIVE=3 val SCE_VISUALPROLOG_COMMENT_BLOCK=4 val SCE_VISUALPROLOG_COMMENT_LINE=5 val SCE_VISUALPROLOG_COMMENT_KEY=6 val SCE_VISUALPROLOG_COMMENT_KEY_ERROR=7 val SCE_VISUALPROLOG_IDENTIFIER=8 val SCE_VISUALPROLOG_VARIABLE=9 val SCE_VISUALPROLOG_ANONYMOUS=10 val SCE_VISUALPROLOG_NUMBER=11 val SCE_VISUALPROLOG_OPERATOR=12 val SCE_VISUALPROLOG_CHARACTER=13 val SCE_VISUALPROLOG_CHARACTER_TOO_MANY=14 val SCE_VISUALPROLOG_CHARACTER_ESCAPE_ERROR=15 val SCE_VISUALPROLOG_STRING=16 val SCE_VISUALPROLOG_STRING_ESCAPE=17 val SCE_VISUALPROLOG_STRING_ESCAPE_ERROR=18 val SCE_VISUALPROLOG_STRING_EOL_OPEN=19 val SCE_VISUALPROLOG_STRING_VERBATIM=20 val SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL=21 val SCE_VISUALPROLOG_STRING_VERBATIM_EOL=22 # Events evt void StyleNeeded=2000(int position) evt void CharAdded=2001(int ch) evt void SavePointReached=2002(void) evt void SavePointLeft=2003(void) evt void ModifyAttemptRO=2004(void) # GTK+ Specific to work around focus and accelerator problems: evt void Key=2005(int ch, int modifiers) evt void DoubleClick=2006(int modifiers, int position, int line) evt void UpdateUI=2007(int updated) evt void Modified=2008(int position, int modificationType, string text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev, int token, int annotationLinesAdded) evt void MacroRecord=2009(int message, int wParam, int lParam) evt void MarginClick=2010(int modifiers, int position, int margin) evt void NeedShown=2011(int position, int length) evt void Painted=2013(void) evt void UserListSelection=2014(int listType, string text, int position) evt void URIDropped=2015(string text) evt void DwellStart=2016(int position, int x, int y) evt void DwellEnd=2017(int position, int x, int y) evt void Zoom=2018(void) evt void HotSpotClick=2019(int modifiers, int position) evt void HotSpotDoubleClick=2020(int modifiers, int position) evt void CallTipClick=2021(int position) evt void AutoCSelection=2022(string text, int position) evt void IndicatorClick=2023(int modifiers, int position) evt void IndicatorRelease=2024(int modifiers, int position) evt void AutoCCancelled=2025(void) evt void AutoCCharDeleted=2026(void) evt void HotSpotReleaseClick=2027(int modifiers, int position) cat Provisional # Line end types which may be used in addition to LF, CR, and CRLF # SC_LINE_END_TYPE_UNICODE includes U+2028 Line Separator, # U+2029 Paragraph Separator, and U+0085 Next Line enu LineEndType=SC_LINE_END_TYPE_ val SC_LINE_END_TYPE_DEFAULT=0 val SC_LINE_END_TYPE_UNICODE=1 # Set the line end types that the application wants to use. May not be used if incompatible with lexer or encoding. set void SetLineEndTypesAllowed=2656(int lineEndBitSet,) # Get the line end types currently allowed. get int GetLineEndTypesAllowed=2657(,) # Get the line end types currently recognised. May be a subset of the allowed types due to lexer limitation. get int GetLineEndTypesActive=2658(,) # Bit set of LineEndType enumertion for which line ends beyond the standard # LF, CR, and CRLF are supported by the lexer. get int GetLineEndTypesSupported=4018(,) # Allocate a set of sub styles for a particular base style, returning start of range fun int AllocateSubStyles=4020(int styleBase, int numberStyles) # The starting style number for the sub styles associated with a base style get int GetSubStylesStart=4021(int styleBase,) # The number of sub styles associated with a base style get int GetSubStylesLength=4022(int styleBase,) # Free allocated sub styles fun void FreeSubStyles=4023(,) # Set the identifiers that are shown in a particular style set void SetIdentifiers=4024(int style, string identifiers) # Where styles are duplicated by a feature such as active/inactive code # return the distance between the two types. get int DistanceToSecondaryStyles=4025(,) # Get the set of base styles that can be extended with sub styles get int GetSubStyleBases=4026(, stringresult styles) cat Deprecated # Deprecated in 2.21 # The SC_CP_DBCS value can be used to indicate a DBCS mode for GTK+. val SC_CP_DBCS=1 # Deprecated in 2.30 # In palette mode? get bool GetUsePalette=2139(,) # In palette mode, Scintilla uses the environment's palette calls to display # more colours. This may lead to ugly displays. set void SetUsePalette=2039(bool usePalette,) |
Added include/ScintillaWidget.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
/* Scintilla source code edit control */ /** @file ScintillaWidget.h ** Definition of Scintilla widget for GTK+. ** Only needed by GTK+ code but is harmless on other platforms. **/ /* Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> * The License.txt file describes the conditions under which this software may be distributed. */ #ifndef SCINTILLAWIDGET_H #define SCINTILLAWIDGET_H #if defined(GTK) #ifdef __cplusplus extern "C" { #endif #define SCINTILLA(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, scintilla_get_type (), ScintillaObject) #define SCINTILLA_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, scintilla_get_type (), ScintillaClass) #define IS_SCINTILLA(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, scintilla_get_type ()) typedef struct _ScintillaObject ScintillaObject; typedef struct _ScintillaClass ScintillaClass; struct _ScintillaObject { GtkContainer cont; void *pscin; }; struct _ScintillaClass { GtkContainerClass parent_class; void (* command) (ScintillaObject *ttt); void (* notify) (ScintillaObject *ttt); }; GType scintilla_get_type (void); GtkWidget* scintilla_new (void); void scintilla_set_id (ScintillaObject *sci, uptr_t id); sptr_t scintilla_send_message (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam); void scintilla_release_resources(void); #define SCINTILLA_NOTIFY "sci-notify" #ifdef __cplusplus } #endif #elif defined(TK) //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifdef __cplusplus extern "C" { #endif #include <tcl.h> #include <tk.h> // a simple stack dumper void _print_trace (bool on=false); int _x_error_handler(Display *, XErrorEvent *); typedef struct _ScintillaObject ScintillaObject; // pick a start value safely above what the scintilla code already uses (see Scintilla.h) enum { SCI_TKMSG_PAINT = 10000, SCI_TKMSG_DESTROY, SCI_TKMSG_DUMPSTYLES, SCI_TKMSG_ANNOTATIONINDENT, SCI_TKMSG_ANNOTATIONLENGTH, SCI_TKMSG_RESIZE }; struct _ScintillaObject { _ScintillaObject() { // printf("HEY -- CTOR of ScintillaObject %p\n",(void *)this); } ~_ScintillaObject() { // printf("HEY -- DTOR of ScintillaObject %p\n",(void *)this); } Tcl_Interp *interp; Tk_Window tkwin; ClientData client; // this will hold the ref to the parent Tk widget // pointer to the platform-specific scintilla editor class object void *pscin; // this flag indicates if this is the main(client) window bool main; }; // THESE ARE IMPLEMENTED IN ScintillaTK.cxx ScintillaObject* scintilla_new(Tcl_Interp *, Tk_Window, ClientData); sptr_t scintilla_send_message(ScintillaObject *sci, unsigned int iMessage, uptr_t wParam, sptr_t lParam); #ifdef __cplusplus } #endif #endif //if defined(TK) #endif |
Added lexers/LexA68k.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
// Scintilla source code edit control /** @file LexA68k.cxx ** Lexer for Assembler, just for the MASM syntax ** Written by Martial Demolins AKA Folco **/ // Copyright 2010 Martial Demolins <mdemolins(a)gmail.com> // The License.txt file describes the conditions under which this software // may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // Return values for GetOperatorType #define NO_OPERATOR 0 #define OPERATOR_1CHAR 1 #define OPERATOR_2CHAR 2 /** * IsIdentifierStart * * Return true if the given char is a valid identifier first char */ static inline bool IsIdentifierStart (const int ch) { return (isalpha(ch) || (ch == '_') || (ch == '\\')); } /** * IsIdentifierChar * * Return true if the given char is a valid identifier char */ static inline bool IsIdentifierChar (const int ch) { return (isalnum(ch) || (ch == '_') || (ch == '@') || (ch == ':') || (ch == '.')); } /** * GetOperatorType * * Return: * NO_OPERATOR if char is not an operator * OPERATOR_1CHAR if the operator is one char long * OPERATOR_2CHAR if the operator is two chars long */ static inline int GetOperatorType (const int ch1, const int ch2) { int OpType = NO_OPERATOR; if ((ch1 == '+') || (ch1 == '-') || (ch1 == '*') || (ch1 == '/') || (ch1 == '#') || (ch1 == '(') || (ch1 == ')') || (ch1 == '~') || (ch1 == '&') || (ch1 == '|') || (ch1 == ',')) OpType = OPERATOR_1CHAR; else if ((ch1 == ch2) && (ch1 == '<' || ch1 == '>')) OpType = OPERATOR_2CHAR; return OpType; } /** * IsBin * * Return true if the given char is 0 or 1 */ static inline bool IsBin (const int ch) { return (ch == '0') || (ch == '1'); } /** * IsDoxygenChar * * Return true if the char may be part of a Doxygen keyword */ static inline bool IsDoxygenChar (const int ch) { return isalpha(ch) || (ch == '$') || (ch == '[') || (ch == ']') || (ch == '{') || (ch == '}'); } /** * ColouriseA68kDoc * * Main function, which colourises a 68k source */ static void ColouriseA68kDoc (unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { // Get references to keywords lists WordList &cpuInstruction = *keywordlists[0]; WordList ®isters = *keywordlists[1]; WordList &directive = *keywordlists[2]; WordList &extInstruction = *keywordlists[3]; WordList &commentSpecial = *keywordlists[4]; WordList &doxygenKeyword = *keywordlists[5]; // Instanciate a context for our source StyleContext sc(startPos, length, initStyle, styler); /************************************************************ * * Parse the text * ************************************************************/ for ( ; sc.More(); sc.Forward()) { char Buffer[100]; int OpType; // Reset style at beginning of line if (sc.atLineStart) sc.SetState(SCE_A68K_DEFAULT); /************************************************************ * * Handle current state if we are not in the "default style" * ************************************************************/ if (sc.state != SCE_A68K_DEFAULT) { // Check if current style continue. // If this case, we loop because there is nothing else to do if (((sc.state == SCE_A68K_NUMBER_DEC) && isdigit(sc.ch)) // Decimal number || ((sc.state == SCE_A68K_NUMBER_BIN) && IsBin(sc.ch)) // Binary number || ((sc.state == SCE_A68K_NUMBER_HEX) && isxdigit(sc.ch)) // Hexa number || ((sc.state == SCE_A68K_MACRO_ARG) && isdigit(sc.ch)) // Arg of macro || ((sc.state == SCE_A68K_STRING1) && (sc.ch != '\'')) // String single-quoted || ((sc.state == SCE_A68K_STRING2) && (sc.ch != '\"')) // String double-quoted || ((sc.state == SCE_A68K_MACRO_ARG) && isdigit(sc.ch)) // Macro argument // Label. ' ' and '\t' are needed to handle macro declarations || ((sc.state == SCE_A68K_LABEL) && (sc.ch != ':') && (sc.ch != ' ') && (sc.ch != '\t')) || ((sc.state == SCE_A68K_IDENTIFIER) && (sc.ch < 0x80) && IsIdentifierChar(sc.ch)) // Identifier || ((sc.state == SCE_A68K_COMMENT_DOXYGEN) && (sc.ch < 0x80) && IsDoxygenChar(sc.ch)) // Doxygen keyword || ((sc.state == SCE_A68K_COMMENT_WORD) && (sc.ch < 0x80) && isalpha(sc.ch))) // Comment current word { continue; } // Check if some states terminate at the current char: // we must include this char in the current style context else if (((sc.state == SCE_A68K_STRING1) && (sc.ch < 0x80) && (sc.ch == '\'')) // String single-quoted || ((sc.state == SCE_A68K_STRING2) && (sc.ch < 0x80) && (sc.ch == '\"')) // String double-quoted || ((sc.state == SCE_A68K_LABEL) && (sc.ch < 0x80) && (sc.ch == ':'))) // Label { sc.ForwardSetState(SCE_A68K_DEFAULT); } // Check for special words or Doxygen keywords in comments else if (sc.state == SCE_A68K_COMMENT) { if (sc.ch == '\\') { sc.SetState(SCE_A68K_COMMENT_DOXYGEN); } else if ((sc.ch < 0x80) && isalpha(sc.ch)) { sc.SetState(SCE_A68K_COMMENT_WORD); } continue; } // Check for special words in comment else if ((sc.state == SCE_A68K_COMMENT_WORD) && (sc.ch < 0x80) && !isalpha(sc.ch)) { sc.GetCurrent(Buffer, sizeof(Buffer)); if (commentSpecial.InList(Buffer)) { sc.ChangeState(SCE_A68K_COMMENT_SPECIAL); } else { sc.ChangeState(SCE_A68K_COMMENT); } sc.SetState(SCE_A68K_COMMENT); continue; } // Check for Doxygen keywords else if ((sc.state == SCE_A68K_COMMENT_DOXYGEN) && (sc.ch < 0x80) && !IsDoxygenChar(sc.ch)) { sc.GetCurrentLowered(Buffer, sizeof(Buffer)); // Buffer the string of the current context if (!doxygenKeyword.InList(Buffer)) { sc.ChangeState(SCE_A68K_COMMENT); } sc.SetState(SCE_A68K_COMMENT); continue; } // Check if we are in the case of a label which terminates without ':' // It should be a macro declaration, not a label else if ((sc.state == SCE_A68K_LABEL) && (sc.ch < 0x80) && ((sc.ch == ' ') || (sc.ch == '\t'))) { sc.ChangeState(SCE_A68K_MACRO_DECLARATION); } // Check if we are at the end of an identifier // In this case, colourise it if was a keyword. else if ((sc.state == SCE_A68K_IDENTIFIER) && !IsIdentifierChar(sc.ch)) { sc.GetCurrentLowered(Buffer, sizeof(Buffer)); // Buffer the string of the current context if (cpuInstruction.InList(Buffer)) { // And check if it belongs to a keyword list sc.ChangeState(SCE_A68K_CPUINSTRUCTION); } else if (extInstruction.InList(Buffer)) { sc.ChangeState(SCE_A68K_EXTINSTRUCTION); } else if (registers.InList(Buffer)) { sc.ChangeState(SCE_A68K_REGISTER); } else if (directive.InList(Buffer)) { sc.ChangeState(SCE_A68K_DIRECTIVE); } } // All special contexts are now handled.Come back to default style sc.SetState(SCE_A68K_DEFAULT); } /************************************************************ * * Check if we must enter a new state * ************************************************************/ // Label and macro identifiers start at the beginning of a line // We set both as a label, but if it wasn't one (no ':' at the end), // it will be changed as a macro identifier. if (sc.atLineStart && (sc.ch < 0x80) && IsIdentifierStart(sc.ch)) { sc.SetState(SCE_A68K_LABEL); } else if ((sc.ch < 0x80) && (sc.ch == ';')) { // Comment sc.SetState(SCE_A68K_COMMENT); } else if ((sc.ch < 0x80) && isdigit(sc.ch)) { // Decimal numbers haven't prefix sc.SetState(SCE_A68K_NUMBER_DEC); } else if ((sc.ch < 0x80) && (sc.ch == '%')) { // Binary numbers are prefixed with '%' sc.SetState(SCE_A68K_NUMBER_BIN); } else if ((sc.ch < 0x80) && (sc.ch == '$')) { // Hexadecimal numbers are prefixed with '$' sc.SetState(SCE_A68K_NUMBER_HEX); } else if ((sc.ch < 0x80) && (sc.ch == '\'')) { // String (single-quoted) sc.SetState(SCE_A68K_STRING1); } else if ((sc.ch < 0x80) && (sc.ch == '\"')) { // String (double-quoted) sc.SetState(SCE_A68K_STRING2); } else if ((sc.ch < 0x80) && (sc.ch == '\\') && (isdigit(sc.chNext))) { // Replacement symbols in macro sc.SetState(SCE_A68K_MACRO_ARG); } else if ((sc.ch < 0x80) && IsIdentifierStart(sc.ch)) { // An identifier: constant, label, etc... sc.SetState(SCE_A68K_IDENTIFIER); } else { if (sc.ch < 0x80) { OpType = GetOperatorType(sc.ch, sc.chNext); // Check if current char is an operator if (OpType != NO_OPERATOR) { sc.SetState(SCE_A68K_OPERATOR); if (OpType == OPERATOR_2CHAR) { // Check if the operator is 2 bytes long sc.ForwardSetState(SCE_A68K_OPERATOR); // (>> or <<) } } } } } // End of for() sc.Complete(); } // Names of the keyword lists static const char * const a68kWordListDesc[] = { "CPU instructions", "Registers", "Directives", "Extended instructions", "Comment special words", "Doxygen keywords", 0 }; LexerModule lmA68k(SCLEX_A68K, ColouriseA68kDoc, "a68k", 0, a68kWordListDesc); |
Added lexers/LexAPDL.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
// Scintilla source code edit control /** @file LexAPDL.cxx ** Lexer for APDL. Based on the lexer for Assembler by The Black Horus. ** By Hadar Raz. **/ // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(const int ch) { return (ch < 0x80 && (isalnum(ch) || ch == '_')); } static inline bool IsAnOperator(char ch) { // '.' left out as it is used to make up numbers if (ch == '*' || ch == '/' || ch == '-' || ch == '+' || ch == '(' || ch == ')' || ch == '=' || ch == '^' || ch == '[' || ch == ']' || ch == '<' || ch == '&' || ch == '>' || ch == ',' || ch == '|' || ch == '~' || ch == '$' || ch == ':' || ch == '%') return true; return false; } static void ColouriseAPDLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { int stringStart = ' '; WordList &processors = *keywordlists[0]; WordList &commands = *keywordlists[1]; WordList &slashcommands = *keywordlists[2]; WordList &starcommands = *keywordlists[3]; WordList &arguments = *keywordlists[4]; WordList &functions = *keywordlists[5]; // Do not leak onto next line initStyle = SCE_APDL_DEFAULT; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { // Determine if the current state should terminate. if (sc.state == SCE_APDL_NUMBER) { if (!(IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') || ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) { sc.SetState(SCE_APDL_DEFAULT); } } else if (sc.state == SCE_APDL_COMMENT) { if (sc.atLineEnd) { sc.SetState(SCE_APDL_DEFAULT); } } else if (sc.state == SCE_APDL_COMMENTBLOCK) { if (sc.atLineEnd) { if (sc.ch == '\r') { sc.Forward(); } sc.ForwardSetState(SCE_APDL_DEFAULT); } } else if (sc.state == SCE_APDL_STRING) { if (sc.atLineEnd) { sc.SetState(SCE_APDL_DEFAULT); } else if ((sc.ch == '\'' && stringStart == '\'') || (sc.ch == '\"' && stringStart == '\"')) { sc.ForwardSetState(SCE_APDL_DEFAULT); } } else if (sc.state == SCE_APDL_WORD) { if (!IsAWordChar(sc.ch)) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (processors.InList(s)) { sc.ChangeState(SCE_APDL_PROCESSOR); } else if (slashcommands.InList(s)) { sc.ChangeState(SCE_APDL_SLASHCOMMAND); } else if (starcommands.InList(s)) { sc.ChangeState(SCE_APDL_STARCOMMAND); } else if (commands.InList(s)) { sc.ChangeState(SCE_APDL_COMMAND); } else if (arguments.InList(s)) { sc.ChangeState(SCE_APDL_ARGUMENT); } else if (functions.InList(s)) { sc.ChangeState(SCE_APDL_FUNCTION); } sc.SetState(SCE_APDL_DEFAULT); } } else if (sc.state == SCE_APDL_OPERATOR) { if (!IsAnOperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_APDL_DEFAULT); } } // Determine if a new state should be entered. if (sc.state == SCE_APDL_DEFAULT) { if (sc.ch == '!' && sc.chNext == '!') { sc.SetState(SCE_APDL_COMMENTBLOCK); } else if (sc.ch == '!') { sc.SetState(SCE_APDL_COMMENT); } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_APDL_NUMBER); } else if (sc.ch == '\'' || sc.ch == '\"') { sc.SetState(SCE_APDL_STRING); stringStart = sc.ch; } else if (IsAWordChar(sc.ch) || ((sc.ch == '*' || sc.ch == '/') && !isgraph(sc.chPrev))) { sc.SetState(SCE_APDL_WORD); } else if (IsAnOperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_APDL_OPERATOR); } } } sc.Complete(); } //------------------------------------------------------------------------------ // 06-27-07 Sergio Lucato // - Included code folding for Ansys APDL lexer // - Copyied from LexBasic.cxx and modified for APDL //------------------------------------------------------------------------------ /* Bits: * 1 - whitespace * 2 - operator * 4 - identifier * 8 - decimal digit * 16 - hex digit * 32 - bin digit */ static int character_classification[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 10, 6, 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4, 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0 }; static bool IsSpace(int c) { return c < 128 && (character_classification[c] & 1); } static bool IsIdentifier(int c) { return c < 128 && (character_classification[c] & 4); } static int LowerCase(int c) { if (c >= 'A' && c <= 'Z') return 'a' + c - 'A'; return c; } static int CheckAPDLFoldPoint(char const *token, int &level) { if (!strcmp(token, "*if") || !strcmp(token, "*do") || !strcmp(token, "*dowhile") ) { level |= SC_FOLDLEVELHEADERFLAG; return 1; } if (!strcmp(token, "*endif") || !strcmp(token, "*enddo") ) { return -1; } return 0; } static void FoldAPDLDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { int line = styler.GetLine(startPos); int level = styler.LevelAt(line); int go = 0, done = 0; int endPos = startPos + length; char word[256]; int wordlen = 0; int i; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; // Scan for tokens at the start of the line (they may include // whitespace, for tokens like "End Function" for (i = startPos; i < endPos; i++) { int c = styler.SafeGetCharAt(i); if (!done && !go) { if (wordlen) { // are we scanning a token already? word[wordlen] = static_cast<char>(LowerCase(c)); if (!IsIdentifier(c)) { // done with token word[wordlen] = '\0'; go = CheckAPDLFoldPoint(word, level); if (!go) { // Treat any whitespace as single blank, for // things like "End Function". if (IsSpace(c) && IsIdentifier(word[wordlen - 1])) { word[wordlen] = ' '; if (wordlen < 255) wordlen++; } else // done with this line done = 1; } } else if (wordlen < 255) { wordlen++; } } else { // start scanning at first non-whitespace character if (!IsSpace(c)) { if (IsIdentifier(c)) { word[0] = static_cast<char>(LowerCase(c)); wordlen = 1; } else // done with this line done = 1; } } } if (c == '\n') { // line end if (!done && wordlen == 0 && foldCompact) // line was only space level |= SC_FOLDLEVELWHITEFLAG; if (level != styler.LevelAt(line)) styler.SetLevel(line, level); level += go; line++; // reset state wordlen = 0; level &= ~SC_FOLDLEVELHEADERFLAG; level &= ~SC_FOLDLEVELWHITEFLAG; go = 0; done = 0; } } } static const char * const apdlWordListDesc[] = { "processors", "commands", "slashommands", "starcommands", "arguments", "functions", 0 }; LexerModule lmAPDL(SCLEX_APDL, ColouriseAPDLDoc, "apdl", FoldAPDLDoc, apdlWordListDesc); |
Added lexers/LexASY.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
// Scintilla source code edit control //Author: instanton (email: soft_share<at>126<dot>com) // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static void ColouriseAsyDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true); int visibleChars = 0; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.atLineStart) { if (sc.state == SCE_ASY_STRING) { sc.SetState(SCE_ASY_STRING); } visibleChars = 0; } if (sc.ch == '\\') { if (sc.chNext == '\n' || sc.chNext == '\r') { sc.Forward(); if (sc.ch == '\r' && sc.chNext == '\n') { sc.Forward(); } // continuationLine = true; continue; } } // Determine if the current state should terminate. switch (sc.state) { case SCE_ASY_OPERATOR: sc.SetState(SCE_ASY_DEFAULT); break; case SCE_ASY_NUMBER: if (!setWord.Contains(sc.ch)) { sc.SetState(SCE_ASY_DEFAULT); } break; case SCE_ASY_IDENTIFIER: if (!setWord.Contains(sc.ch) || (sc.ch == '.')) { char s[1000]; sc.GetCurrentLowered(s, sizeof(s)); if (keywords.InList(s)) { sc.ChangeState(SCE_ASY_WORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_ASY_WORD2); } sc.SetState(SCE_ASY_DEFAULT); } break; case SCE_ASY_COMMENT: if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_ASY_DEFAULT); } break; case SCE_ASY_COMMENTLINE: if (sc.atLineStart) { sc.SetState(SCE_ASY_DEFAULT); } break; case SCE_ASY_STRING: if (sc.atLineEnd) { sc.ChangeState(SCE_ASY_STRINGEOL); } else if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_ASY_DEFAULT); } break; case SCE_ASY_CHARACTER: if (sc.atLineEnd) { sc.ChangeState(SCE_ASY_STRINGEOL); } else if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\'') { sc.ForwardSetState(SCE_ASY_DEFAULT); } break; } // Determine if a new state should be entered. if (sc.state == SCE_ASY_DEFAULT) { if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) { sc.SetState(SCE_ASY_IDENTIFIER); } else if (sc.Match('/', '*')) { sc.SetState(SCE_ASY_COMMENT); sc.Forward(); // } else if (sc.Match('/', '/')) { sc.SetState(SCE_ASY_COMMENTLINE); } else if (sc.ch == '\"') { sc.SetState(SCE_ASY_STRING); } else if (sc.ch == '\'') { sc.SetState(SCE_ASY_CHARACTER); } else if (sc.ch == '#' && visibleChars == 0) { do { sc.Forward(); } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More()); if (sc.atLineEnd) { sc.SetState(SCE_ASY_DEFAULT); } } else if (isoperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_ASY_OPERATOR); } } } sc.Complete(); } static bool IsAsyCommentStyle(int style) { return style == SCE_ASY_COMMENT; } static inline bool isASYidentifier(int ch) { return ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) ; } static int ParseASYWord(unsigned int pos, Accessor &styler, char *word) { int length=0; char ch=styler.SafeGetCharAt(pos); *word=0; while(isASYidentifier(ch) && length<100){ word[length]=ch; length++; ch=styler.SafeGetCharAt(pos+length); } word[length]=0; return length; } static bool IsASYDrawingLine(int line, Accessor &styler) { int pos = styler.LineStart(line); int eol_pos = styler.LineStart(line + 1) - 1; int startpos = pos; char buffer[100]=""; while (startpos<eol_pos){ char ch = styler[startpos]; ParseASYWord(startpos,styler,buffer); bool drawcommands = strncmp(buffer,"draw",4)==0|| strncmp(buffer,"pair",4)==0||strncmp(buffer,"label",5)==0; if (!drawcommands && ch!=' ') return false; else if (drawcommands) return true; startpos++; } return false; } static void FoldAsyDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelMinCurrent = levelCurrent; int levelNext = levelCurrent; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment && IsAsyCommentStyle(style)) { if (!IsAsyCommentStyle(stylePrev) && (stylePrev != SCE_ASY_COMMENTLINEDOC)) { levelNext++; } else if (!IsAsyCommentStyle(styleNext) && (styleNext != SCE_ASY_COMMENTLINEDOC) && !atEOL) { levelNext--; } } if (style == SCE_ASY_OPERATOR) { if (ch == '{') { if (levelMinCurrent > levelNext) { levelMinCurrent = levelNext; } levelNext++; } else if (ch == '}') { levelNext--; } } if (atEOL && IsASYDrawingLine(lineCurrent, styler)){ if (lineCurrent==0 && IsASYDrawingLine(lineCurrent + 1, styler)) levelNext++; else if (lineCurrent!=0 && !IsASYDrawingLine(lineCurrent - 1, styler) && IsASYDrawingLine(lineCurrent + 1, styler) ) levelNext++; else if (lineCurrent!=0 && IsASYDrawingLine(lineCurrent - 1, styler) && !IsASYDrawingLine(lineCurrent+1, styler)) levelNext--; } if (atEOL) { int levelUse = levelCurrent; if (foldAtElse) { levelUse = levelMinCurrent; } int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelCurrent = levelNext; levelMinCurrent = levelCurrent; visibleChars = 0; } if (!IsASpace(ch)) visibleChars++; } } static const char * const asyWordLists[] = { "Primary keywords and identifiers", "Secondary keywords and identifiers", 0, }; LexerModule lmASY(SCLEX_ASYMPTOTE, ColouriseAsyDoc, "asy", FoldAsyDoc, asyWordLists); |
Added lexers/LexAU3.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 |
// Scintilla source code edit control // @file LexAU3.cxx // Lexer for AutoIt3 http://www.hiddensoft.com/autoit3 // by Jos van der Zande, jvdzande@yahoo.com // // Changes: // March 28, 2004 - Added the standard Folding code // April 21, 2004 - Added Preprosessor Table + Syntax Highlighting // Fixed Number highlighting // Changed default isoperator to IsAOperator to have a better match to AutoIt3 // Fixed "#comments_start" -> "#comments-start" // Fixed "#comments_end" -> "#comments-end" // Fixed Sendkeys in Strings when not terminated with } // Added support for Sendkey strings that have second parameter e.g. {UP 5} or {a down} // April 26, 2004 - Fixed # pre-processor statement inside of comment block would invalidly change the color. // Added logic for #include <xyz.au3> to treat the <> as string // Added underscore to IsAOperator. // May 17, 2004 - Changed the folding logic from indent to keyword folding. // Added Folding logic for blocks of single-commentlines or commentblock. // triggered by: fold.comment=1 // Added Folding logic for preprocessor blocks triggered by fold.preprocessor=1 // Added Special for #region - #endregion syntax highlight and folding. // May 30, 2004 - Fixed issue with continuation lines on If statements. // June 5, 2004 - Added comma to Operators for better readability. // Added fold.compact support set with fold.compact=1 // Changed folding inside of #cs-#ce. Default is no keyword folding inside comment blocks when fold.comment=1 // it will now only happen when fold.comment=2. // Sep 5, 2004 - Added logic to handle colourizing words on the last line. // Typed Characters now show as "default" till they match any table. // Oct 10, 2004 - Added logic to show Comments in "Special" directives. // Nov 1, 2004 - Added better testing for Numbers supporting x and e notation. // Nov 28, 2004 - Added logic to handle continuation lines for syntax highlighting. // Jan 10, 2005 - Added Abbreviations Keyword used for expansion // Mar 24, 2005 - Updated Abbreviations Keywords to fix when followed by Operator. // Apr 18, 2005 - Updated #CE/#Comment-End logic to take a linecomment ";" into account // - Added folding support for With...EndWith // - Added support for a DOT in variable names // - Fixed Underscore in CommentBlock // May 23, 2005 - Fixed the SentKey lexing in case of a missing } // Aug 11, 2005 - Fixed possible bug with s_save length > 100. // Aug 23, 2005 - Added Switch/endswitch support to the folding logic. // Sep 27, 2005 - Fixed the SentKey lexing logic in case of multiple sentkeys. // Mar 12, 2006 - Fixed issue with <> coloring as String in stead of Operator in rare occasions. // Apr 8, 2006 - Added support for AutoIt3 Standard UDF library (SCE_AU3_UDF) // Mar 9, 2007 - Fixed bug with + following a String getting the wrong Color. // Jun 20, 2007 - Fixed Commentblock issue when LF's are used as EOL. // Jul 26, 2007 - Fixed #endregion undetected bug. // // Copyright for Scintilla: 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. // Scintilla source code edit control #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsTypeCharacter(const int ch) { return ch == '$'; } static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_'); } static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '@' || ch == '#' || ch == '$' || ch == '.'); } static inline bool IsAOperator(char ch) { if (isascii(ch) && isalnum(ch)) return false; if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '&' || ch == '^' || ch == '=' || ch == '<' || ch == '>' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == ',' ) return true; return false; } /////////////////////////////////////////////////////////////////////////////// // GetSendKey() filters the portion before and after a/multiple space(s) // and return the first portion to be looked-up in the table // also check if the second portion is valid... (up,down.on.off,toggle or a number) /////////////////////////////////////////////////////////////////////////////// static int GetSendKey(const char *szLine, char *szKey) { int nFlag = 0; int nStartFound = 0; int nKeyPos = 0; int nSpecPos= 0; int nSpecNum= 1; int nPos = 0; char cTemp; char szSpecial[100]; // split the portion of the sendkey in the part before and after the spaces while ( ( (cTemp = szLine[nPos]) != '\0')) { // skip leading Ctrl/Shift/Alt state if (cTemp == '{') { nStartFound = 1; } // if (nStartFound == 1) { if ((cTemp == ' ') && (nFlag == 0) ) // get the stuff till first space { nFlag = 1; // Add } to the end of the first bit for table lookup later. szKey[nKeyPos++] = '}'; } else if (cTemp == ' ') { // skip other spaces } else if (nFlag == 0) { // save first portion into var till space or } is hit szKey[nKeyPos++] = cTemp; } else if ((nFlag == 1) && (cTemp != '}')) { // Save second portion into var... szSpecial[nSpecPos++] = cTemp; // check if Second portion is all numbers for repeat fuction if (isdigit(cTemp) == false) {nSpecNum = 0;} } } nPos++; // skip to next char } // End While // Check if the second portion is either a number or one of these keywords szKey[nKeyPos] = '\0'; szSpecial[nSpecPos] = '\0'; if (strcmp(szSpecial,"down")== 0 || strcmp(szSpecial,"up")== 0 || strcmp(szSpecial,"on")== 0 || strcmp(szSpecial,"off")== 0 || strcmp(szSpecial,"toggle")== 0 || nSpecNum == 1 ) { nFlag = 0; } else { nFlag = 1; } return nFlag; // 1 is bad, 0 is good } // GetSendKey() // // Routine to check the last "none comment" character on a line to see if its a continuation // static bool IsContinuationLine(unsigned int szLine, Accessor &styler) { int nsPos = styler.LineStart(szLine); int nePos = styler.LineStart(szLine+1) - 2; //int stylech = styler.StyleAt(nsPos); while (nsPos < nePos) { //stylech = styler.StyleAt(nePos); int stylech = styler.StyleAt(nsPos); if (!(stylech == SCE_AU3_COMMENT)) { char ch = styler.SafeGetCharAt(nePos); if (!isspacechar(ch)) { if (ch == '_') return true; else return false; } } nePos--; // skip to next char } // End While return false; } // IsContinuationLine() // // syntax highlighting logic static void ColouriseAU3Doc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; WordList &keywords5 = *keywordlists[4]; WordList &keywords6 = *keywordlists[5]; WordList &keywords7 = *keywordlists[6]; WordList &keywords8 = *keywordlists[7]; // find the first previous line without continuation character at the end int lineCurrent = styler.GetLine(startPos); int s_startPos = startPos; // When not inside a Block comment: find First line without _ if (!(initStyle==SCE_AU3_COMMENTBLOCK)) { while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) || (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) { lineCurrent--; startPos = styler.LineStart(lineCurrent); // get start position initStyle = 0; // reset the start style to 0 } } // Set the new length to include it from the start and set the start position length = length + s_startPos - startPos; // correct the total length to process styler.StartAt(startPos); StyleContext sc(startPos, length, initStyle, styler); char si; // string indicator "=1 '=2 char ni; // Numeric indicator error=9 normal=0 normal+dec=1 hex=2 Enot=3 char ci; // comment indicator 0=not linecomment(;) char s_save[100]; si=0; ni=0; ci=0; //$$$ for (; sc.More(); sc.Forward()) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); // ********************************************** // save the total current word for eof processing if (IsAWordChar(sc.ch) || sc.ch == '}') { strcpy(s_save,s); int tp = static_cast<int>(strlen(s_save)); if (tp < 99) { s_save[tp] = static_cast<char>(tolower(sc.ch)); s_save[tp+1] = '\0'; } } // ********************************************** // switch (sc.state) { case SCE_AU3_COMMENTBLOCK: { //Reset at line end if (sc.atLineEnd) { ci=0; if (strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0) { if (sc.atLineEnd) sc.SetState(SCE_AU3_DEFAULT); else sc.SetState(SCE_AU3_COMMENTBLOCK); } break; } //skip rest of line when a ; is encountered if (sc.chPrev == ';') { ci=2; sc.SetState(SCE_AU3_COMMENTBLOCK); } // skip rest of the line if (ci==2) break; // check when first character is detected on the line if (ci==0) { if (IsAWordStart(static_cast<char>(sc.ch)) || IsAOperator(static_cast<char>(sc.ch))) { ci=1; sc.SetState(SCE_AU3_COMMENTBLOCK); } break; } if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && strcmp(s, "#comments") == 0))) { if ((strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0)) sc.SetState(SCE_AU3_COMMENT); // set to comment line for the rest of the line else ci=2; // line doesn't begin with #CE so skip the rest of the line } break; } case SCE_AU3_COMMENT: { if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);} break; } case SCE_AU3_OPERATOR: { // check if its a COMobject if (sc.chPrev == '.' && IsAWordChar(sc.ch)) { sc.SetState(SCE_AU3_COMOBJ); } else { sc.SetState(SCE_AU3_DEFAULT); } break; } case SCE_AU3_SPECIAL: { if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);} if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);} break; } case SCE_AU3_KEYWORD: { if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && (strcmp(s, "#comments") == 0 || strcmp(s, "#include") == 0)))) { if (!IsTypeCharacter(sc.ch)) { if (strcmp(s, "#cs")== 0 || strcmp(s, "#comments-start")== 0 ) { sc.ChangeState(SCE_AU3_COMMENTBLOCK); sc.SetState(SCE_AU3_COMMENTBLOCK); break; } else if (keywords.InList(s)) { sc.ChangeState(SCE_AU3_KEYWORD); sc.SetState(SCE_AU3_DEFAULT); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_AU3_FUNCTION); sc.SetState(SCE_AU3_DEFAULT); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_AU3_MACRO); sc.SetState(SCE_AU3_DEFAULT); } else if (keywords5.InList(s)) { sc.ChangeState(SCE_AU3_PREPROCESSOR); sc.SetState(SCE_AU3_DEFAULT); if (strcmp(s, "#include")== 0) { si = 3; // use to determine string start for #inlude <> } } else if (keywords6.InList(s)) { sc.ChangeState(SCE_AU3_SPECIAL); sc.SetState(SCE_AU3_SPECIAL); } else if ((keywords7.InList(s)) && (!IsAOperator(static_cast<char>(sc.ch)))) { sc.ChangeState(SCE_AU3_EXPAND); sc.SetState(SCE_AU3_DEFAULT); } else if (keywords8.InList(s)) { sc.ChangeState(SCE_AU3_UDF); sc.SetState(SCE_AU3_DEFAULT); } else if (strcmp(s, "_") == 0) { sc.ChangeState(SCE_AU3_OPERATOR); sc.SetState(SCE_AU3_DEFAULT); } else if (!IsAWordChar(sc.ch)) { sc.ChangeState(SCE_AU3_DEFAULT); sc.SetState(SCE_AU3_DEFAULT); } } } if (sc.atLineEnd) { sc.SetState(SCE_AU3_DEFAULT);} break; } case SCE_AU3_NUMBER: { // Numeric indicator error=9 normal=0 normal+dec=1 hex=2 E-not=3 // // test for Hex notation if (strcmp(s, "0") == 0 && (sc.ch == 'x' || sc.ch == 'X') && ni == 0) { ni = 2; break; } // test for E notation if (IsADigit(sc.chPrev) && (sc.ch == 'e' || sc.ch == 'E') && ni <= 1) { ni = 3; break; } // Allow Hex characters inside hex numeric strings if ((ni == 2) && (sc.ch == 'a' || sc.ch == 'b' || sc.ch == 'c' || sc.ch == 'd' || sc.ch == 'e' || sc.ch == 'f' || sc.ch == 'A' || sc.ch == 'B' || sc.ch == 'C' || sc.ch == 'D' || sc.ch == 'E' || sc.ch == 'F' )) { break; } // test for 1 dec point only if (sc.ch == '.') { if (ni==0) { ni=1; } else { ni=9; } break; } // end of numeric string ? if (!(IsADigit(sc.ch))) { if (ni==9) { sc.ChangeState(SCE_AU3_DEFAULT); } sc.SetState(SCE_AU3_DEFAULT); } break; } case SCE_AU3_VARIABLE: { // Check if its a COMObject if (sc.ch == '.' && !IsADigit(sc.chNext)) { sc.SetState(SCE_AU3_OPERATOR); } else if (!IsAWordChar(sc.ch)) { sc.SetState(SCE_AU3_DEFAULT); } break; } case SCE_AU3_COMOBJ: { if (!(IsAWordChar(sc.ch))) { sc.SetState(SCE_AU3_DEFAULT); } break; } case SCE_AU3_STRING: { // check for " to end a double qouted string or // check for ' to end a single qouted string if ((si == 1 && sc.ch == '\"') || (si == 2 && sc.ch == '\'') || (si == 3 && sc.ch == '>')) { sc.ForwardSetState(SCE_AU3_DEFAULT); si=0; break; } if (sc.atLineEnd) { si=0; // at line end and not found a continuation char then reset to default int lineCurrent = styler.GetLine(sc.currentPos); if (!IsContinuationLine(lineCurrent,styler)) { sc.SetState(SCE_AU3_DEFAULT); break; } } // find Sendkeys in a STRING if (sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' ) { sc.SetState(SCE_AU3_SENT);} break; } case SCE_AU3_SENT: { // Send key string ended if (sc.chPrev == '}' && sc.ch != '}') { // set color to SENDKEY when valid sendkey .. else set back to regular string char sk[100]; // split {111 222} and return {111} and check if 222 is valid. // if return code = 1 then invalid 222 so must be string if (GetSendKey(s,sk)) { sc.ChangeState(SCE_AU3_STRING); } // if single char between {?} then its ok as sendkey for a single character else if (strlen(sk) == 3) { sc.ChangeState(SCE_AU3_SENT); } // if sendkey {111} is in table then ok as sendkey else if (keywords4.InList(sk)) { sc.ChangeState(SCE_AU3_SENT); } else { sc.ChangeState(SCE_AU3_STRING); } sc.SetState(SCE_AU3_STRING); } else { // check if the start is a valid SendKey start int nPos = 0; int nState = 1; char cTemp; while (!(nState == 2) && ((cTemp = s[nPos]) != '\0')) { if (cTemp == '{' && nState == 1) { nState = 2; } if (nState == 1 && !(cTemp == '+' || cTemp == '!' || cTemp == '^' || cTemp == '#' )) { nState = 0; } nPos++; } //Verify characters infront of { ... if not assume regular string if (nState == 1 && (!(sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' ))) { sc.ChangeState(SCE_AU3_STRING); sc.SetState(SCE_AU3_STRING); } // If invalid character found then assume its a regular string if (nState == 0) { sc.ChangeState(SCE_AU3_STRING); sc.SetState(SCE_AU3_STRING); } } // check if next portion is again a sendkey if (sc.atLineEnd) { sc.ChangeState(SCE_AU3_STRING); sc.SetState(SCE_AU3_DEFAULT); si = 0; // reset string indicator } //* check in next characters following a sentkey are again a sent key // Need this test incase of 2 sentkeys like {F1}{ENTER} but not detect {{} if (sc.state == SCE_AU3_STRING && (sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' )) { sc.SetState(SCE_AU3_SENT);} // check to see if the string ended... // Sendkey string isn't complete but the string ended.... if ((si == 1 && sc.ch == '\"') || (si == 2 && sc.ch == '\'')) { sc.ChangeState(SCE_AU3_STRING); sc.ForwardSetState(SCE_AU3_DEFAULT); } break; } } //switch (sc.state) // Determine if a new state should be entered: if (sc.state == SCE_AU3_DEFAULT) { if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);} else if (sc.ch == '#') {sc.SetState(SCE_AU3_KEYWORD);} else if (sc.ch == '$') {sc.SetState(SCE_AU3_VARIABLE);} else if (sc.ch == '.' && !IsADigit(sc.chNext)) {sc.SetState(SCE_AU3_OPERATOR);} else if (sc.ch == '@') {sc.SetState(SCE_AU3_KEYWORD);} //else if (sc.ch == '_') {sc.SetState(SCE_AU3_KEYWORD);} else if (sc.ch == '<' && si==3) {sc.SetState(SCE_AU3_STRING);} // string after #include else if (sc.ch == '\"') { sc.SetState(SCE_AU3_STRING); si = 1; } else if (sc.ch == '\'') { sc.SetState(SCE_AU3_STRING); si = 2; } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_AU3_NUMBER); ni = 0; } else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_AU3_KEYWORD);} else if (IsAOperator(static_cast<char>(sc.ch))) {sc.SetState(SCE_AU3_OPERATOR);} else if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);} } } //for (; sc.More(); sc.Forward()) //************************************* // Colourize the last word correctly //************************************* if (sc.state == SCE_AU3_KEYWORD) { if (strcmp(s_save, "#cs")== 0 || strcmp(s_save, "#comments-start")== 0 ) { sc.ChangeState(SCE_AU3_COMMENTBLOCK); sc.SetState(SCE_AU3_COMMENTBLOCK); } else if (keywords.InList(s_save)) { sc.ChangeState(SCE_AU3_KEYWORD); sc.SetState(SCE_AU3_KEYWORD); } else if (keywords2.InList(s_save)) { sc.ChangeState(SCE_AU3_FUNCTION); sc.SetState(SCE_AU3_FUNCTION); } else if (keywords3.InList(s_save)) { sc.ChangeState(SCE_AU3_MACRO); sc.SetState(SCE_AU3_MACRO); } else if (keywords5.InList(s_save)) { sc.ChangeState(SCE_AU3_PREPROCESSOR); sc.SetState(SCE_AU3_PREPROCESSOR); } else if (keywords6.InList(s_save)) { sc.ChangeState(SCE_AU3_SPECIAL); sc.SetState(SCE_AU3_SPECIAL); } else if (keywords7.InList(s_save) && sc.atLineEnd) { sc.ChangeState(SCE_AU3_EXPAND); sc.SetState(SCE_AU3_EXPAND); } else if (keywords8.InList(s_save)) { sc.ChangeState(SCE_AU3_UDF); sc.SetState(SCE_AU3_UDF); } else { sc.ChangeState(SCE_AU3_DEFAULT); sc.SetState(SCE_AU3_DEFAULT); } } if (sc.state == SCE_AU3_SENT) { // Send key string ended if (sc.chPrev == '}' && sc.ch != '}') { // set color to SENDKEY when valid sendkey .. else set back to regular string char sk[100]; // split {111 222} and return {111} and check if 222 is valid. // if return code = 1 then invalid 222 so must be string if (GetSendKey(s_save,sk)) { sc.ChangeState(SCE_AU3_STRING); } // if single char between {?} then its ok as sendkey for a single character else if (strlen(sk) == 3) { sc.ChangeState(SCE_AU3_SENT); } // if sendkey {111} is in table then ok as sendkey else if (keywords4.InList(sk)) { sc.ChangeState(SCE_AU3_SENT); } else { sc.ChangeState(SCE_AU3_STRING); } sc.SetState(SCE_AU3_STRING); } // check if next portion is again a sendkey if (sc.atLineEnd) { sc.ChangeState(SCE_AU3_STRING); sc.SetState(SCE_AU3_DEFAULT); } } //************************************* sc.Complete(); } // static bool IsStreamCommentStyle(int style) { return style == SCE_AU3_COMMENT || style == SCE_AU3_COMMENTBLOCK; } // // Routine to find first none space on the current line and return its Style // needed for comment lines not starting on pos 1 static int GetStyleFirstWord(unsigned int szLine, Accessor &styler) { int nsPos = styler.LineStart(szLine); int nePos = styler.LineStart(szLine+1) - 1; while (isspacechar(styler.SafeGetCharAt(nsPos)) && nsPos < nePos) { nsPos++; // skip to next char } // End While return styler.StyleAt(nsPos); } // GetStyleFirstWord() // static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { int endPos = startPos + length; // get settings from the config files for folding comments and preprocessor lines bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldInComment = styler.GetPropertyInt("fold.comment") == 2; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldpreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0; // Backtrack to previous line in case need to fix its fold status int lineCurrent = styler.GetLine(startPos); if (startPos > 0) { if (lineCurrent > 0) { lineCurrent--; startPos = styler.LineStart(lineCurrent); } } // vars for style of previous/current/next lines int style = GetStyleFirstWord(lineCurrent,styler); int stylePrev = 0; // find the first previous line without continuation character at the end while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) || (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) { lineCurrent--; startPos = styler.LineStart(lineCurrent); } if (lineCurrent > 0) { stylePrev = GetStyleFirstWord(lineCurrent-1,styler); } // vars for getting first word to check for keywords bool FirstWordStart = false; bool FirstWordEnd = false; char szKeyword[11]=""; int szKeywordlen = 0; char szThen[5]=""; int szThenlen = 0; bool ThenFoundLast = false; // var for indentlevel int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelNext = levelCurrent; // int visibleChars = 0; char chNext = styler.SafeGetCharAt(startPos); char chPrev = ' '; // for (int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if (IsAWordChar(ch)) { visibleChars++; } // get the syle for the current character neede to check in comment int stylech = styler.StyleAt(i); // get first word for the line for indent check max 9 characters if (FirstWordStart && (!(FirstWordEnd))) { if (!IsAWordChar(ch)) { FirstWordEnd = true; szKeyword[szKeywordlen] = '\0'; } else { if (szKeywordlen < 10) { szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch)); } } } // start the capture of the first word if (!(FirstWordStart)) { if (IsAWordChar(ch) || IsAWordStart(ch) || ch == ';') { FirstWordStart = true; szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch)); } } // only process this logic when not in comment section if (!(stylech == SCE_AU3_COMMENT)) { if (ThenFoundLast) { if (IsAWordChar(ch)) { ThenFoundLast = false; } } // find out if the word "then" is the last on a "if" line if (FirstWordEnd && strcmp(szKeyword,"if") == 0) { if (szThenlen == 4) { szThen[0] = szThen[1]; szThen[1] = szThen[2]; szThen[2] = szThen[3]; szThen[3] = static_cast<char>(tolower(ch)); if (strcmp(szThen,"then") == 0 ) { ThenFoundLast = true; } } else { szThen[szThenlen++] = static_cast<char>(tolower(ch)); if (szThenlen == 5) { szThen[4] = '\0'; } } } } // End of Line found so process the information if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) { // ************************** // Folding logic for Keywords // ************************** // if a keyword is found on the current line and the line doesn't end with _ (continuation) // and we are not inside a commentblock. if (szKeywordlen > 0 && (!(chPrev == '_')) && ((!(IsStreamCommentStyle(style)) || foldInComment)) ) { szKeyword[szKeywordlen] = '\0'; // only fold "if" last keyword is "then" (else its a one line if) if (strcmp(szKeyword,"if") == 0 && ThenFoundLast) { levelNext++; } // create new fold for these words if (strcmp(szKeyword,"do") == 0 || strcmp(szKeyword,"for") == 0 || strcmp(szKeyword,"func") == 0 || strcmp(szKeyword,"while") == 0|| strcmp(szKeyword,"with") == 0 || strcmp(szKeyword,"#region") == 0 ) { levelNext++; } // create double Fold for select&switch because Case will subtract one of the current level if (strcmp(szKeyword,"select") == 0 || strcmp(szKeyword,"switch") == 0) { levelNext++; levelNext++; } // end the fold for these words before the current line if (strcmp(szKeyword,"endfunc") == 0 || strcmp(szKeyword,"endif") == 0 || strcmp(szKeyword,"next") == 0 || strcmp(szKeyword,"until") == 0 || strcmp(szKeyword,"endwith") == 0 ||strcmp(szKeyword,"wend") == 0){ levelNext--; levelCurrent--; } // end the fold for these words before the current line and Start new fold if (strcmp(szKeyword,"case") == 0 || strcmp(szKeyword,"else") == 0 || strcmp(szKeyword,"elseif") == 0 ) { levelCurrent--; } // end the double fold for this word before the current line if (strcmp(szKeyword,"endselect") == 0 || strcmp(szKeyword,"endswitch") == 0 ) { levelNext--; levelNext--; levelCurrent--; levelCurrent--; } // end the fold for these words on the current line if (strcmp(szKeyword,"#endregion") == 0 ) { levelNext--; } } // Preprocessor and Comment folding int styleNext = GetStyleFirstWord(lineCurrent + 1,styler); // ************************************* // Folding logic for preprocessor blocks // ************************************* // process preprosessor line if (foldpreprocessor && style == SCE_AU3_PREPROCESSOR) { if (!(stylePrev == SCE_AU3_PREPROCESSOR) && (styleNext == SCE_AU3_PREPROCESSOR)) { levelNext++; } // fold till the last line for normal comment lines else if (stylePrev == SCE_AU3_PREPROCESSOR && !(styleNext == SCE_AU3_PREPROCESSOR)) { levelNext--; } } // ********************************* // Folding logic for Comment blocks // ********************************* if (foldComment && IsStreamCommentStyle(style)) { // Start of a comment block if (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) { levelNext++; } // fold till the last line for normal comment lines else if (IsStreamCommentStyle(stylePrev) && !(styleNext == SCE_AU3_COMMENT) && stylePrev == SCE_AU3_COMMENT && style == SCE_AU3_COMMENT) { levelNext--; } // fold till the one but last line for Blockcomment lines else if (IsStreamCommentStyle(stylePrev) && !(styleNext == SCE_AU3_COMMENTBLOCK) && style == SCE_AU3_COMMENTBLOCK) { levelNext--; levelCurrent--; } } int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) { lev |= SC_FOLDLEVELHEADERFLAG; } if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } // reset values for the next line lineCurrent++; stylePrev = style; style = styleNext; levelCurrent = levelNext; visibleChars = 0; // if the last character is an Underscore then don't reset since the line continues on the next line. if (!(chPrev == '_')) { szKeywordlen = 0; szThenlen = 0; FirstWordStart = false; FirstWordEnd = false; ThenFoundLast = false; } } // save the last processed character if (!isspacechar(ch)) { chPrev = ch; visibleChars++; } } } // static const char * const AU3WordLists[] = { "#autoit keywords", "#autoit functions", "#autoit macros", "#autoit Sent keys", "#autoit Pre-processors", "#autoit Special", "#autoit Expand", "#autoit UDF", 0 }; LexerModule lmAU3(SCLEX_AU3, ColouriseAU3Doc, "au3", FoldAU3Doc , AU3WordLists); |
Added lexers/LexAVE.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
// SciTE - Scintilla based Text Editor /** @file LexAVE.cxx ** Lexer for Avenue. ** ** Written by Alexey Yutkin <yutkin@geol.msu.ru>. **/ // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_'); } static inline bool IsEnumChar(const int ch) { return (ch < 0x80) && (isalnum(ch)|| ch == '_'); } static inline bool IsANumberChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' ); } inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_'); } inline bool isAveOperator(char ch) { if (isascii(ch) && isalnum(ch)) return false; // '.' left out as it is used to make up numbers if (ch == '*' || ch == '/' || ch == '-' || ch == '+' || ch == '(' || ch == ')' || ch == '=' || ch == '{' || ch == '}' || ch == '[' || ch == ']' || ch == ';' || ch == '<' || ch == '>' || ch == ',' || ch == '.' ) return true; return false; } static void ColouriseAveDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; WordList &keywords5 = *keywordlists[4]; WordList &keywords6 = *keywordlists[5]; // Do not leak onto next line if (initStyle == SCE_AVE_STRINGEOL) { initStyle = SCE_AVE_DEFAULT; } StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.atLineEnd) { // Update the line state, so it can be seen by next line int currentLine = styler.GetLine(sc.currentPos); styler.SetLineState(currentLine, 0); } if (sc.atLineStart && (sc.state == SCE_AVE_STRING)) { // Prevent SCE_AVE_STRINGEOL from leaking back to previous line sc.SetState(SCE_AVE_STRING); } // Determine if the current state should terminate. if (sc.state == SCE_AVE_OPERATOR) { sc.SetState(SCE_AVE_DEFAULT); } else if (sc.state == SCE_AVE_NUMBER) { if (!IsANumberChar(sc.ch)) { sc.SetState(SCE_AVE_DEFAULT); } } else if (sc.state == SCE_AVE_ENUM) { if (!IsEnumChar(sc.ch)) { sc.SetState(SCE_AVE_DEFAULT); } } else if (sc.state == SCE_AVE_IDENTIFIER) { if (!IsAWordChar(sc.ch) || (sc.ch == '.')) { char s[100]; //sc.GetCurrent(s, sizeof(s)); sc.GetCurrentLowered(s, sizeof(s)); if (keywords.InList(s)) { sc.ChangeState(SCE_AVE_WORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_AVE_WORD2); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_AVE_WORD3); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_AVE_WORD4); } else if (keywords5.InList(s)) { sc.ChangeState(SCE_AVE_WORD5); } else if (keywords6.InList(s)) { sc.ChangeState(SCE_AVE_WORD6); } sc.SetState(SCE_AVE_DEFAULT); } } else if (sc.state == SCE_AVE_COMMENT) { if (sc.atLineEnd) { sc.SetState(SCE_AVE_DEFAULT); } } else if (sc.state == SCE_AVE_STRING) { if (sc.ch == '\"') { sc.ForwardSetState(SCE_AVE_DEFAULT); } else if (sc.atLineEnd) { sc.ChangeState(SCE_AVE_STRINGEOL); sc.ForwardSetState(SCE_AVE_DEFAULT); } } // Determine if a new state should be entered. if (sc.state == SCE_AVE_DEFAULT) { if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_AVE_NUMBER); } else if (IsAWordStart(sc.ch)) { sc.SetState(SCE_AVE_IDENTIFIER); } else if (sc.Match('\"')) { sc.SetState(SCE_AVE_STRING); } else if (sc.Match('\'')) { sc.SetState(SCE_AVE_COMMENT); sc.Forward(); } else if (isAveOperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_AVE_OPERATOR); } else if (sc.Match('#')) { sc.SetState(SCE_AVE_ENUM); sc.Forward(); } } } sc.Complete(); } static void FoldAveDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[], Accessor &styler) { unsigned int lengthDoc = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = static_cast<char>(tolower(styler[startPos])); bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; int styleNext = styler.StyleAt(startPos); char s[10]; for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = static_cast<char>(tolower(chNext)); chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1))); int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (style == SCE_AVE_WORD) { if (ch == 't' || ch == 'f' || ch == 'w' || ch == 'e') { for (unsigned int j = 0; j < 6; j++) { if (!iswordchar(styler[i + j])) { break; } s[j] = static_cast<char>(tolower(styler[i + j])); s[j + 1] = '\0'; } if ((strcmp(s, "then") == 0) || (strcmp(s, "for") == 0) || (strcmp(s, "while") == 0)) { levelCurrent++; } if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0)) { // Normally "elseif" and "then" will be on the same line and will cancel // each other out. // As implemented, this does not support fold.at.else. levelCurrent--; } } } else if (style == SCE_AVE_OPERATOR) { if (ch == '{' || ch == '(') { levelCurrent++; } else if (ch == '}' || ch == ')') { levelCurrent--; } } if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) { lev |= SC_FOLDLEVELWHITEFLAG; } if ((levelCurrent > levelPrev) && (visibleChars > 0)) { lev |= SC_FOLDLEVELHEADERFLAG; } if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) { visibleChars++; } } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } LexerModule lmAVE(SCLEX_AVE, ColouriseAveDoc, "ave", FoldAveDoc); |
Added lexers/LexAVS.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
// Scintilla source code edit control /** @file LexAVS.cxx ** Lexer for AviSynth. **/ // Copyright 2012 by Bruno Barbieri <brunorex@gmail.com> // Heavily based on LexPOV by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_'); } static inline bool IsAWordStart(int ch) { return isalpha(ch) || (ch != ' ' && ch != '\n' && ch != '(' && ch != '.' && ch != ','); } static inline bool IsANumberChar(int ch) { // Not exactly following number definition (several dots are seen as OK, etc.) // but probably enough in most cases. return (ch < 0x80) && (isdigit(ch) || ch == '.' || ch == '-' || ch == '+'); } static void ColouriseAvsDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &filters = *keywordlists[1]; WordList &plugins = *keywordlists[2]; WordList &functions = *keywordlists[3]; WordList &clipProperties = *keywordlists[4]; WordList &userDefined = *keywordlists[5]; int currentLine = styler.GetLine(startPos); // Initialize the block comment nesting level, if we are inside such a comment. int blockCommentLevel = 0; if (initStyle == SCE_AVS_COMMENTBLOCK || initStyle == SCE_AVS_COMMENTBLOCKN) { blockCommentLevel = styler.GetLineState(currentLine - 1); } // Do not leak onto next line if (initStyle == SCE_AVS_COMMENTLINE) { initStyle = SCE_AVS_DEFAULT; } StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.atLineEnd) { // Update the line state, so it can be seen by next line currentLine = styler.GetLine(sc.currentPos); if (sc.state == SCE_AVS_COMMENTBLOCK || sc.state == SCE_AVS_COMMENTBLOCKN) { // Inside a block comment, we set the line state styler.SetLineState(currentLine, blockCommentLevel); } else { // Reset the line state styler.SetLineState(currentLine, 0); } } // Determine if the current state should terminate. if (sc.state == SCE_AVS_OPERATOR) { sc.SetState(SCE_AVS_DEFAULT); } else if (sc.state == SCE_AVS_NUMBER) { // We stop the number definition on non-numerical non-dot non-sign char if (!IsANumberChar(sc.ch)) { sc.SetState(SCE_AVS_DEFAULT); } } else if (sc.state == SCE_AVS_IDENTIFIER) { if (!IsAWordChar(sc.ch)) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (keywords.InList(s)) { sc.ChangeState(SCE_AVS_KEYWORD); } else if (filters.InList(s)) { sc.ChangeState(SCE_AVS_FILTER); } else if (plugins.InList(s)) { sc.ChangeState(SCE_AVS_PLUGIN); } else if (functions.InList(s)) { sc.ChangeState(SCE_AVS_FUNCTION); } else if (clipProperties.InList(s)) { sc.ChangeState(SCE_AVS_CLIPPROP); } else if (userDefined.InList(s)) { sc.ChangeState(SCE_AVS_USERDFN); } sc.SetState(SCE_AVS_DEFAULT); } } else if (sc.state == SCE_AVS_COMMENTBLOCK) { if (sc.Match('/', '*')) { blockCommentLevel++; sc.Forward(); } else if (sc.Match('*', '/') && blockCommentLevel > 0) { blockCommentLevel--; sc.Forward(); if (blockCommentLevel == 0) { sc.ForwardSetState(SCE_AVS_DEFAULT); } } } else if (sc.state == SCE_AVS_COMMENTBLOCKN) { if (sc.Match('[', '*')) { blockCommentLevel++; sc.Forward(); } else if (sc.Match('*', ']') && blockCommentLevel > 0) { blockCommentLevel--; sc.Forward(); if (blockCommentLevel == 0) { sc.ForwardSetState(SCE_AVS_DEFAULT); } } } else if (sc.state == SCE_AVS_COMMENTLINE) { if (sc.atLineEnd) { sc.ForwardSetState(SCE_AVS_DEFAULT); } } else if (sc.state == SCE_AVS_STRING) { if (sc.ch == '\"') { sc.ForwardSetState(SCE_AVS_DEFAULT); } } else if (sc.state == SCE_AVS_TRIPLESTRING) { if (sc.Match("\"\"\"")) { sc.Forward(); sc.Forward(); sc.ForwardSetState(SCE_AVS_DEFAULT); } } // Determine if a new state should be entered. if (sc.state == SCE_AVS_DEFAULT) { if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_AVS_NUMBER); } else if (IsADigit(sc.ch) || (sc.ch == ',' && IsADigit(sc.chNext))) { sc.Forward(); sc.SetState(SCE_AVS_NUMBER); } else if (sc.Match('/', '*')) { blockCommentLevel = 1; sc.SetState(SCE_AVS_COMMENTBLOCK); sc.Forward(); // Eat the * so it isn't used for the end of the comment } else if (sc.Match('[', '*')) { blockCommentLevel = 1; sc.SetState(SCE_AVS_COMMENTBLOCKN); sc.Forward(); // Eat the * so it isn't used for the end of the comment } else if (sc.ch == '#') { sc.SetState(SCE_AVS_COMMENTLINE); } else if (sc.ch == '\"') { if (sc.Match("\"\"\"")) { sc.SetState(SCE_AVS_TRIPLESTRING); } else { sc.SetState(SCE_AVS_STRING); } } else if (isoperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_AVS_OPERATOR); } else if (IsAWordStart(sc.ch)) { sc.SetState(SCE_AVS_IDENTIFIER); } } } // End of file: complete any pending changeState if (sc.state == SCE_AVS_IDENTIFIER) { if (!IsAWordChar(sc.ch)) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (keywords.InList(s)) { sc.ChangeState(SCE_AVS_KEYWORD); } else if (filters.InList(s)) { sc.ChangeState(SCE_AVS_FILTER); } else if (plugins.InList(s)) { sc.ChangeState(SCE_AVS_PLUGIN); } else if (functions.InList(s)) { sc.ChangeState(SCE_AVS_FUNCTION); } else if (clipProperties.InList(s)) { sc.ChangeState(SCE_AVS_CLIPPROP); } else if (userDefined.InList(s)) { sc.ChangeState(SCE_AVS_USERDFN); } sc.SetState(SCE_AVS_DEFAULT); } } sc.Complete(); } static void FoldAvsDoc( unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment && style == SCE_AVS_COMMENTBLOCK) { if (stylePrev != SCE_AVS_COMMENTBLOCK) { levelCurrent++; } else if ((styleNext != SCE_AVS_COMMENTBLOCK) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelCurrent--; } } if (foldComment && style == SCE_AVS_COMMENTBLOCKN) { if (stylePrev != SCE_AVS_COMMENTBLOCKN) { levelCurrent++; } else if ((styleNext != SCE_AVS_COMMENTBLOCKN) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelCurrent--; } } if (style == SCE_AVS_OPERATOR) { if (ch == '{') { levelCurrent++; } else if (ch == '}') { levelCurrent--; } } if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char * const avsWordLists[] = { "Keywords", "Filters", "Plugins", "Functions", "Clip properties", "User defined functions", 0, }; LexerModule lmAVS(SCLEX_AVS, ColouriseAvsDoc, "avs", FoldAvsDoc, avsWordLists); |
Added lexers/LexAbaqus.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 |
// Scintilla source code edit control /** @file LexABAQUS.cxx ** Lexer for ABAQUS. Based on the lexer for APDL by Hadar Raz. ** By Sergio Lucato. ** Sort of completely rewritten by Gertjan Kloosterman **/ // The License.txt file describes the conditions under which this software may be distributed. // Code folding copyied and modified from LexBasic.cxx #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(const int ch) { return (ch < 0x80 && (isalnum(ch) || (ch == '_'))); } static inline bool IsAKeywordChar(const int ch) { return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == ' '))); } static inline bool IsASetChar(const int ch) { return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == '.') || (ch == '-'))); } static inline bool IsAnOperator(char ch) { // '.' left out as it is used to make up numbers if (ch == '*' || ch == '/' || ch == '-' || ch == '+' || ch == '(' || ch == ')' || ch == '=' || ch == '^' || ch == '[' || ch == ']' || ch == '<' || ch == '&' || ch == '>' || ch == ',' || ch == '|' || ch == '~' || ch == '$' || ch == ':' || ch == '%') return true; return false; } static void ColouriseABAQUSDoc(unsigned int startPos, int length, int initStyle, WordList*[] /* *keywordlists[] */, Accessor &styler) { enum localState { KW_LINE_KW, KW_LINE_COMMA, KW_LINE_PAR, KW_LINE_EQ, KW_LINE_VAL, \ DAT_LINE_VAL, DAT_LINE_COMMA,\ COMMENT_LINE,\ ST_ERROR, LINE_END } state ; // Do not leak onto next line state = LINE_END ; initStyle = SCE_ABAQUS_DEFAULT; StyleContext sc(startPos, length, initStyle, styler); // Things are actually quite simple // we have commentlines // keywordlines and datalines // On a data line there will only be colouring of numbers // a keyword line is constructed as // *word,[ paramname[=paramvalue]]* // if the line ends with a , the keyword line continues onto the new line for (; sc.More(); sc.Forward()) { switch ( state ) { case KW_LINE_KW : if ( sc.atLineEnd ) { // finished the line in keyword state, switch to LINE_END sc.SetState(SCE_ABAQUS_DEFAULT) ; state = LINE_END ; } else if ( IsAKeywordChar(sc.ch) ) { // nothing changes state = KW_LINE_KW ; } else if ( sc.ch == ',' ) { // Well well we say a comma, arguments *MUST* follow sc.SetState(SCE_ABAQUS_OPERATOR) ; state = KW_LINE_COMMA ; } else { // Flag an error sc.SetState(SCE_ABAQUS_PROCESSOR) ; state = ST_ERROR ; } // Done with processing break ; case KW_LINE_COMMA : // acomma on a keywordline was seen if ( IsAKeywordChar(sc.ch)) { sc.SetState(SCE_ABAQUS_ARGUMENT) ; state = KW_LINE_PAR ; } else if ( sc.atLineEnd || (sc.ch == ',') ) { // we remain in keyword mode state = KW_LINE_COMMA ; } else if ( sc.ch == ' ' ) { sc.SetState(SCE_ABAQUS_DEFAULT) ; state = KW_LINE_COMMA ; } else { // Anything else constitutes an error sc.SetState(SCE_ABAQUS_PROCESSOR) ; state = ST_ERROR ; } break ; case KW_LINE_PAR : if ( sc.atLineEnd ) { sc.SetState(SCE_ABAQUS_DEFAULT) ; state = LINE_END ; } else if ( IsAKeywordChar(sc.ch) || (sc.ch == '-') ) { // remain in this state state = KW_LINE_PAR ; } else if ( sc.ch == ',' ) { sc.SetState(SCE_ABAQUS_OPERATOR) ; state = KW_LINE_COMMA ; } else if ( sc.ch == '=' ) { sc.SetState(SCE_ABAQUS_OPERATOR) ; state = KW_LINE_EQ ; } else { // Anything else constitutes an error sc.SetState(SCE_ABAQUS_PROCESSOR) ; state = ST_ERROR ; } break ; case KW_LINE_EQ : if ( sc.ch == ' ' ) { sc.SetState(SCE_ABAQUS_DEFAULT) ; // remain in this state state = KW_LINE_EQ ; } else if ( IsADigit(sc.ch) || (sc.ch == '-') || (sc.ch == '.' && IsADigit(sc.chNext)) ) { sc.SetState(SCE_ABAQUS_NUMBER) ; state = KW_LINE_VAL ; } else if ( IsAKeywordChar(sc.ch) ) { sc.SetState(SCE_ABAQUS_DEFAULT) ; state = KW_LINE_VAL ; } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) { sc.SetState(SCE_ABAQUS_STRING) ; state = KW_LINE_VAL ; } else { sc.SetState(SCE_ABAQUS_PROCESSOR) ; state = ST_ERROR ; } break ; case KW_LINE_VAL : if ( sc.atLineEnd ) { sc.SetState(SCE_ABAQUS_DEFAULT) ; state = LINE_END ; } else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) { // nothing changes state = KW_LINE_VAL ; } else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') || ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) && (sc.state == SCE_ABAQUS_NUMBER)) { // remain in number mode state = KW_LINE_VAL ; } else if (sc.state == SCE_ABAQUS_STRING) { // accept everything until a closing quote if ( sc.ch == '\'' || sc.ch == '\"' ) { sc.SetState(SCE_ABAQUS_DEFAULT) ; state = KW_LINE_VAL ; } } else if ( sc.ch == ',' ) { sc.SetState(SCE_ABAQUS_OPERATOR) ; state = KW_LINE_COMMA ; } else { // anything else is an error sc.SetState(SCE_ABAQUS_PROCESSOR) ; state = ST_ERROR ; } break ; case DAT_LINE_VAL : if ( sc.atLineEnd ) { sc.SetState(SCE_ABAQUS_DEFAULT) ; state = LINE_END ; } else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) { // nothing changes state = DAT_LINE_VAL ; } else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') || ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) && (sc.state == SCE_ABAQUS_NUMBER)) { // remain in number mode state = DAT_LINE_VAL ; } else if (sc.state == SCE_ABAQUS_STRING) { // accept everything until a closing quote if ( sc.ch == '\'' || sc.ch == '\"' ) { sc.SetState(SCE_ABAQUS_DEFAULT) ; state = DAT_LINE_VAL ; } } else if ( sc.ch == ',' ) { sc.SetState(SCE_ABAQUS_OPERATOR) ; state = DAT_LINE_COMMA ; } else { // anything else is an error sc.SetState(SCE_ABAQUS_PROCESSOR) ; state = ST_ERROR ; } break ; case DAT_LINE_COMMA : // a comma on a data line was seen if ( sc.atLineEnd ) { sc.SetState(SCE_ABAQUS_DEFAULT) ; state = LINE_END ; } else if ( sc.ch == ' ' ) { sc.SetState(SCE_ABAQUS_DEFAULT) ; state = DAT_LINE_COMMA ; } else if (sc.ch == ',') { sc.SetState(SCE_ABAQUS_OPERATOR) ; state = DAT_LINE_COMMA ; } else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) { sc.SetState(SCE_ABAQUS_NUMBER) ; state = DAT_LINE_VAL ; } else if ( IsAKeywordChar(sc.ch) ) { sc.SetState(SCE_ABAQUS_DEFAULT) ; state = DAT_LINE_VAL ; } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) { sc.SetState(SCE_ABAQUS_STRING) ; state = DAT_LINE_VAL ; } else { sc.SetState(SCE_ABAQUS_PROCESSOR) ; state = ST_ERROR ; } break ; case COMMENT_LINE : if ( sc.atLineEnd ) { sc.SetState(SCE_ABAQUS_DEFAULT) ; state = LINE_END ; } break ; case ST_ERROR : if ( sc.atLineEnd ) { sc.SetState(SCE_ABAQUS_DEFAULT) ; state = LINE_END ; } break ; case LINE_END : if ( sc.atLineEnd || sc.ch == ' ' ) { // nothing changes state = LINE_END ; } else if ( sc.ch == '*' ) { if ( sc.chNext == '*' ) { state = COMMENT_LINE ; sc.SetState(SCE_ABAQUS_COMMENT) ; } else { state = KW_LINE_KW ; sc.SetState(SCE_ABAQUS_STARCOMMAND) ; } } else { // it must be a data line, things are as if we are in DAT_LINE_COMMA if ( sc.ch == ',' ) { sc.SetState(SCE_ABAQUS_OPERATOR) ; state = DAT_LINE_COMMA ; } else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) { sc.SetState(SCE_ABAQUS_NUMBER) ; state = DAT_LINE_VAL ; } else if ( IsAKeywordChar(sc.ch) ) { sc.SetState(SCE_ABAQUS_DEFAULT) ; state = DAT_LINE_VAL ; } else if ( (sc.ch == '\'') || (sc.ch == '\"') ) { sc.SetState(SCE_ABAQUS_STRING) ; state = DAT_LINE_VAL ; } else { sc.SetState(SCE_ABAQUS_PROCESSOR) ; state = ST_ERROR ; } } break ; } } sc.Complete(); } //------------------------------------------------------------------------------ // This copyied and modified from LexBasic.cxx //------------------------------------------------------------------------------ /* Bits: * 1 - whitespace * 2 - operator * 4 - identifier * 8 - decimal digit * 16 - hex digit * 32 - bin digit */ static int character_classification[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 10, 6, 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4, 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0 }; static bool IsSpace(int c) { return c < 128 && (character_classification[c] & 1); } static bool IsIdentifier(int c) { return c < 128 && (character_classification[c] & 4); } static int LowerCase(int c) { if (c >= 'A' && c <= 'Z') return 'a' + c - 'A'; return c; } static int LineEnd(int line, Accessor &styler) { const int docLines = styler.GetLine(styler.Length() - 1); // Available last line int eol_pos ; // if the line is the last line, the eol_pos is styler.Length() // eol will contain a new line, or a virtual new line if ( docLines == line ) eol_pos = styler.Length() ; else eol_pos = styler.LineStart(line + 1) - 1; return eol_pos ; } static int LineStart(int line, Accessor &styler) { return styler.LineStart(line) ; } // LineType // // bits determines the line type // 1 : data line // 2 : only whitespace // 3 : data line with only whitespace // 4 : keyword line // 5 : block open keyword line // 6 : block close keyword line // 7 : keyword line in error // 8 : comment line static int LineType(int line, Accessor &styler) { int pos = LineStart(line, styler) ; int eol_pos = LineEnd(line, styler) ; int c ; char ch = ' '; int i = pos ; while ( i < eol_pos ) { c = styler.SafeGetCharAt(i); ch = static_cast<char>(LowerCase(c)); // We can say something as soon as no whitespace // was encountered if ( !IsSpace(c) ) break ; i++ ; } if ( i >= eol_pos ) { // This is a whitespace line, currently // classifies as data line return 3 ; } if ( ch != '*' ) { // This is a data line return 1 ; } if ( i == eol_pos - 1 ) { // Only a single *, error but make keyword line return 4+3 ; } // This means we can have a second character // if that is also a * this means a comment // otherwise it is a keyword. c = styler.SafeGetCharAt(i+1); ch = static_cast<char>(LowerCase(c)); if ( ch == '*' ) { return 8 ; } // At this point we know this is a keyword line // the character at position i is a * // it is not a comment line char word[256] ; int wlen = 0; word[wlen] = '*' ; wlen++ ; i++ ; while ( (i < eol_pos) && (wlen < 255) ) { c = styler.SafeGetCharAt(i); ch = static_cast<char>(LowerCase(c)); if ( (!IsSpace(c)) && (!IsIdentifier(c)) ) break ; if ( IsIdentifier(c) ) { word[wlen] = ch ; wlen++ ; } i++ ; } word[wlen] = 0 ; // Make a comparison if ( !strcmp(word, "*step") || !strcmp(word, "*part") || !strcmp(word, "*instance") || !strcmp(word, "*assembly")) { return 4+1 ; } if ( !strcmp(word, "*endstep") || !strcmp(word, "*endpart") || !strcmp(word, "*endinstance") || !strcmp(word, "*endassembly")) { return 4+2 ; } return 4 ; } static void SafeSetLevel(int line, int level, Accessor &styler) { if ( line < 0 ) return ; int mask = ((~SC_FOLDLEVELHEADERFLAG) | (~SC_FOLDLEVELWHITEFLAG)); if ( (level & mask) < 0 ) return ; if ( styler.LevelAt(line) != level ) styler.SetLevel(line, level) ; } static void FoldABAQUSDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { int startLine = styler.GetLine(startPos) ; int endLine = styler.GetLine(startPos+length-1) ; // bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; // We want to deal with all the cases // To know the correct indentlevel, we need to look back to the // previous command line indentation level // order of formatting keyline datalines commentlines int beginData = -1 ; int beginComment = -1 ; int prvKeyLine = startLine ; int prvKeyLineTp = 0 ; // Scan until we find the previous keyword line // this will give us the level reference that we need while ( prvKeyLine > 0 ) { prvKeyLine-- ; prvKeyLineTp = LineType(prvKeyLine, styler) ; if ( prvKeyLineTp & 4 ) break ; } // Determine the base line level of all lines following // the previous keyword // new keyword lines are placed on this level //if ( prvKeyLineTp & 4 ) { int level = styler.LevelAt(prvKeyLine) & ~SC_FOLDLEVELHEADERFLAG ; //} // uncomment line below if weird behaviour continues prvKeyLine = -1 ; // Now start scanning over the lines. for ( int line = startLine; line <= endLine; line++ ) { int lineType = LineType(line, styler) ; // Check for comment line if ( lineType == 8 ) { if ( beginComment < 0 ) { beginComment = line ; } } // Check for data line if ( (lineType == 1) || (lineType == 3) ) { if ( beginData < 0 ) { if ( beginComment >= 0 ) { beginData = beginComment ; } else { beginData = line ; } } beginComment = -1 ; } // Check for keywordline. // As soon as a keyword line is encountered, we can set the // levels of everything from the previous keyword line to this one if ( lineType & 4 ) { // this is a keyword, we can now place the previous keyword // all its data lines and the remainder // Write comments and data line if ( beginComment < 0 ) { beginComment = line ; } if ( beginData < 0 ) { beginData = beginComment ; if ( prvKeyLineTp != 5 ) SafeSetLevel(prvKeyLine, level, styler) ; else SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ; } else { SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ; } int datLevel = level + 1 ; if ( !(prvKeyLineTp & 4) ) { datLevel = level ; } for ( int ll = beginData; ll < beginComment; ll++ ) SafeSetLevel(ll, datLevel, styler) ; // The keyword we just found is going to be written at another level // if we have a type 5 and type 6 if ( prvKeyLineTp == 5 ) { level += 1 ; } if ( prvKeyLineTp == 6 ) { level -= 1 ; if ( level < 0 ) { level = 0 ; } } for ( int lll = beginComment; lll < line; lll++ ) SafeSetLevel(lll, level, styler) ; // wrap and reset beginComment = -1 ; beginData = -1 ; prvKeyLine = line ; prvKeyLineTp = lineType ; } } if ( beginComment < 0 ) { beginComment = endLine + 1 ; } else { // We need to find out whether this comment block is followed by // a data line or a keyword line const int docLines = styler.GetLine(styler.Length() - 1); for ( int line = endLine + 1; line <= docLines; line++ ) { int lineType = LineType(line, styler) ; if ( lineType != 8 ) { if ( !(lineType & 4) ) { beginComment = endLine + 1 ; } break ; } } } if ( beginData < 0 ) { beginData = beginComment ; if ( prvKeyLineTp != 5 ) SafeSetLevel(prvKeyLine, level, styler) ; else SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ; } else { SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ; } int datLevel = level + 1 ; if ( !(prvKeyLineTp & 4) ) { datLevel = level ; } for ( int ll = beginData; ll < beginComment; ll++ ) SafeSetLevel(ll, datLevel, styler) ; if ( prvKeyLineTp == 5 ) { level += 1 ; } if ( prvKeyLineTp == 6 ) { level -= 1 ; } for ( int m = beginComment; m <= endLine; m++ ) SafeSetLevel(m, level, styler) ; } static const char * const abaqusWordListDesc[] = { "processors", "commands", "slashommands", "starcommands", "arguments", "functions", 0 }; LexerModule lmAbaqus(SCLEX_ABAQUS, ColouriseABAQUSDoc, "abaqus", FoldABAQUSDoc, abaqusWordListDesc); |
Added lexers/LexAda.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 |
// Scintilla source code edit control /** @file LexAda.cxx ** Lexer for Ada 95 **/ // Copyright 2002 by Sergey Koshcheyev <sergey.k@seznam.cz> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include <string> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif /* * Interface */ static void ColouriseDocument( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler); static const char * const adaWordListDesc[] = { "Keywords", 0 }; LexerModule lmAda(SCLEX_ADA, ColouriseDocument, "ada", NULL, adaWordListDesc); /* * Implementation */ // Functions that have apostropheStartsAttribute as a parameter set it according to whether // an apostrophe encountered after processing the current token will start an attribute or // a character literal. static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute); static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute); static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL); static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute); static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute); static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute); static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute); static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute); static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute); static inline bool IsDelimiterCharacter(int ch); static inline bool IsNumberStartCharacter(int ch); static inline bool IsNumberCharacter(int ch); static inline bool IsSeparatorOrDelimiterCharacter(int ch); static bool IsValidIdentifier(const std::string& identifier); static bool IsValidNumber(const std::string& number); static inline bool IsWordStartCharacter(int ch); static inline bool IsWordCharacter(int ch); static void ColouriseCharacter(StyleContext& sc, bool& apostropheStartsAttribute) { apostropheStartsAttribute = true; sc.SetState(SCE_ADA_CHARACTER); // Skip the apostrophe and one more character (so that '' is shown as non-terminated and ''' // is handled correctly) sc.Forward(); sc.Forward(); ColouriseContext(sc, '\'', SCE_ADA_CHARACTEREOL); } static void ColouriseContext(StyleContext& sc, char chEnd, int stateEOL) { while (!sc.atLineEnd && !sc.Match(chEnd)) { sc.Forward(); } if (!sc.atLineEnd) { sc.ForwardSetState(SCE_ADA_DEFAULT); } else { sc.ChangeState(stateEOL); } } static void ColouriseComment(StyleContext& sc, bool& /*apostropheStartsAttribute*/) { // Apostrophe meaning is not changed, but the parameter is present for uniformity sc.SetState(SCE_ADA_COMMENTLINE); while (!sc.atLineEnd) { sc.Forward(); } } static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) { apostropheStartsAttribute = sc.Match (')'); sc.SetState(SCE_ADA_DELIMITER); sc.ForwardSetState(SCE_ADA_DEFAULT); } static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) { apostropheStartsAttribute = false; sc.SetState(SCE_ADA_LABEL); // Skip "<<" sc.Forward(); sc.Forward(); std::string identifier; while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) { identifier += static_cast<char>(tolower(sc.ch)); sc.Forward(); } // Skip ">>" if (sc.Match('>', '>')) { sc.Forward(); sc.Forward(); } else { sc.ChangeState(SCE_ADA_ILLEGAL); } // If the name is an invalid identifier or a keyword, then make it invalid label if (!IsValidIdentifier(identifier) || keywords.InList(identifier.c_str())) { sc.ChangeState(SCE_ADA_ILLEGAL); } sc.SetState(SCE_ADA_DEFAULT); } static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) { apostropheStartsAttribute = true; std::string number; sc.SetState(SCE_ADA_NUMBER); // Get all characters up to a delimiter or a separator, including points, but excluding // double points (ranges). while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) { number += static_cast<char>(sc.ch); sc.Forward(); } // Special case: exponent with sign if ((sc.chPrev == 'e' || sc.chPrev == 'E') && (sc.ch == '+' || sc.ch == '-')) { number += static_cast<char>(sc.ch); sc.Forward (); while (!IsSeparatorOrDelimiterCharacter(sc.ch)) { number += static_cast<char>(sc.ch); sc.Forward(); } } if (!IsValidNumber(number)) { sc.ChangeState(SCE_ADA_ILLEGAL); } sc.SetState(SCE_ADA_DEFAULT); } static void ColouriseString(StyleContext& sc, bool& apostropheStartsAttribute) { apostropheStartsAttribute = true; sc.SetState(SCE_ADA_STRING); sc.Forward(); ColouriseContext(sc, '"', SCE_ADA_STRINGEOL); } static void ColouriseWhiteSpace(StyleContext& sc, bool& /*apostropheStartsAttribute*/) { // Apostrophe meaning is not changed, but the parameter is present for uniformity sc.SetState(SCE_ADA_DEFAULT); sc.ForwardSetState(SCE_ADA_DEFAULT); } static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostropheStartsAttribute) { apostropheStartsAttribute = true; sc.SetState(SCE_ADA_IDENTIFIER); std::string word; while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) { word += static_cast<char>(tolower(sc.ch)); sc.Forward(); } if (!IsValidIdentifier(word)) { sc.ChangeState(SCE_ADA_ILLEGAL); } else if (keywords.InList(word.c_str())) { sc.ChangeState(SCE_ADA_WORD); if (word != "all") { apostropheStartsAttribute = false; } } sc.SetState(SCE_ADA_DEFAULT); } // // ColouriseDocument // static void ColouriseDocument( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; StyleContext sc(startPos, length, initStyle, styler); int lineCurrent = styler.GetLine(startPos); bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0; while (sc.More()) { if (sc.atLineEnd) { // Go to the next line sc.Forward(); lineCurrent++; // Remember the line state for future incremental lexing styler.SetLineState(lineCurrent, apostropheStartsAttribute); // Don't continue any styles on the next line sc.SetState(SCE_ADA_DEFAULT); } // Comments if (sc.Match('-', '-')) { ColouriseComment(sc, apostropheStartsAttribute); // Strings } else if (sc.Match('"')) { ColouriseString(sc, apostropheStartsAttribute); // Characters } else if (sc.Match('\'') && !apostropheStartsAttribute) { ColouriseCharacter(sc, apostropheStartsAttribute); // Labels } else if (sc.Match('<', '<')) { ColouriseLabel(sc, keywords, apostropheStartsAttribute); // Whitespace } else if (IsASpace(sc.ch)) { ColouriseWhiteSpace(sc, apostropheStartsAttribute); // Delimiters } else if (IsDelimiterCharacter(sc.ch)) { ColouriseDelimiter(sc, apostropheStartsAttribute); // Numbers } else if (IsADigit(sc.ch) || sc.ch == '#') { ColouriseNumber(sc, apostropheStartsAttribute); // Keywords or identifiers } else { ColouriseWord(sc, keywords, apostropheStartsAttribute); } } sc.Complete(); } static inline bool IsDelimiterCharacter(int ch) { switch (ch) { case '&': case '\'': case '(': case ')': case '*': case '+': case ',': case '-': case '.': case '/': case ':': case ';': case '<': case '=': case '>': case '|': return true; default: return false; } } static inline bool IsNumberCharacter(int ch) { return IsNumberStartCharacter(ch) || ch == '_' || ch == '.' || ch == '#' || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'); } static inline bool IsNumberStartCharacter(int ch) { return IsADigit(ch); } static inline bool IsSeparatorOrDelimiterCharacter(int ch) { return IsASpace(ch) || IsDelimiterCharacter(ch); } static bool IsValidIdentifier(const std::string& identifier) { // First character can't be '_', so initialize the flag to true bool lastWasUnderscore = true; size_t length = identifier.length(); // Zero-length identifiers are not valid (these can occur inside labels) if (length == 0) { return false; } // Check for valid character at the start if (!IsWordStartCharacter(identifier[0])) { return false; } // Check for only valid characters and no double underscores for (size_t i = 0; i < length; i++) { if (!IsWordCharacter(identifier[i]) || (identifier[i] == '_' && lastWasUnderscore)) { return false; } lastWasUnderscore = identifier[i] == '_'; } // Check for underscore at the end if (lastWasUnderscore == true) { return false; } // All checks passed return true; } static bool IsValidNumber(const std::string& number) { size_t hashPos = number.find("#"); bool seenDot = false; size_t i = 0; size_t length = number.length(); if (length == 0) return false; // Just in case // Decimal number if (hashPos == std::string::npos) { bool canBeSpecial = false; for (; i < length; i++) { if (number[i] == '_') { if (!canBeSpecial) { return false; } canBeSpecial = false; } else if (number[i] == '.') { if (!canBeSpecial || seenDot) { return false; } canBeSpecial = false; seenDot = true; } else if (IsADigit(number[i])) { canBeSpecial = true; } else { break; } } if (!canBeSpecial) return false; } else { // Based number bool canBeSpecial = false; int base = 0; // Parse base for (; i < length; i++) { int ch = number[i]; if (ch == '_') { if (!canBeSpecial) return false; canBeSpecial = false; } else if (IsADigit(ch)) { base = base * 10 + (ch - '0'); if (base > 16) return false; canBeSpecial = true; } else if (ch == '#' && canBeSpecial) { break; } else { return false; } } if (base < 2) return false; if (i == length) return false; i++; // Skip over '#' // Parse number canBeSpecial = false; for (; i < length; i++) { int ch = tolower(number[i]); if (ch == '_') { if (!canBeSpecial) { return false; } canBeSpecial = false; } else if (ch == '.') { if (!canBeSpecial || seenDot) { return false; } canBeSpecial = false; seenDot = true; } else if (IsADigit(ch)) { if (ch - '0' >= base) { return false; } canBeSpecial = true; } else if (ch >= 'a' && ch <= 'f') { if (ch - 'a' + 10 >= base) { return false; } canBeSpecial = true; } else if (ch == '#' && canBeSpecial) { break; } else { return false; } } if (i == length) { return false; } i++; } // Exponent (optional) if (i < length) { if (number[i] != 'e' && number[i] != 'E') return false; i++; // Move past 'E' if (i == length) { return false; } if (number[i] == '+') i++; else if (number[i] == '-') { if (seenDot) { i++; } else { return false; // Integer literals should not have negative exponents } } if (i == length) { return false; } bool canBeSpecial = false; for (; i < length; i++) { if (number[i] == '_') { if (!canBeSpecial) { return false; } canBeSpecial = false; } else if (IsADigit(number[i])) { canBeSpecial = true; } else { return false; } } if (!canBeSpecial) return false; } // if i == length, number was parsed successfully. return i == length; } static inline bool IsWordCharacter(int ch) { return IsWordStartCharacter(ch) || IsADigit(ch); } static inline bool IsWordStartCharacter(int ch) { return (isascii(ch) && isalpha(ch)) || ch == '_'; } |
Added lexers/LexAsm.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 |
// Scintilla source code edit control /** @file LexAsm.cxx ** Lexer for Assembler, just for the MASM syntax ** Written by The Black Horus ** Enhancements and NASM stuff by Kein-Hong Man, 2003-10 ** SCE_ASM_COMMENTBLOCK and SCE_ASM_CHARACTER are for future GNU as colouring ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net> **/ // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include <string> #include <map> #include <set> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #include "OptionSet.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '?'); } static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' || ch == '%' || ch == '@' || ch == '$' || ch == '?'); } static inline bool IsAsmOperator(const int ch) { if ((ch < 0x80) && (isalnum(ch))) return false; // '.' left out as it is used to make up numbers if (ch == '*' || ch == '/' || ch == '-' || ch == '+' || ch == '(' || ch == ')' || ch == '=' || ch == '^' || ch == '[' || ch == ']' || ch == '<' || ch == '&' || ch == '>' || ch == ',' || ch == '|' || ch == '~' || ch == '%' || ch == ':') return true; return false; } static bool IsStreamCommentStyle(int style) { return style == SCE_ASM_COMMENTDIRECTIVE || style == SCE_ASM_COMMENTBLOCK; } static inline int LowerCase(int c) { if (c >= 'A' && c <= 'Z') return 'a' + c - 'A'; return c; } // An individual named option for use in an OptionSet // Options used for LexerAsm struct OptionsAsm { std::string delimiter; bool fold; bool foldSyntaxBased; bool foldCommentMultiline; bool foldCommentExplicit; std::string foldExplicitStart; std::string foldExplicitEnd; bool foldExplicitAnywhere; bool foldCompact; OptionsAsm() { delimiter = ""; fold = false; foldSyntaxBased = true; foldCommentMultiline = false; foldCommentExplicit = false; foldExplicitStart = ""; foldExplicitEnd = ""; foldExplicitAnywhere = false; foldCompact = true; } }; static const char * const asmWordListDesc[] = { "CPU instructions", "FPU instructions", "Registers", "Directives", "Directive operands", "Extended instructions", "Directives4Foldstart", "Directives4Foldend", 0 }; struct OptionSetAsm : public OptionSet<OptionsAsm> { OptionSetAsm() { DefineProperty("lexer.asm.comment.delimiter", &OptionsAsm::delimiter, "Character used for COMMENT directive's delimiter, replacing the standard \"~\"."); DefineProperty("fold", &OptionsAsm::fold); DefineProperty("fold.asm.syntax.based", &OptionsAsm::foldSyntaxBased, "Set this property to 0 to disable syntax based folding."); DefineProperty("fold.asm.comment.multiline", &OptionsAsm::foldCommentMultiline, "Set this property to 1 to enable folding multi-line comments."); DefineProperty("fold.asm.comment.explicit", &OptionsAsm::foldCommentExplicit, "This option enables folding explicit fold points when using the Asm lexer. " "Explicit fold points allows adding extra folding by placing a ;{ comment at the start and a ;} " "at the end of a section that should fold."); DefineProperty("fold.asm.explicit.start", &OptionsAsm::foldExplicitStart, "The string to use for explicit fold start points, replacing the standard ;{."); DefineProperty("fold.asm.explicit.end", &OptionsAsm::foldExplicitEnd, "The string to use for explicit fold end points, replacing the standard ;}."); DefineProperty("fold.asm.explicit.anywhere", &OptionsAsm::foldExplicitAnywhere, "Set this property to 1 to enable explicit fold points anywhere, not just in line comments."); DefineProperty("fold.compact", &OptionsAsm::foldCompact); DefineWordListSets(asmWordListDesc); } }; class LexerAsm : public ILexer { WordList cpuInstruction; WordList mathInstruction; WordList registers; WordList directive; WordList directiveOperand; WordList extInstruction; WordList directives4foldstart; WordList directives4foldend; OptionsAsm options; OptionSetAsm osAsm; public: LexerAsm() { } virtual ~LexerAsm() { } void SCI_METHOD Release() { delete this; } int SCI_METHOD Version() const { return lvOriginal; } const char * SCI_METHOD PropertyNames() { return osAsm.PropertyNames(); } int SCI_METHOD PropertyType(const char *name) { return osAsm.PropertyType(name); } const char * SCI_METHOD DescribeProperty(const char *name) { return osAsm.DescribeProperty(name); } int SCI_METHOD PropertySet(const char *key, const char *val); const char * SCI_METHOD DescribeWordListSets() { return osAsm.DescribeWordListSets(); } int SCI_METHOD WordListSet(int n, const char *wl); void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess); void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess); void * SCI_METHOD PrivateCall(int, void *) { return 0; } static ILexer *LexerFactoryAsm() { return new LexerAsm(); } }; int SCI_METHOD LexerAsm::PropertySet(const char *key, const char *val) { if (osAsm.PropertySet(&options, key, val)) { return 0; } return -1; } int SCI_METHOD LexerAsm::WordListSet(int n, const char *wl) { WordList *wordListN = 0; switch (n) { case 0: wordListN = &cpuInstruction; break; case 1: wordListN = &mathInstruction; break; case 2: wordListN = ®isters; break; case 3: wordListN = &directive; break; case 4: wordListN = &directiveOperand; break; case 5: wordListN = &extInstruction; break; case 6: wordListN = &directives4foldstart; break; case 7: wordListN = &directives4foldend; break; } int firstModification = -1; if (wordListN) { WordList wlNew; wlNew.Set(wl); if (*wordListN != wlNew) { wordListN->Set(wl); firstModification = 0; } } return firstModification; } void SCI_METHOD LexerAsm::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { LexAccessor styler(pAccess); // Do not leak onto next line if (initStyle == SCE_ASM_STRINGEOL) initStyle = SCE_ASM_DEFAULT; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { // Prevent SCE_ASM_STRINGEOL from leaking back to previous line if (sc.atLineStart && (sc.state == SCE_ASM_STRING)) { sc.SetState(SCE_ASM_STRING); } else if (sc.atLineStart && (sc.state == SCE_ASM_CHARACTER)) { sc.SetState(SCE_ASM_CHARACTER); } // Handle line continuation generically. if (sc.ch == '\\') { if (sc.chNext == '\n' || sc.chNext == '\r') { sc.Forward(); if (sc.ch == '\r' && sc.chNext == '\n') { sc.Forward(); } continue; } } // Determine if the current state should terminate. if (sc.state == SCE_ASM_OPERATOR) { if (!IsAsmOperator(sc.ch)) { sc.SetState(SCE_ASM_DEFAULT); } } else if (sc.state == SCE_ASM_NUMBER) { if (!IsAWordChar(sc.ch)) { sc.SetState(SCE_ASM_DEFAULT); } } else if (sc.state == SCE_ASM_IDENTIFIER) { if (!IsAWordChar(sc.ch) ) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); bool IsDirective = false; if (cpuInstruction.InList(s)) { sc.ChangeState(SCE_ASM_CPUINSTRUCTION); } else if (mathInstruction.InList(s)) { sc.ChangeState(SCE_ASM_MATHINSTRUCTION); } else if (registers.InList(s)) { sc.ChangeState(SCE_ASM_REGISTER); } else if (directive.InList(s)) { sc.ChangeState(SCE_ASM_DIRECTIVE); IsDirective = true; } else if (directiveOperand.InList(s)) { sc.ChangeState(SCE_ASM_DIRECTIVEOPERAND); } else if (extInstruction.InList(s)) { sc.ChangeState(SCE_ASM_EXTINSTRUCTION); } sc.SetState(SCE_ASM_DEFAULT); if (IsDirective && !strcmp(s, "comment")) { char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0]; while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) { sc.ForwardSetState(SCE_ASM_DEFAULT); } if (sc.ch == delimiter) { sc.SetState(SCE_ASM_COMMENTDIRECTIVE); } } } } else if (sc.state == SCE_ASM_COMMENTDIRECTIVE) { char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0]; if (sc.ch == delimiter) { while (!sc.atLineEnd) { sc.Forward(); } sc.SetState(SCE_ASM_DEFAULT); } } else if (sc.state == SCE_ASM_COMMENT ) { if (sc.atLineEnd) { sc.SetState(SCE_ASM_DEFAULT); } } else if (sc.state == SCE_ASM_STRING) { if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_ASM_DEFAULT); } else if (sc.atLineEnd) { sc.ChangeState(SCE_ASM_STRINGEOL); sc.ForwardSetState(SCE_ASM_DEFAULT); } } else if (sc.state == SCE_ASM_CHARACTER) { if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\'') { sc.ForwardSetState(SCE_ASM_DEFAULT); } else if (sc.atLineEnd) { sc.ChangeState(SCE_ASM_STRINGEOL); sc.ForwardSetState(SCE_ASM_DEFAULT); } } // Determine if a new state should be entered. if (sc.state == SCE_ASM_DEFAULT) { if (sc.ch == ';'){ sc.SetState(SCE_ASM_COMMENT); } else if (isascii(sc.ch) && (isdigit(sc.ch) || (sc.ch == '.' && isascii(sc.chNext) && isdigit(sc.chNext)))) { sc.SetState(SCE_ASM_NUMBER); } else if (IsAWordStart(sc.ch)) { sc.SetState(SCE_ASM_IDENTIFIER); } else if (sc.ch == '\"') { sc.SetState(SCE_ASM_STRING); } else if (sc.ch == '\'') { sc.SetState(SCE_ASM_CHARACTER); } else if (IsAsmOperator(sc.ch)) { sc.SetState(SCE_ASM_OPERATOR); } } } sc.Complete(); } // Store both the current line's fold level and the next lines in the // level store to make it easy to pick up with each increment // and to make it possible to fiddle the current level for "else". void SCI_METHOD LexerAsm::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { if (!options.fold) return; LexAccessor styler(pAccess); unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelNext = levelCurrent; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; char word[100]; int wordlen = 0; const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty(); for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (options.foldCommentMultiline && IsStreamCommentStyle(style)) { if (!IsStreamCommentStyle(stylePrev)) { levelNext++; } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelNext--; } } if (options.foldCommentExplicit && ((style == SCE_ASM_COMMENT) || options.foldExplicitAnywhere)) { if (userDefinedFoldMarkers) { if (styler.Match(i, options.foldExplicitStart.c_str())) { levelNext++; } else if (styler.Match(i, options.foldExplicitEnd.c_str())) { levelNext--; } } else { if (ch == ';') { if (chNext == '{') { levelNext++; } else if (chNext == '}') { levelNext--; } } } } if (options.foldSyntaxBased && (style == SCE_ASM_DIRECTIVE)) { word[wordlen++] = static_cast<char>(LowerCase(ch)); if (wordlen == 100) { // prevent overflow word[0] = '\0'; wordlen = 1; } if (styleNext != SCE_ASM_DIRECTIVE) { // reading directive ready word[wordlen] = '\0'; wordlen = 0; if (directives4foldstart.InList(word)) { levelNext++; } else if (directives4foldend.InList(word)){ levelNext--; } } } if (!IsASpace(ch)) visibleChars++; if (atEOL || (i == endPos-1)) { int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; if (visibleChars == 0 && options.foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelCurrent = levelNext; if (atEOL && (i == static_cast<unsigned int>(styler.Length()-1))) { // There is an empty line at end of file so give it same level and empty styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG); } visibleChars = 0; } } } LexerModule lmAsm(SCLEX_ASM, LexerAsm::LexerFactoryAsm, "asm", asmWordListDesc); |
Added lexers/LexAsn1.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
// Scintilla source code edit control /** @file LexAsn1.cxx ** Lexer for ASN.1 **/ // Copyright 2004 by Herr Pfarrer rpfarrer <at> yahoo <dot> de // Last Updated: 20/07/2004 // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // Some char test functions static bool isAsn1Number(int ch) { return (ch >= '0' && ch <= '9'); } static bool isAsn1Letter(int ch) { return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); } static bool isAsn1Char(int ch) { return (ch == '-' ) || isAsn1Number(ch) || isAsn1Letter (ch); } // // Function determining the color of a given code portion // Based on a "state" // static void ColouriseAsn1Doc(unsigned int startPos, int length, int initStyle, WordList *keywordLists[], Accessor &styler) { // The keywords WordList &Keywords = *keywordLists[0]; WordList &Attributes = *keywordLists[1]; WordList &Descriptors = *keywordLists[2]; WordList &Types = *keywordLists[3]; // Parse the whole buffer character by character using StyleContext StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { // The state engine switch (sc.state) { case SCE_ASN1_DEFAULT: // Plain characters asn1_default: if (sc.ch == '-' && sc.chNext == '-') // A comment begins here sc.SetState(SCE_ASN1_COMMENT); else if (sc.ch == '"') // A string begins here sc.SetState(SCE_ASN1_STRING); else if (isAsn1Number (sc.ch)) // A number starts here (identifier should start with a letter in ASN.1) sc.SetState(SCE_ASN1_SCALAR); else if (isAsn1Char (sc.ch)) // An identifier starts here (identifier always start with a letter) sc.SetState(SCE_ASN1_IDENTIFIER); else if (sc.ch == ':') // A ::= operator starts here sc.SetState(SCE_ASN1_OPERATOR); break; case SCE_ASN1_COMMENT: // A comment if (sc.ch == '\r' || sc.ch == '\n') // A comment ends here sc.SetState(SCE_ASN1_DEFAULT); break; case SCE_ASN1_IDENTIFIER: // An identifier (keyword, attribute, descriptor or type) if (!isAsn1Char (sc.ch)) { // The end of identifier is here: we can look for it in lists by now and change its state char s[100]; sc.GetCurrent(s, sizeof(s)); if (Keywords.InList(s)) // It's a keyword, change its state sc.ChangeState(SCE_ASN1_KEYWORD); else if (Attributes.InList(s)) // It's an attribute, change its state sc.ChangeState(SCE_ASN1_ATTRIBUTE); else if (Descriptors.InList(s)) // It's a descriptor, change its state sc.ChangeState(SCE_ASN1_DESCRIPTOR); else if (Types.InList(s)) // It's a type, change its state sc.ChangeState(SCE_ASN1_TYPE); // Set to default now sc.SetState(SCE_ASN1_DEFAULT); } break; case SCE_ASN1_STRING: // A string delimited by "" if (sc.ch == '"') { // A string ends here sc.ForwardSetState(SCE_ASN1_DEFAULT); // To correctly manage a char sticking to the string quote goto asn1_default; } break; case SCE_ASN1_SCALAR: // A plain number if (!isAsn1Number (sc.ch)) // A number ends here sc.SetState(SCE_ASN1_DEFAULT); break; case SCE_ASN1_OPERATOR: // The affectation operator ::= and wath follows (eg: ::= { org 6 } OID or ::= 12 trap) if (sc.ch == '{') { // An OID definition starts here: enter the sub loop for (; sc.More(); sc.Forward()) { if (isAsn1Number (sc.ch) && (!isAsn1Char (sc.chPrev) || isAsn1Number (sc.chPrev))) // The OID number is highlighted sc.SetState(SCE_ASN1_OID); else if (isAsn1Char (sc.ch)) // The OID parent identifier is plain sc.SetState(SCE_ASN1_IDENTIFIER); else sc.SetState(SCE_ASN1_DEFAULT); if (sc.ch == '}') // Here ends the OID and the operator sub loop: go back to main loop break; } } else if (isAsn1Number (sc.ch)) { // A trap number definition starts here: enter the sub loop for (; sc.More(); sc.Forward()) { if (isAsn1Number (sc.ch)) // The trap number is highlighted sc.SetState(SCE_ASN1_OID); else { // The number ends here: go back to main loop sc.SetState(SCE_ASN1_DEFAULT); break; } } } else if (sc.ch != ':' && sc.ch != '=' && sc.ch != ' ') // The operator doesn't imply an OID definition nor a trap, back to main loop goto asn1_default; // To be sure to handle actually the state change break; } } sc.Complete(); } static void FoldAsn1Doc(unsigned int, int, int, WordList *[], Accessor &styler) { // No folding enabled, no reason to continue... if( styler.GetPropertyInt("fold") == 0 ) return; // No folding implemented: doesn't make sense for ASN.1 } static const char * const asn1WordLists[] = { "Keywords", "Attributes", "Descriptors", "Types", 0, }; LexerModule lmAns1(SCLEX_ASN1, ColouriseAsn1Doc, "asn1", FoldAsn1Doc, asn1WordLists); |
Added lexers/LexBaan.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
// Scintilla source code edit control /** @file LexBaan.cxx ** Lexer for Baan. ** Based heavily on LexCPP.cxx **/ // Copyright 2001- by Vamsi Potluru <vamsi@who.net> & Praveen Ambekar <ambekarpraveen@yahoo.com> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '$' || ch == ':'); } static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_'); } static void ColouriseBaanDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0; if (initStyle == SCE_BAAN_STRINGEOL) // Does not leak onto next line initStyle = SCE_BAAN_DEFAULT; int visibleChars = 0; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.state == SCE_BAAN_OPERATOR) { sc.SetState(SCE_BAAN_DEFAULT); } else if (sc.state == SCE_BAAN_NUMBER) { if (!IsAWordChar(sc.ch)) { sc.SetState(SCE_BAAN_DEFAULT); } } else if (sc.state == SCE_BAAN_IDENTIFIER) { if (!IsAWordChar(sc.ch)) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (keywords.InList(s)) { sc.ChangeState(SCE_BAAN_WORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_BAAN_WORD2); } sc.SetState(SCE_BAAN_DEFAULT); } } else if (sc.state == SCE_BAAN_PREPROCESSOR) { if (stylingWithinPreprocessor) { if (IsASpace(sc.ch)) { sc.SetState(SCE_BAAN_DEFAULT); } } else { if (sc.atLineEnd && (sc.chNext != '^')) { sc.SetState(SCE_BAAN_DEFAULT); } } } else if (sc.state == SCE_BAAN_COMMENT) { if (sc.atLineEnd) { sc.SetState(SCE_BAAN_DEFAULT); } } else if (sc.state == SCE_BAAN_COMMENTDOC) { if (sc.MatchIgnoreCase("enddllusage")) { for (unsigned int i = 0; i < 10; i++){ sc.Forward(); } sc.ForwardSetState(SCE_BAAN_DEFAULT); } } else if (sc.state == SCE_BAAN_STRING) { if (sc.ch == '\"') { sc.ForwardSetState(SCE_BAAN_DEFAULT); } else if ((sc.atLineEnd) && (sc.chNext != '^')) { sc.ChangeState(SCE_BAAN_STRINGEOL); sc.ForwardSetState(SCE_C_DEFAULT); visibleChars = 0; } } if (sc.state == SCE_BAAN_DEFAULT) { if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_BAAN_NUMBER); } else if (sc.MatchIgnoreCase("dllusage")){ sc.SetState(SCE_BAAN_COMMENTDOC); do { sc.Forward(); } while ((!sc.atLineEnd) && sc.More()); } else if (IsAWordStart(sc.ch)) { sc.SetState(SCE_BAAN_IDENTIFIER); } else if (sc.Match('|')){ sc.SetState(SCE_BAAN_COMMENT); } else if (sc.ch == '\"') { sc.SetState(SCE_BAAN_STRING); } else if (sc.ch == '#' && visibleChars == 0) { // Preprocessor commands are alone on their line sc.SetState(SCE_BAAN_PREPROCESSOR); // Skip whitespace between # and preprocessor word do { sc.Forward(); } while (IsASpace(sc.ch) && sc.More()); } else if (isoperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_BAAN_OPERATOR); } } if (sc.atLineEnd) { // Reset states to begining of colourise so no surprises // if different sets of lines lexed. visibleChars = 0; } if (!IsASpace(sc.ch)) { visibleChars++; } } sc.Complete(); } static void FoldBaanDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment && (style == SCE_BAAN_COMMENT || style == SCE_BAAN_COMMENTDOC)) { if (style != stylePrev) { levelCurrent++; } else if ((style != styleNext) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelCurrent--; } } if (style == SCE_BAAN_OPERATOR) { if (ch == '{') { levelCurrent++; } else if (ch == '}') { levelCurrent--; } } if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } LexerModule lmBaan(SCLEX_BAAN, ColouriseBaanDoc, "baan", FoldBaanDoc); |
Added lexers/LexBash.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 |
// Scintilla source code edit control /** @file LexBash.cxx ** Lexer for Bash. **/ // Copyright 2004-2012 by Neil Hodgson <neilh@scintilla.org> // Adapted from LexPerl by Kein-Hong Man 2004 // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif #define HERE_DELIM_MAX 256 // define this if you want 'invalid octals' to be marked as errors // usually, this is not a good idea, permissive lexing is better #undef PEDANTIC_OCTAL #define BASH_BASE_ERROR 65 #define BASH_BASE_DECIMAL 66 #define BASH_BASE_HEX 67 #ifdef PEDANTIC_OCTAL #define BASH_BASE_OCTAL 68 #define BASH_BASE_OCTAL_ERROR 69 #endif // state constants for parts of a bash command segment #define BASH_CMD_BODY 0 #define BASH_CMD_START 1 #define BASH_CMD_WORD 2 #define BASH_CMD_TEST 3 #define BASH_CMD_ARITH 4 #define BASH_CMD_DELIM 5 // state constants for nested delimiter pairs, used by // SCE_SH_STRING and SCE_SH_BACKTICKS processing #define BASH_DELIM_LITERAL 0 #define BASH_DELIM_STRING 1 #define BASH_DELIM_CSTRING 2 #define BASH_DELIM_LSTRING 3 #define BASH_DELIM_COMMAND 4 #define BASH_DELIM_BACKTICK 5 #define BASH_DELIM_STACK_MAX 7 static inline int translateBashDigit(int ch) { if (ch >= '0' && ch <= '9') { return ch - '0'; } else if (ch >= 'a' && ch <= 'z') { return ch - 'a' + 10; } else if (ch >= 'A' && ch <= 'Z') { return ch - 'A' + 36; } else if (ch == '@') { return 62; } else if (ch == '_') { return 63; } return BASH_BASE_ERROR; } static inline int getBashNumberBase(char *s) { int i = 0; int base = 0; while (*s) { base = base * 10 + (*s++ - '0'); i++; } if (base > 64 || i > 2) { return BASH_BASE_ERROR; } return base; } static int opposite(int ch) { if (ch == '(') return ')'; if (ch == '[') return ']'; if (ch == '{') return '}'; if (ch == '<') return '>'; return ch; } static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList cmdDelimiter, bashStruct, bashStruct_in; cmdDelimiter.Set("| || |& & && ; ;; ( ) { }"); bashStruct.Set("if elif fi while until else then do done esac eval"); bashStruct_in.Set("for case select"); CharacterSet setWordStart(CharacterSet::setAlpha, "_"); // note that [+-] are often parts of identifiers in shell scripts CharacterSet setWord(CharacterSet::setAlphaNum, "._+-"); CharacterSet setBashOperator(CharacterSet::setNone, "^&%()-+=|{}[]:;>,*/<?!.~@"); CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMACahGLNn"); CharacterSet setParam(CharacterSet::setAlphaNum, "$_"); CharacterSet setHereDoc(CharacterSet::setAlpha, "_\\-+!"); CharacterSet setHereDoc2(CharacterSet::setAlphaNum, "_-+!"); CharacterSet setLeftShift(CharacterSet::setDigits, "=$"); class HereDocCls { // Class to manage HERE document elements public: int State; // 0: '<<' encountered // 1: collect the delimiter // 2: here doc text (lines after the delimiter) int Quote; // the char after '<<' bool Quoted; // true if Quote in ('\'','"','`') bool Indent; // indented delimiter (for <<-) int DelimiterLength; // strlen(Delimiter) char *Delimiter; // the Delimiter, 256: sizeof PL_tokenbuf HereDocCls() { State = 0; Quote = 0; Quoted = false; Indent = 0; DelimiterLength = 0; Delimiter = new char[HERE_DELIM_MAX]; Delimiter[0] = '\0'; } void Append(int ch) { Delimiter[DelimiterLength++] = static_cast<char>(ch); Delimiter[DelimiterLength] = '\0'; } ~HereDocCls() { delete []Delimiter; } }; HereDocCls HereDoc; class QuoteCls { // Class to manage quote pairs (simplified vs LexPerl) public: int Count; int Up, Down; QuoteCls() { Count = 0; Up = '\0'; Down = '\0'; } void Open(int u) { Count++; Up = u; Down = opposite(Up); } void Start(int u) { Count = 0; Open(u); } }; QuoteCls Quote; class QuoteStackCls { // Class to manage quote pairs that nest public: int Count; int Up, Down; int Style; int Depth; // levels pushed int *CountStack; int *UpStack; int *StyleStack; QuoteStackCls() { Count = 0; Up = '\0'; Down = '\0'; Style = 0; Depth = 0; CountStack = new int[BASH_DELIM_STACK_MAX]; UpStack = new int[BASH_DELIM_STACK_MAX]; StyleStack = new int[BASH_DELIM_STACK_MAX]; } void Start(int u, int s) { Count = 1; Up = u; Down = opposite(Up); Style = s; } void Push(int u, int s) { if (Depth >= BASH_DELIM_STACK_MAX) return; CountStack[Depth] = Count; UpStack [Depth] = Up; StyleStack[Depth] = Style; Depth++; Count = 1; Up = u; Down = opposite(Up); Style = s; } void Pop(void) { if (Depth <= 0) return; Depth--; Count = CountStack[Depth]; Up = UpStack [Depth]; Style = StyleStack[Depth]; Down = opposite(Up); } ~QuoteStackCls() { delete []CountStack; delete []UpStack; delete []StyleStack; } }; QuoteStackCls QuoteStack; int numBase = 0; int digit; unsigned int endPos = startPos + length; int cmdState = BASH_CMD_START; int testExprType = 0; // Always backtracks to the start of a line that is not a continuation // of the previous line (i.e. start of a bash command segment) int ln = styler.GetLine(startPos); if (ln > 0 && startPos == static_cast<unsigned int>(styler.LineStart(ln))) ln--; for (;;) { startPos = styler.LineStart(ln); if (ln == 0 || styler.GetLineState(ln) == BASH_CMD_START) break; ln--; } initStyle = SCE_SH_DEFAULT; StyleContext sc(startPos, endPos - startPos, initStyle, styler); for (; sc.More(); sc.Forward()) { // handle line continuation, updates per-line stored state if (sc.atLineStart) { ln = styler.GetLine(sc.currentPos); if (sc.state == SCE_SH_STRING || sc.state == SCE_SH_BACKTICKS || sc.state == SCE_SH_CHARACTER || sc.state == SCE_SH_HERE_Q || sc.state == SCE_SH_COMMENTLINE || sc.state == SCE_SH_PARAM) { // force backtrack while retaining cmdState styler.SetLineState(ln, BASH_CMD_BODY); } else { if (ln > 0) { if ((sc.GetRelative(-3) == '\\' && sc.GetRelative(-2) == '\r' && sc.chPrev == '\n') || sc.GetRelative(-2) == '\\') { // handle '\' line continuation // retain last line's state } else cmdState = BASH_CMD_START; } styler.SetLineState(ln, cmdState); } } // controls change of cmdState at the end of a non-whitespace element // states BODY|TEST|ARITH persist until the end of a command segment // state WORD persist, but ends with 'in' or 'do' construct keywords int cmdStateNew = BASH_CMD_BODY; if (cmdState == BASH_CMD_TEST || cmdState == BASH_CMD_ARITH || cmdState == BASH_CMD_WORD) cmdStateNew = cmdState; int stylePrev = sc.state; // Determine if the current state should terminate. switch (sc.state) { case SCE_SH_OPERATOR: sc.SetState(SCE_SH_DEFAULT); if (cmdState == BASH_CMD_DELIM) // if command delimiter, start new command cmdStateNew = BASH_CMD_START; else if (sc.chPrev == '\\') // propagate command state if line continued cmdStateNew = cmdState; break; case SCE_SH_WORD: // "." never used in Bash variable names but used in file names if (!setWord.Contains(sc.ch)) { char s[500]; char s2[10]; sc.GetCurrent(s, sizeof(s)); // allow keywords ending in a whitespace or command delimiter s2[0] = static_cast<char>(sc.ch); s2[1] = '\0'; bool keywordEnds = IsASpace(sc.ch) || cmdDelimiter.InList(s2); // 'in' or 'do' may be construct keywords if (cmdState == BASH_CMD_WORD) { if (strcmp(s, "in") == 0 && keywordEnds) cmdStateNew = BASH_CMD_BODY; else if (strcmp(s, "do") == 0 && keywordEnds) cmdStateNew = BASH_CMD_START; else sc.ChangeState(SCE_SH_IDENTIFIER); sc.SetState(SCE_SH_DEFAULT); break; } // a 'test' keyword starts a test expression if (strcmp(s, "test") == 0) { if (cmdState == BASH_CMD_START && keywordEnds) { cmdStateNew = BASH_CMD_TEST; testExprType = 0; } else sc.ChangeState(SCE_SH_IDENTIFIER); } // detect bash construct keywords else if (bashStruct.InList(s)) { if (cmdState == BASH_CMD_START && keywordEnds) cmdStateNew = BASH_CMD_START; else sc.ChangeState(SCE_SH_IDENTIFIER); } // 'for'|'case'|'select' needs 'in'|'do' to be highlighted later else if (bashStruct_in.InList(s)) { if (cmdState == BASH_CMD_START && keywordEnds) cmdStateNew = BASH_CMD_WORD; else sc.ChangeState(SCE_SH_IDENTIFIER); } // disambiguate option items and file test operators else if (s[0] == '-') { if (cmdState != BASH_CMD_TEST) sc.ChangeState(SCE_SH_IDENTIFIER); } // disambiguate keywords and identifiers else if (cmdState != BASH_CMD_START || !(keywords.InList(s) && keywordEnds)) { sc.ChangeState(SCE_SH_IDENTIFIER); } sc.SetState(SCE_SH_DEFAULT); } break; case SCE_SH_IDENTIFIER: if (sc.chPrev == '\\') { // for escaped chars sc.ForwardSetState(SCE_SH_DEFAULT); } else if (!setWord.Contains(sc.ch)) { sc.SetState(SCE_SH_DEFAULT); } break; case SCE_SH_NUMBER: digit = translateBashDigit(sc.ch); if (numBase == BASH_BASE_DECIMAL) { if (sc.ch == '#') { char s[10]; sc.GetCurrent(s, sizeof(s)); numBase = getBashNumberBase(s); if (numBase != BASH_BASE_ERROR) break; } else if (IsADigit(sc.ch)) break; } else if (numBase == BASH_BASE_HEX) { if (IsADigit(sc.ch, 16)) break; #ifdef PEDANTIC_OCTAL } else if (numBase == BASH_BASE_OCTAL || numBase == BASH_BASE_OCTAL_ERROR) { if (digit <= 7) break; if (digit <= 9) { numBase = BASH_BASE_OCTAL_ERROR; break; } #endif } else if (numBase == BASH_BASE_ERROR) { if (digit <= 9) break; } else { // DD#DDDD number style handling if (digit != BASH_BASE_ERROR) { if (numBase <= 36) { // case-insensitive if base<=36 if (digit >= 36) digit -= 26; } if (digit < numBase) break; if (digit <= 9) { numBase = BASH_BASE_ERROR; break; } } } // fallthrough when number is at an end or error if (numBase == BASH_BASE_ERROR #ifdef PEDANTIC_OCTAL || numBase == BASH_BASE_OCTAL_ERROR #endif ) { sc.ChangeState(SCE_SH_ERROR); } sc.SetState(SCE_SH_DEFAULT); break; case SCE_SH_COMMENTLINE: if (sc.atLineEnd && sc.chPrev != '\\') { sc.SetState(SCE_SH_DEFAULT); } break; case SCE_SH_HERE_DELIM: // From Bash info: // --------------- // Specifier format is: <<[-]WORD // Optional '-' is for removal of leading tabs from here-doc. // Whitespace acceptable after <<[-] operator // if (HereDoc.State == 0) { // '<<' encountered HereDoc.Quote = sc.chNext; HereDoc.Quoted = false; HereDoc.DelimiterLength = 0; HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0'; if (sc.chNext == '\'' || sc.chNext == '\"') { // a quoted here-doc delimiter (' or ") sc.Forward(); HereDoc.Quoted = true; HereDoc.State = 1; } else if (!HereDoc.Indent && sc.chNext == '-') { // <<- indent case HereDoc.Indent = true; } else if (setHereDoc.Contains(sc.chNext)) { // an unquoted here-doc delimiter, no special handling // TODO check what exactly bash considers part of the delim HereDoc.State = 1; } else if (sc.chNext == '<') { // HERE string <<< sc.Forward(); sc.ForwardSetState(SCE_SH_DEFAULT); } else if (IsASpace(sc.chNext)) { // eat whitespace } else if (setLeftShift.Contains(sc.chNext)) { // left shift << or <<= operator cases sc.ChangeState(SCE_SH_OPERATOR); sc.ForwardSetState(SCE_SH_DEFAULT); } else { // symbols terminates; deprecated zero-length delimiter HereDoc.State = 1; } } else if (HereDoc.State == 1) { // collect the delimiter if (setHereDoc2.Contains(sc.ch) || sc.chPrev == '\\') { HereDoc.Append(sc.ch); } else if (HereDoc.Quoted && sc.ch == HereDoc.Quote) { // closing quote => end of delimiter sc.ForwardSetState(SCE_SH_DEFAULT); } else if (sc.ch == '\\') { // skip escape prefix } else if (!HereDoc.Quoted) { sc.SetState(SCE_SH_DEFAULT); } if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) { // force blowup sc.SetState(SCE_SH_ERROR); HereDoc.State = 0; } } break; case SCE_SH_HERE_Q: // HereDoc.State == 2 if (sc.atLineStart) { sc.SetState(SCE_SH_HERE_Q); int prefixws = 0; while (IsASpace(sc.ch) && !sc.atLineEnd) { // whitespace prefix sc.Forward(); prefixws++; } if (prefixws > 0) sc.SetState(SCE_SH_HERE_Q); while (!sc.atLineEnd) { sc.Forward(); } char s[HERE_DELIM_MAX]; sc.GetCurrent(s, sizeof(s)); if (sc.LengthCurrent() == 0) { // '' or "" delimiters if (prefixws == 0 && HereDoc.Quoted && HereDoc.DelimiterLength == 0) sc.SetState(SCE_SH_DEFAULT); break; } if (s[strlen(s) - 1] == '\r') s[strlen(s) - 1] = '\0'; if (strcmp(HereDoc.Delimiter, s) == 0) { if ((prefixws == 0) || // indentation rule (prefixws > 0 && HereDoc.Indent)) { sc.SetState(SCE_SH_DEFAULT); break; } } } break; case SCE_SH_SCALAR: // variable names if (!setParam.Contains(sc.ch)) { if (sc.LengthCurrent() == 1) { // Special variable: $(, $_ etc. sc.ForwardSetState(SCE_SH_DEFAULT); } else { sc.SetState(SCE_SH_DEFAULT); } } break; case SCE_SH_STRING: // delimited styles, can nest case SCE_SH_BACKTICKS: if (sc.ch == '\\' && QuoteStack.Up != '\\') { if (QuoteStack.Style != BASH_DELIM_LITERAL) sc.Forward(); } else if (sc.ch == QuoteStack.Down) { QuoteStack.Count--; if (QuoteStack.Count == 0) { if (QuoteStack.Depth > 0) { QuoteStack.Pop(); } else sc.ForwardSetState(SCE_SH_DEFAULT); } } else if (sc.ch == QuoteStack.Up) { QuoteStack.Count++; } else { if (QuoteStack.Style == BASH_DELIM_STRING || QuoteStack.Style == BASH_DELIM_LSTRING ) { // do nesting for "string", $"locale-string" if (sc.ch == '`') { QuoteStack.Push(sc.ch, BASH_DELIM_BACKTICK); } else if (sc.ch == '$' && sc.chNext == '(') { sc.Forward(); QuoteStack.Push(sc.ch, BASH_DELIM_COMMAND); } } else if (QuoteStack.Style == BASH_DELIM_COMMAND || QuoteStack.Style == BASH_DELIM_BACKTICK ) { // do nesting for $(command), `command` if (sc.ch == '\'') { QuoteStack.Push(sc.ch, BASH_DELIM_LITERAL); } else if (sc.ch == '\"') { QuoteStack.Push(sc.ch, BASH_DELIM_STRING); } else if (sc.ch == '`') { QuoteStack.Push(sc.ch, BASH_DELIM_BACKTICK); } else if (sc.ch == '$') { if (sc.chNext == '\'') { sc.Forward(); QuoteStack.Push(sc.ch, BASH_DELIM_CSTRING); } else if (sc.chNext == '\"') { sc.Forward(); QuoteStack.Push(sc.ch, BASH_DELIM_LSTRING); } else if (sc.chNext == '(') { sc.Forward(); QuoteStack.Push(sc.ch, BASH_DELIM_COMMAND); } } } } break; case SCE_SH_PARAM: // ${parameter} if (sc.ch == '\\' && Quote.Up != '\\') { sc.Forward(); } else if (sc.ch == Quote.Down) { Quote.Count--; if (Quote.Count == 0) { sc.ForwardSetState(SCE_SH_DEFAULT); } } else if (sc.ch == Quote.Up) { Quote.Count++; } break; case SCE_SH_CHARACTER: // singly-quoted strings if (sc.ch == Quote.Down) { Quote.Count--; if (Quote.Count == 0) { sc.ForwardSetState(SCE_SH_DEFAULT); } } break; } // Must check end of HereDoc state 1 before default state is handled if (HereDoc.State == 1 && sc.atLineEnd) { // Begin of here-doc (the line after the here-doc delimiter): // Lexically, the here-doc starts from the next line after the >>, but the // first line of here-doc seem to follow the style of the last EOL sequence HereDoc.State = 2; if (HereDoc.Quoted) { if (sc.state == SCE_SH_HERE_DELIM) { // Missing quote at end of string! We are stricter than bash. // Colour here-doc anyway while marking this bit as an error. sc.ChangeState(SCE_SH_ERROR); } // HereDoc.Quote always == '\'' sc.SetState(SCE_SH_HERE_Q); } else if (HereDoc.DelimiterLength == 0) { // no delimiter, illegal (but '' and "" are legal) sc.ChangeState(SCE_SH_ERROR); sc.SetState(SCE_SH_DEFAULT); } else { sc.SetState(SCE_SH_HERE_Q); } } // update cmdState about the current command segment if (stylePrev != SCE_SH_DEFAULT && sc.state == SCE_SH_DEFAULT) { cmdState = cmdStateNew; } // Determine if a new state should be entered. if (sc.state == SCE_SH_DEFAULT) { if (sc.ch == '\\') { // Bash can escape any non-newline as a literal sc.SetState(SCE_SH_IDENTIFIER); if (sc.chNext == '\r' || sc.chNext == '\n') sc.SetState(SCE_SH_OPERATOR); } else if (IsADigit(sc.ch)) { sc.SetState(SCE_SH_NUMBER); numBase = BASH_BASE_DECIMAL; if (sc.ch == '0') { // hex,octal if (sc.chNext == 'x' || sc.chNext == 'X') { numBase = BASH_BASE_HEX; sc.Forward(); } else if (IsADigit(sc.chNext)) { #ifdef PEDANTIC_OCTAL numBase = BASH_BASE_OCTAL; #else numBase = BASH_BASE_HEX; #endif } } } else if (setWordStart.Contains(sc.ch)) { sc.SetState(SCE_SH_WORD); } else if (sc.ch == '#') { sc.SetState(SCE_SH_COMMENTLINE); } else if (sc.ch == '\"') { sc.SetState(SCE_SH_STRING); QuoteStack.Start(sc.ch, BASH_DELIM_STRING); } else if (sc.ch == '\'') { sc.SetState(SCE_SH_CHARACTER); Quote.Start(sc.ch); } else if (sc.ch == '`') { sc.SetState(SCE_SH_BACKTICKS); QuoteStack.Start(sc.ch, BASH_DELIM_BACKTICK); } else if (sc.ch == '$') { if (sc.Match("$((")) { sc.SetState(SCE_SH_OPERATOR); // handle '((' later continue; } sc.SetState(SCE_SH_SCALAR); sc.Forward(); if (sc.ch == '{') { sc.ChangeState(SCE_SH_PARAM); Quote.Start(sc.ch); } else if (sc.ch == '\'') { sc.ChangeState(SCE_SH_STRING); QuoteStack.Start(sc.ch, BASH_DELIM_CSTRING); } else if (sc.ch == '"') { sc.ChangeState(SCE_SH_STRING); QuoteStack.Start(sc.ch, BASH_DELIM_LSTRING); } else if (sc.ch == '(') { sc.ChangeState(SCE_SH_BACKTICKS); QuoteStack.Start(sc.ch, BASH_DELIM_COMMAND); } else if (sc.ch == '`') { // $` seen in a configure script, valid? sc.ChangeState(SCE_SH_BACKTICKS); QuoteStack.Start(sc.ch, BASH_DELIM_BACKTICK); } else { continue; // scalar has no delimiter pair } } else if (sc.Match('<', '<')) { sc.SetState(SCE_SH_HERE_DELIM); HereDoc.State = 0; HereDoc.Indent = false; } else if (sc.ch == '-' && // one-char file test operators setSingleCharOp.Contains(sc.chNext) && !setWord.Contains(sc.GetRelative(2)) && IsASpace(sc.chPrev)) { sc.SetState(SCE_SH_WORD); sc.Forward(); } else if (setBashOperator.Contains(sc.ch)) { char s[10]; bool isCmdDelim = false; sc.SetState(SCE_SH_OPERATOR); // handle opening delimiters for test/arithmetic expressions - ((,[[,[ if (cmdState == BASH_CMD_START || cmdState == BASH_CMD_BODY) { if (sc.Match('(', '(')) { cmdState = BASH_CMD_ARITH; sc.Forward(); } else if (sc.Match('[', '[') && IsASpace(sc.GetRelative(2))) { cmdState = BASH_CMD_TEST; testExprType = 1; sc.Forward(); } else if (sc.ch == '[' && IsASpace(sc.chNext)) { cmdState = BASH_CMD_TEST; testExprType = 2; } } // special state -- for ((x;y;z)) in ... looping if (cmdState == BASH_CMD_WORD && sc.Match('(', '(')) { cmdState = BASH_CMD_ARITH; sc.Forward(); continue; } // handle command delimiters in command START|BODY|WORD state, also TEST if 'test' if (cmdState == BASH_CMD_START || cmdState == BASH_CMD_BODY || cmdState == BASH_CMD_WORD || (cmdState == BASH_CMD_TEST && testExprType == 0)) { s[0] = static_cast<char>(sc.ch); if (setBashOperator.Contains(sc.chNext)) { s[1] = static_cast<char>(sc.chNext); s[2] = '\0'; isCmdDelim = cmdDelimiter.InList(s); if (isCmdDelim) sc.Forward(); } if (!isCmdDelim) { s[1] = '\0'; isCmdDelim = cmdDelimiter.InList(s); } if (isCmdDelim) { cmdState = BASH_CMD_DELIM; continue; } } // handle closing delimiters for test/arithmetic expressions - )),]],] if (cmdState == BASH_CMD_ARITH && sc.Match(')', ')')) { cmdState = BASH_CMD_BODY; sc.Forward(); } else if (cmdState == BASH_CMD_TEST && IsASpace(sc.chPrev)) { if (sc.Match(']', ']') && testExprType == 1) { sc.Forward(); cmdState = BASH_CMD_BODY; } else if (sc.ch == ']' && testExprType == 2) { cmdState = BASH_CMD_BODY; } } } }// sc.state } sc.Complete(); if (sc.state == SCE_SH_HERE_Q) { styler.ChangeLexerState(sc.currentPos, styler.Length()); } sc.Complete(); } static bool IsCommentLine(int line, Accessor &styler) { int pos = styler.LineStart(line); int eol_pos = styler.LineStart(line + 1) - 1; for (int i = pos; i < eol_pos; i++) { char ch = styler[i]; if (ch == '#') return true; else if (ch != ' ' && ch != '\t') return false; } return false; } static void FoldBashDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); // Comment folding if (foldComment && atEOL && IsCommentLine(lineCurrent, styler)) { if (!IsCommentLine(lineCurrent - 1, styler) && IsCommentLine(lineCurrent + 1, styler)) levelCurrent++; else if (IsCommentLine(lineCurrent - 1, styler) && !IsCommentLine(lineCurrent + 1, styler)) levelCurrent--; } if (style == SCE_SH_OPERATOR) { if (ch == '{') { levelCurrent++; } else if (ch == '}') { levelCurrent--; } } // Here Document folding if (style == SCE_SH_HERE_DELIM) { if (ch == '<' && chNext == '<') { levelCurrent++; } } else if (style == SCE_SH_HERE_Q && styler.StyleAt(i+1) == SCE_SH_DEFAULT) { levelCurrent--; } if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char * const bashWordListDesc[] = { "Keywords", 0 }; LexerModule lmBash(SCLEX_BASH, ColouriseBashDoc, "bash", FoldBashDoc, bashWordListDesc); |
Added lexers/LexBasic.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 |
// Scintilla source code edit control /** @file LexBasic.cxx ** Lexer for BlitzBasic and PureBasic. ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net> **/ // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. // This tries to be a unified Lexer/Folder for all the BlitzBasic/BlitzMax/PurBasic basics // and derivatives. Once they diverge enough, might want to split it into multiple // lexers for more code clearity. // // Mail me (elias <at> users <dot> sf <dot> net) for any bugs. // Folding only works for simple things like functions or types. // You may want to have a look at my ctags lexer as well, if you additionally to coloring // and folding need to extract things like label tags in your editor. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include <string> #include <map> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #include "OptionSet.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif /* Bits: * 1 - whitespace * 2 - operator * 4 - identifier * 8 - decimal digit * 16 - hex digit * 32 - bin digit */ static int character_classification[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 2, 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4, 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0 }; static bool IsSpace(int c) { return c < 128 && (character_classification[c] & 1); } static bool IsOperator(int c) { return c < 128 && (character_classification[c] & 2); } static bool IsIdentifier(int c) { return c < 128 && (character_classification[c] & 4); } static bool IsDigit(int c) { return c < 128 && (character_classification[c] & 8); } static bool IsHexDigit(int c) { return c < 128 && (character_classification[c] & 16); } static bool IsBinDigit(int c) { return c < 128 && (character_classification[c] & 32); } static int LowerCase(int c) { if (c >= 'A' && c <= 'Z') return 'a' + c - 'A'; return c; } static int CheckBlitzFoldPoint(char const *token, int &level) { if (!strcmp(token, "function") || !strcmp(token, "type")) { level |= SC_FOLDLEVELHEADERFLAG; return 1; } if (!strcmp(token, "end function") || !strcmp(token, "end type")) { return -1; } return 0; } static int CheckPureFoldPoint(char const *token, int &level) { if (!strcmp(token, "procedure") || !strcmp(token, "enumeration") || !strcmp(token, "interface") || !strcmp(token, "structure")) { level |= SC_FOLDLEVELHEADERFLAG; return 1; } if (!strcmp(token, "endprocedure") || !strcmp(token, "endenumeration") || !strcmp(token, "endinterface") || !strcmp(token, "endstructure")) { return -1; } return 0; } static int CheckFreeFoldPoint(char const *token, int &level) { if (!strcmp(token, "function") || !strcmp(token, "sub") || !strcmp(token, "type")) { level |= SC_FOLDLEVELHEADERFLAG; return 1; } if (!strcmp(token, "end function") || !strcmp(token, "end sub") || !strcmp(token, "end type")) { return -1; } return 0; } // An individual named option for use in an OptionSet // Options used for LexerBasic struct OptionsBasic { bool fold; bool foldSyntaxBased; bool foldCommentExplicit; std::string foldExplicitStart; std::string foldExplicitEnd; bool foldExplicitAnywhere; bool foldCompact; OptionsBasic() { fold = false; foldSyntaxBased = true; foldCommentExplicit = false; foldExplicitStart = ""; foldExplicitEnd = ""; foldExplicitAnywhere = false; foldCompact = true; } }; static const char * const blitzbasicWordListDesc[] = { "BlitzBasic Keywords", "user1", "user2", "user3", 0 }; static const char * const purebasicWordListDesc[] = { "PureBasic Keywords", "PureBasic PreProcessor Keywords", "user defined 1", "user defined 2", 0 }; static const char * const freebasicWordListDesc[] = { "FreeBasic Keywords", "FreeBasic PreProcessor Keywords", "user defined 1", "user defined 2", 0 }; struct OptionSetBasic : public OptionSet<OptionsBasic> { OptionSetBasic(const char * const wordListDescriptions[]) { DefineProperty("fold", &OptionsBasic::fold); DefineProperty("fold.basic.syntax.based", &OptionsBasic::foldSyntaxBased, "Set this property to 0 to disable syntax based folding."); DefineProperty("fold.basic.comment.explicit", &OptionsBasic::foldCommentExplicit, "This option enables folding explicit fold points when using the Basic lexer. " "Explicit fold points allows adding extra folding by placing a ;{ (BB/PB) or '{ (FB) comment at the start " "and a ;} (BB/PB) or '} (FB) at the end of a section that should be folded."); DefineProperty("fold.basic.explicit.start", &OptionsBasic::foldExplicitStart, "The string to use for explicit fold start points, replacing the standard ;{ (BB/PB) or '{ (FB)."); DefineProperty("fold.basic.explicit.end", &OptionsBasic::foldExplicitEnd, "The string to use for explicit fold end points, replacing the standard ;} (BB/PB) or '} (FB)."); DefineProperty("fold.basic.explicit.anywhere", &OptionsBasic::foldExplicitAnywhere, "Set this property to 1 to enable explicit fold points anywhere, not just in line comments."); DefineProperty("fold.compact", &OptionsBasic::foldCompact); DefineWordListSets(wordListDescriptions); } }; class LexerBasic : public ILexer { char comment_char; int (*CheckFoldPoint)(char const *, int &); WordList keywordlists[4]; OptionsBasic options; OptionSetBasic osBasic; public: LexerBasic(char comment_char_, int (*CheckFoldPoint_)(char const *, int &), const char * const wordListDescriptions[]) : comment_char(comment_char_), CheckFoldPoint(CheckFoldPoint_), osBasic(wordListDescriptions) { } virtual ~LexerBasic() { } void SCI_METHOD Release() { delete this; } int SCI_METHOD Version() const { return lvOriginal; } const char * SCI_METHOD PropertyNames() { return osBasic.PropertyNames(); } int SCI_METHOD PropertyType(const char *name) { return osBasic.PropertyType(name); } const char * SCI_METHOD DescribeProperty(const char *name) { return osBasic.DescribeProperty(name); } int SCI_METHOD PropertySet(const char *key, const char *val); const char * SCI_METHOD DescribeWordListSets() { return osBasic.DescribeWordListSets(); } int SCI_METHOD WordListSet(int n, const char *wl); void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess); void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess); void * SCI_METHOD PrivateCall(int, void *) { return 0; } static ILexer *LexerFactoryBlitzBasic() { return new LexerBasic(';', CheckBlitzFoldPoint, blitzbasicWordListDesc); } static ILexer *LexerFactoryPureBasic() { return new LexerBasic(';', CheckPureFoldPoint, purebasicWordListDesc); } static ILexer *LexerFactoryFreeBasic() { return new LexerBasic('\'', CheckFreeFoldPoint, freebasicWordListDesc ); } }; int SCI_METHOD LexerBasic::PropertySet(const char *key, const char *val) { if (osBasic.PropertySet(&options, key, val)) { return 0; } return -1; } int SCI_METHOD LexerBasic::WordListSet(int n, const char *wl) { WordList *wordListN = 0; switch (n) { case 0: wordListN = &keywordlists[0]; break; case 1: wordListN = &keywordlists[1]; break; case 2: wordListN = &keywordlists[2]; break; case 3: wordListN = &keywordlists[3]; break; } int firstModification = -1; if (wordListN) { WordList wlNew; wlNew.Set(wl); if (*wordListN != wlNew) { wordListN->Set(wl); firstModification = 0; } } return firstModification; } void SCI_METHOD LexerBasic::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { LexAccessor styler(pAccess); bool wasfirst = true, isfirst = true; // true if first token in a line styler.StartAt(startPos); StyleContext sc(startPos, length, initStyle, styler); // Can't use sc.More() here else we miss the last character for (; ; sc.Forward()) { if (sc.state == SCE_B_IDENTIFIER) { if (!IsIdentifier(sc.ch)) { // Labels if (wasfirst && sc.Match(':')) { sc.ChangeState(SCE_B_LABEL); sc.ForwardSetState(SCE_B_DEFAULT); } else { char s[100]; int kstates[4] = { SCE_B_KEYWORD, SCE_B_KEYWORD2, SCE_B_KEYWORD3, SCE_B_KEYWORD4, }; sc.GetCurrentLowered(s, sizeof(s)); for (int i = 0; i < 4; i++) { if (keywordlists[i].InList(s)) { sc.ChangeState(kstates[i]); } } // Types, must set them as operator else they will be // matched as number/constant if (sc.Match('.') || sc.Match('$') || sc.Match('%') || sc.Match('#')) { sc.SetState(SCE_B_OPERATOR); } else { sc.SetState(SCE_B_DEFAULT); } } } } else if (sc.state == SCE_B_OPERATOR) { if (!IsOperator(sc.ch) || sc.Match('#')) sc.SetState(SCE_B_DEFAULT); } else if (sc.state == SCE_B_LABEL) { if (!IsIdentifier(sc.ch)) sc.SetState(SCE_B_DEFAULT); } else if (sc.state == SCE_B_CONSTANT) { if (!IsIdentifier(sc.ch)) sc.SetState(SCE_B_DEFAULT); } else if (sc.state == SCE_B_NUMBER) { if (!IsDigit(sc.ch)) sc.SetState(SCE_B_DEFAULT); } else if (sc.state == SCE_B_HEXNUMBER) { if (!IsHexDigit(sc.ch)) sc.SetState(SCE_B_DEFAULT); } else if (sc.state == SCE_B_BINNUMBER) { if (!IsBinDigit(sc.ch)) sc.SetState(SCE_B_DEFAULT); } else if (sc.state == SCE_B_STRING) { if (sc.ch == '"') { sc.ForwardSetState(SCE_B_DEFAULT); } if (sc.atLineEnd) { sc.ChangeState(SCE_B_ERROR); sc.SetState(SCE_B_DEFAULT); } } else if (sc.state == SCE_B_COMMENT || sc.state == SCE_B_PREPROCESSOR) { if (sc.atLineEnd) { sc.SetState(SCE_B_DEFAULT); } } if (sc.atLineStart) isfirst = true; if (sc.state == SCE_B_DEFAULT || sc.state == SCE_B_ERROR) { if (isfirst && sc.Match('.')) { sc.SetState(SCE_B_LABEL); } else if (isfirst && sc.Match('#')) { wasfirst = isfirst; sc.SetState(SCE_B_IDENTIFIER); } else if (sc.Match(comment_char)) { // Hack to make deprecated QBASIC '$Include show // up in freebasic with SCE_B_PREPROCESSOR. if (comment_char == '\'' && sc.Match(comment_char, '$')) sc.SetState(SCE_B_PREPROCESSOR); else sc.SetState(SCE_B_COMMENT); } else if (sc.Match('"')) { sc.SetState(SCE_B_STRING); } else if (IsDigit(sc.ch)) { sc.SetState(SCE_B_NUMBER); } else if (sc.Match('$')) { sc.SetState(SCE_B_HEXNUMBER); } else if (sc.Match('%')) { sc.SetState(SCE_B_BINNUMBER); } else if (sc.Match('#')) { sc.SetState(SCE_B_CONSTANT); } else if (IsOperator(sc.ch)) { sc.SetState(SCE_B_OPERATOR); } else if (IsIdentifier(sc.ch)) { wasfirst = isfirst; sc.SetState(SCE_B_IDENTIFIER); } else if (!IsSpace(sc.ch)) { sc.SetState(SCE_B_ERROR); } } if (!IsSpace(sc.ch)) isfirst = false; if (!sc.More()) break; } sc.Complete(); } void SCI_METHOD LexerBasic::Fold(unsigned int startPos, int length, int /* initStyle */, IDocument *pAccess) { if (!options.fold) return; LexAccessor styler(pAccess); int line = styler.GetLine(startPos); int level = styler.LevelAt(line); int go = 0, done = 0; int endPos = startPos + length; char word[256]; int wordlen = 0; const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty(); int cNext = styler[startPos]; // Scan for tokens at the start of the line (they may include // whitespace, for tokens like "End Function" for (int i = startPos; i < endPos; i++) { int c = cNext; cNext = styler.SafeGetCharAt(i + 1); bool atEOL = (c == '\r' && cNext != '\n') || (c == '\n'); if (options.foldSyntaxBased && !done && !go) { if (wordlen) { // are we scanning a token already? word[wordlen] = static_cast<char>(LowerCase(c)); if (!IsIdentifier(c)) { // done with token word[wordlen] = '\0'; go = CheckFoldPoint(word, level); if (!go) { // Treat any whitespace as single blank, for // things like "End Function". if (IsSpace(c) && IsIdentifier(word[wordlen - 1])) { word[wordlen] = ' '; if (wordlen < 255) wordlen++; } else // done with this line done = 1; } } else if (wordlen < 255) { wordlen++; } } else { // start scanning at first non-whitespace character if (!IsSpace(c)) { if (IsIdentifier(c)) { word[0] = static_cast<char>(LowerCase(c)); wordlen = 1; } else // done with this line done = 1; } } } if (options.foldCommentExplicit && ((styler.StyleAt(i) == SCE_B_COMMENT) || options.foldExplicitAnywhere)) { if (userDefinedFoldMarkers) { if (styler.Match(i, options.foldExplicitStart.c_str())) { level |= SC_FOLDLEVELHEADERFLAG; go = 1; } else if (styler.Match(i, options.foldExplicitEnd.c_str())) { go = -1; } } else { if (c == comment_char) { if (cNext == '{') { level |= SC_FOLDLEVELHEADERFLAG; go = 1; } else if (cNext == '}') { go = -1; } } } } if (atEOL) { // line end if (!done && wordlen == 0 && options.foldCompact) // line was only space level |= SC_FOLDLEVELWHITEFLAG; if (level != styler.LevelAt(line)) styler.SetLevel(line, level); level += go; line++; // reset state wordlen = 0; level &= ~SC_FOLDLEVELHEADERFLAG; level &= ~SC_FOLDLEVELWHITEFLAG; go = 0; done = 0; } } } LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, LexerBasic::LexerFactoryBlitzBasic, "blitzbasic", blitzbasicWordListDesc); LexerModule lmPureBasic(SCLEX_PUREBASIC, LexerBasic::LexerFactoryPureBasic, "purebasic", purebasicWordListDesc); LexerModule lmFreeBasic(SCLEX_FREEBASIC, LexerBasic::LexerFactoryFreeBasic, "freebasic", freebasicWordListDesc); |
Added lexers/LexBullant.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
// SciTE - Scintilla based Text Editor // LexBullant.cxx - lexer for Bullant #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static int classifyWordBullant(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { char s[100]; s[0] = '\0'; for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { s[i] = static_cast<char>(tolower(styler[start + i])); s[i + 1] = '\0'; } int lev= 0; char chAttr = SCE_C_IDENTIFIER; if (isdigit(s[0]) || (s[0] == '.')){ chAttr = SCE_C_NUMBER; } else { if (keywords.InList(s)) { chAttr = SCE_C_WORD; if (strcmp(s, "end") == 0) lev = -1; else if (strcmp(s, "method") == 0 || strcmp(s, "case") == 0 || strcmp(s, "class") == 0 || strcmp(s, "debug") == 0 || strcmp(s, "test") == 0 || strcmp(s, "if") == 0 || strcmp(s, "lock") == 0 || strcmp(s, "transaction") == 0 || strcmp(s, "trap") == 0 || strcmp(s, "until") == 0 || strcmp(s, "while") == 0) lev = 1; } } styler.ColourTo(end, chAttr); return lev; } static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; styler.StartAt(startPos); bool fold = styler.GetPropertyInt("fold") != 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; int state = initStyle; if (state == SCE_C_STRINGEOL) // Does not leak onto next line state = SCE_C_DEFAULT; char chPrev = ' '; char chNext = styler[startPos]; unsigned int lengthDoc = startPos + length; int visibleChars = 0; styler.StartSegment(startPos); int endFoundThisLine = 0; for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) // Avoid triggering two times on Dos/Win // End of line endFoundThisLine = 0; if (state == SCE_C_STRINGEOL) { styler.ColourTo(i, state); state = SCE_C_DEFAULT; } if (fold) { int lev = levelPrev; if (visibleChars == 0) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; styler.SetLevel(lineCurrent, lev); lineCurrent++; levelPrev = levelCurrent; } visibleChars = 0; /* int indentBlock = GetLineIndentation(lineCurrent); if (blockChange==1){ lineCurrent++; int pos=SetLineIndentation(lineCurrent, indentBlock + indentSize); } else if (blockChange==-1) { indentBlock -= indentSize; if (indentBlock < 0) indentBlock = 0; SetLineIndentation(lineCurrent, indentBlock); lineCurrent++; } blockChange=0; */ } if (!(isascii(ch) && isspace(ch))) visibleChars++; if (styler.IsLeadByte(ch)) { chNext = styler.SafeGetCharAt(i + 2); chPrev = ' '; i += 1; continue; } if (state == SCE_C_DEFAULT) { if (iswordstart(ch)) { styler.ColourTo(i-1, state); state = SCE_C_IDENTIFIER; } else if (ch == '@' && chNext == 'o') { if ((styler.SafeGetCharAt(i+2) =='f') && (styler.SafeGetCharAt(i+3) == 'f')) { styler.ColourTo(i-1, state); state = SCE_C_COMMENT; } } else if (ch == '#') { styler.ColourTo(i-1, state); state = SCE_C_COMMENTLINE; } else if (ch == '\"') { styler.ColourTo(i-1, state); state = SCE_C_STRING; } else if (ch == '\'') { styler.ColourTo(i-1, state); state = SCE_C_CHARACTER; } else if (isoperator(ch)) { styler.ColourTo(i-1, state); styler.ColourTo(i, SCE_C_OPERATOR); } } else if (state == SCE_C_IDENTIFIER) { if (!iswordchar(ch)) { int levelChange = classifyWordBullant(styler.GetStartSegment(), i - 1, keywords, styler); state = SCE_C_DEFAULT; chNext = styler.SafeGetCharAt(i + 1); if (ch == '#') { state = SCE_C_COMMENTLINE; } else if (ch == '\"') { state = SCE_C_STRING; } else if (ch == '\'') { state = SCE_C_CHARACTER; } else if (isoperator(ch)) { styler.ColourTo(i, SCE_C_OPERATOR); } if (endFoundThisLine == 0) levelCurrent+=levelChange; if (levelChange == -1) endFoundThisLine=1; } } else if (state == SCE_C_COMMENT) { if (ch == '@' && chNext == 'o') { if (styler.SafeGetCharAt(i+2) == 'n') { styler.ColourTo(i+2, state); state = SCE_C_DEFAULT; i+=2; } } } else if (state == SCE_C_COMMENTLINE) { if (ch == '\r' || ch == '\n') { endFoundThisLine = 0; styler.ColourTo(i-1, state); state = SCE_C_DEFAULT; } } else if (state == SCE_C_STRING) { if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; ch = chNext; chNext = styler.SafeGetCharAt(i + 1); } } else if (ch == '\"') { styler.ColourTo(i, state); state = SCE_C_DEFAULT; } else if (chNext == '\r' || chNext == '\n') { endFoundThisLine = 0; styler.ColourTo(i-1, SCE_C_STRINGEOL); state = SCE_C_STRINGEOL; } } else if (state == SCE_C_CHARACTER) { if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { endFoundThisLine = 0; styler.ColourTo(i-1, SCE_C_STRINGEOL); state = SCE_C_STRINGEOL; } else if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; ch = chNext; chNext = styler.SafeGetCharAt(i + 1); } } else if (ch == '\'') { styler.ColourTo(i, state); state = SCE_C_DEFAULT; } } chPrev = ch; } styler.ColourTo(lengthDoc - 1, state); // Fill in the real level of the next line, keeping the current flags as they will be filled in later if (fold) { int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; //styler.SetLevel(lineCurrent, levelCurrent | flagsNext); styler.SetLevel(lineCurrent, levelPrev | flagsNext); } } static const char * const bullantWordListDesc[] = { "Keywords", 0 }; LexerModule lmBullant(SCLEX_BULLANT, ColouriseBullantDoc, "bullant", 0, bullantWordListDesc); |
Added lexers/LexCLW.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 |
// Scintilla source code edit control /** @file LexClw.cxx ** Lexer for Clarion. ** 2004/12/17 Updated Lexer **/ // Copyright 2003-2004 by Ron Schofield <ron@schofieldcomputer.com> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // Is an end of line character inline bool IsEOL(const int ch) { return(ch == '\n'); } // Convert character to uppercase static char CharacterUpper(char chChar) { if (chChar < 'a' || chChar > 'z') { return(chChar); } else { return(static_cast<char>(chChar - 'a' + 'A')); } } // Convert string to uppercase static void StringUpper(char *szString) { while (*szString) { *szString = CharacterUpper(*szString); szString++; } } // Is a label start character inline bool IsALabelStart(const int iChar) { return(isalpha(iChar) || iChar == '_'); } // Is a label character inline bool IsALabelCharacter(const int iChar) { return(isalnum(iChar) || iChar == '_' || iChar == ':'); } // Is the character is a ! and the the next character is not a ! inline bool IsACommentStart(const int iChar) { return(iChar == '!'); } // Is the character a Clarion hex character (ABCDEF) inline bool IsAHexCharacter(const int iChar, bool bCaseSensitive) { // Case insensitive. if (!bCaseSensitive) { if (strchr("ABCDEFabcdef", iChar) != NULL) { return(true); } } // Case sensitive else { if (strchr("ABCDEF", iChar) != NULL) { return(true); } } return(false); } // Is the character a Clarion base character (B=Binary, O=Octal, H=Hex) inline bool IsANumericBaseCharacter(const int iChar, bool bCaseSensitive) { // Case insensitive. if (!bCaseSensitive) { // If character is a numeric base character if (strchr("BOHboh", iChar) != NULL) { return(true); } } // Case sensitive else { // If character is a numeric base character if (strchr("BOH", iChar) != NULL) { return(true); } } return(false); } // Set the correct numeric constant state inline bool SetNumericConstantState(StyleContext &scDoc) { int iPoints = 0; // Point counter char cNumericString[512]; // Numeric string buffer // Buffer the current numberic string scDoc.GetCurrent(cNumericString, sizeof(cNumericString)); // Loop through the string until end of string (NULL termination) for (int iIndex = 0; cNumericString[iIndex] != '\0'; iIndex++) { // Depending on the character switch (cNumericString[iIndex]) { // Is a . (point) case '.' : // Increment point counter iPoints++; break; default : break; } } // If points found (can be more than one for improper formatted number if (iPoints > 0) { return(true); } // Else no points found else { return(false); } } // Get the next word in uppercase from the current position (keyword lookahead) inline bool GetNextWordUpper(Accessor &styler, unsigned int uiStartPos, int iLength, char *cWord) { unsigned int iIndex = 0; // Buffer Index // Loop through the remaining string from the current position for (int iOffset = uiStartPos; iOffset < iLength; iOffset++) { // Get the character from the buffer using the offset char cCharacter = styler[iOffset]; if (IsEOL(cCharacter)) { break; } // If the character is alphabet character if (isalpha(cCharacter)) { // Add UPPERCASE character to the word buffer cWord[iIndex++] = CharacterUpper(cCharacter); } } // Add null termination cWord[iIndex] = '\0'; // If no word was found if (iIndex == 0) { // Return failure return(false); } // Else word was found else { // Return success return(true); } } // Clarion Language Colouring Procedure static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler, bool bCaseSensitive) { int iParenthesesLevel = 0; // Parenthese Level int iColumn1Label = false; // Label starts in Column 1 WordList &wlClarionKeywords = *wlKeywords[0]; // Clarion Keywords WordList &wlCompilerDirectives = *wlKeywords[1]; // Compiler Directives WordList &wlRuntimeExpressions = *wlKeywords[2]; // Runtime Expressions WordList &wlBuiltInProcsFuncs = *wlKeywords[3]; // Builtin Procedures and Functions WordList &wlStructsDataTypes = *wlKeywords[4]; // Structures and Data Types WordList &wlAttributes = *wlKeywords[5]; // Procedure Attributes WordList &wlStandardEquates = *wlKeywords[6]; // Standard Equates WordList &wlLabelReservedWords = *wlKeywords[7]; // Clarion Reserved Keywords (Labels) WordList &wlProcLabelReservedWords = *wlKeywords[8]; // Clarion Reserved Keywords (Procedure Labels) const char wlProcReservedKeywordList[] = "PROCEDURE FUNCTION"; WordList wlProcReservedKeywords; wlProcReservedKeywords.Set(wlProcReservedKeywordList); const char wlCompilerKeywordList[] = "COMPILE OMIT"; WordList wlCompilerKeywords; wlCompilerKeywords.Set(wlCompilerKeywordList); const char wlLegacyStatementsList[] = "BOF EOF FUNCTION POINTER SHARE"; WordList wlLegacyStatements; wlLegacyStatements.Set(wlLegacyStatementsList); StyleContext scDoc(uiStartPos, iLength, iInitStyle, accStyler); // lex source code for (; scDoc.More(); scDoc.Forward()) { // // Determine if the current state should terminate. // // Label State Handling if (scDoc.state == SCE_CLW_LABEL) { // If the character is not a valid label if (!IsALabelCharacter(scDoc.ch)) { // If the character is a . (dot syntax) if (scDoc.ch == '.') { // Turn off column 1 label flag as label now cannot be reserved work iColumn1Label = false; // Uncolour the . (dot) to default state, move forward one character, // and change back to the label state. scDoc.SetState(SCE_CLW_DEFAULT); scDoc.Forward(); scDoc.SetState(SCE_CLW_LABEL); } // Else check label else { char cLabel[512]; // Label buffer // Buffer the current label string scDoc.GetCurrent(cLabel,sizeof(cLabel)); // If case insensitive, convert string to UPPERCASE to match passed keywords. if (!bCaseSensitive) { StringUpper(cLabel); } // Else if UPPERCASE label string is in the Clarion compiler keyword list if (wlCompilerKeywords.InList(cLabel) && iColumn1Label){ // change the label to error state scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE); } // Else if UPPERCASE label string is in the Clarion reserved keyword list else if (wlLabelReservedWords.InList(cLabel) && iColumn1Label){ // change the label to error state scDoc.ChangeState(SCE_CLW_ERROR); } // Else if UPPERCASE label string is else if (wlProcLabelReservedWords.InList(cLabel) && iColumn1Label) { char cWord[512]; // Word buffer // Get the next word from the current position if (GetNextWordUpper(accStyler,scDoc.currentPos,uiStartPos+iLength,cWord)) { // If the next word is a procedure reserved word if (wlProcReservedKeywords.InList(cWord)) { // Change the label to error state scDoc.ChangeState(SCE_CLW_ERROR); } } } // Else if label string is in the compiler directive keyword list else if (wlCompilerDirectives.InList(cLabel)) { // change the state to compiler directive state scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE); } // Terminate the label state and set to default state scDoc.SetState(SCE_CLW_DEFAULT); } } } // Keyword State Handling else if (scDoc.state == SCE_CLW_KEYWORD) { // If character is : (colon) if (scDoc.ch == ':') { char cEquate[512]; // Equate buffer // Move forward to include : (colon) in buffer scDoc.Forward(); // Buffer the equate string scDoc.GetCurrent(cEquate,sizeof(cEquate)); // If case insensitive, convert string to UPPERCASE to match passed keywords. if (!bCaseSensitive) { StringUpper(cEquate); } // If statement string is in the equate list if (wlStandardEquates.InList(cEquate)) { // Change to equate state scDoc.ChangeState(SCE_CLW_STANDARD_EQUATE); } } // If the character is not a valid label character else if (!IsALabelCharacter(scDoc.ch)) { char cStatement[512]; // Statement buffer // Buffer the statement string scDoc.GetCurrent(cStatement,sizeof(cStatement)); // If case insensitive, convert string to UPPERCASE to match passed keywords. if (!bCaseSensitive) { StringUpper(cStatement); } // If statement string is in the Clarion keyword list if (wlClarionKeywords.InList(cStatement)) { // Change the statement string to the Clarion keyword state scDoc.ChangeState(SCE_CLW_KEYWORD); } // Else if statement string is in the compiler directive keyword list else if (wlCompilerDirectives.InList(cStatement)) { // Change the statement string to the compiler directive state scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE); } // Else if statement string is in the runtime expressions keyword list else if (wlRuntimeExpressions.InList(cStatement)) { // Change the statement string to the runtime expressions state scDoc.ChangeState(SCE_CLW_RUNTIME_EXPRESSIONS); } // Else if statement string is in the builtin procedures and functions keyword list else if (wlBuiltInProcsFuncs.InList(cStatement)) { // Change the statement string to the builtin procedures and functions state scDoc.ChangeState(SCE_CLW_BUILTIN_PROCEDURES_FUNCTION); } // Else if statement string is in the tructures and data types keyword list else if (wlStructsDataTypes.InList(cStatement)) { // Change the statement string to the structures and data types state scDoc.ChangeState(SCE_CLW_STRUCTURE_DATA_TYPE); } // Else if statement string is in the procedure attribute keyword list else if (wlAttributes.InList(cStatement)) { // Change the statement string to the procedure attribute state scDoc.ChangeState(SCE_CLW_ATTRIBUTE); } // Else if statement string is in the standard equate keyword list else if (wlStandardEquates.InList(cStatement)) { // Change the statement string to the standard equate state scDoc.ChangeState(SCE_CLW_STANDARD_EQUATE); } // Else if statement string is in the deprecated or legacy keyword list else if (wlLegacyStatements.InList(cStatement)) { // Change the statement string to the standard equate state scDoc.ChangeState(SCE_CLW_DEPRECATED); } // Else the statement string doesn't match any work list else { // Change the statement string to the default state scDoc.ChangeState(SCE_CLW_DEFAULT); } // Terminate the keyword state and set to default state scDoc.SetState(SCE_CLW_DEFAULT); } } // String State Handling else if (scDoc.state == SCE_CLW_STRING) { // If the character is an ' (single quote) if (scDoc.ch == '\'') { // Set the state to default and move forward colouring // the ' (single quote) as default state // terminating the string state scDoc.SetState(SCE_CLW_DEFAULT); scDoc.Forward(); } // If the next character is an ' (single quote) if (scDoc.chNext == '\'') { // Move forward one character and set to default state // colouring the next ' (single quote) as default state // terminating the string state scDoc.ForwardSetState(SCE_CLW_DEFAULT); scDoc.Forward(); } } // Picture String State Handling else if (scDoc.state == SCE_CLW_PICTURE_STRING) { // If the character is an ( (open parenthese) if (scDoc.ch == '(') { // Increment the parenthese level iParenthesesLevel++; } // Else if the character is a ) (close parenthese) else if (scDoc.ch == ')') { // If the parenthese level is set to zero // parentheses matched if (!iParenthesesLevel) { scDoc.SetState(SCE_CLW_DEFAULT); } // Else parenthese level is greater than zero // still looking for matching parentheses else { // Decrement the parenthese level iParenthesesLevel--; } } } // Standard Equate State Handling else if (scDoc.state == SCE_CLW_STANDARD_EQUATE) { if (!isalnum(scDoc.ch)) { scDoc.SetState(SCE_CLW_DEFAULT); } } // Integer Constant State Handling else if (scDoc.state == SCE_CLW_INTEGER_CONSTANT) { // If the character is not a digit (0-9) // or character is not a hexidecimal character (A-F) // or character is not a . (point) // or character is not a numberic base character (B,O,H) if (!(isdigit(scDoc.ch) || IsAHexCharacter(scDoc.ch, bCaseSensitive) || scDoc.ch == '.' || IsANumericBaseCharacter(scDoc.ch, bCaseSensitive))) { // If the number was a real if (SetNumericConstantState(scDoc)) { // Colour the matched string to the real constant state scDoc.ChangeState(SCE_CLW_REAL_CONSTANT); } // Else the number was an integer else { // Colour the matched string to an integer constant state scDoc.ChangeState(SCE_CLW_INTEGER_CONSTANT); } // Terminate the integer constant state and set to default state scDoc.SetState(SCE_CLW_DEFAULT); } } // // Determine if a new state should be entered. // // Beginning of Line Handling if (scDoc.atLineStart) { // Reset the column 1 label flag iColumn1Label = false; // If column 1 character is a label start character if (IsALabelStart(scDoc.ch)) { // Label character is found in column 1 // so set column 1 label flag and clear last column 1 label iColumn1Label = true; // Set the state to label scDoc.SetState(SCE_CLW_LABEL); } // else if character is a space or tab else if (IsASpace(scDoc.ch)){ // Set to default state scDoc.SetState(SCE_CLW_DEFAULT); } // else if comment start (!) or is an * (asterisk) else if (IsACommentStart(scDoc.ch) || scDoc.ch == '*' ) { // then set the state to comment. scDoc.SetState(SCE_CLW_COMMENT); } // else the character is a ? (question mark) else if (scDoc.ch == '?') { // Change to the compiler directive state, move forward, // colouring the ? (question mark), change back to default state. scDoc.ChangeState(SCE_CLW_COMPILER_DIRECTIVE); scDoc.Forward(); scDoc.SetState(SCE_CLW_DEFAULT); } // else an invalid character in column 1 else { // Set to error state scDoc.SetState(SCE_CLW_ERROR); } } // End of Line Handling else if (scDoc.atLineEnd) { // Reset to the default state at the end of each line. scDoc.SetState(SCE_CLW_DEFAULT); } // Default Handling else { // If in default state if (scDoc.state == SCE_CLW_DEFAULT) { // If is a letter could be a possible statement if (isalpha(scDoc.ch)) { // Set the state to Clarion Keyword and verify later scDoc.SetState(SCE_CLW_KEYWORD); } // else is a number else if (isdigit(scDoc.ch)) { // Set the state to Integer Constant and verify later scDoc.SetState(SCE_CLW_INTEGER_CONSTANT); } // else if the start of a comment or a | (line continuation) else if (IsACommentStart(scDoc.ch) || scDoc.ch == '|') { // then set the state to comment. scDoc.SetState(SCE_CLW_COMMENT); } // else if the character is a ' (single quote) else if (scDoc.ch == '\'') { // If the character is also a ' (single quote) // Embedded Apostrophe if (scDoc.chNext == '\'') { // Move forward colouring it as default state scDoc.ForwardSetState(SCE_CLW_DEFAULT); } else { // move to the next character and then set the state to comment. scDoc.ForwardSetState(SCE_CLW_STRING); } } // else the character is an @ (ampersand) else if (scDoc.ch == '@') { // Case insensitive. if (!bCaseSensitive) { // If character is a valid picture token character if (strchr("DEKNPSTdeknpst", scDoc.chNext) != NULL) { // Set to the picture string state scDoc.SetState(SCE_CLW_PICTURE_STRING); } } // Case sensitive else { // If character is a valid picture token character if (strchr("DEKNPST", scDoc.chNext) != NULL) { // Set the picture string state scDoc.SetState(SCE_CLW_PICTURE_STRING); } } } } } } // lexing complete scDoc.Complete(); } // Clarion Language Case Sensitive Colouring Procedure static void ColouriseClarionDocSensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) { ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, true); } // Clarion Language Case Insensitive Colouring Procedure static void ColouriseClarionDocInsensitive(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *wlKeywords[], Accessor &accStyler) { ColouriseClarionDoc(uiStartPos, iLength, iInitStyle, wlKeywords, accStyler, false); } // Fill Buffer static void FillBuffer(unsigned int uiStart, unsigned int uiEnd, Accessor &accStyler, char *szBuffer, unsigned int uiLength) { unsigned int uiPos = 0; while ((uiPos < uiEnd - uiStart + 1) && (uiPos < uiLength-1)) { szBuffer[uiPos] = static_cast<char>(toupper(accStyler[uiStart + uiPos])); uiPos++; } szBuffer[uiPos] = '\0'; } // Classify Clarion Fold Point static int ClassifyClarionFoldPoint(int iLevel, const char* szString) { if (!(isdigit(szString[0]) || (szString[0] == '.'))) { if (strcmp(szString, "PROCEDURE") == 0) { // iLevel = SC_FOLDLEVELBASE + 1; } else if (strcmp(szString, "MAP") == 0 || strcmp(szString,"ACCEPT") == 0 || strcmp(szString,"BEGIN") == 0 || strcmp(szString,"CASE") == 0 || strcmp(szString,"EXECUTE") == 0 || strcmp(szString,"IF") == 0 || strcmp(szString,"ITEMIZE") == 0 || strcmp(szString,"INTERFACE") == 0 || strcmp(szString,"JOIN") == 0 || strcmp(szString,"LOOP") == 0 || strcmp(szString,"MODULE") == 0 || strcmp(szString,"RECORD") == 0) { iLevel++; } else if (strcmp(szString, "APPLICATION") == 0 || strcmp(szString, "CLASS") == 0 || strcmp(szString, "DETAIL") == 0 || strcmp(szString, "FILE") == 0 || strcmp(szString, "FOOTER") == 0 || strcmp(szString, "FORM") == 0 || strcmp(szString, "GROUP") == 0 || strcmp(szString, "HEADER") == 0 || strcmp(szString, "INTERFACE") == 0 || strcmp(szString, "MENU") == 0 || strcmp(szString, "MENUBAR") == 0 || strcmp(szString, "OLE") == 0 || strcmp(szString, "OPTION") == 0 || strcmp(szString, "QUEUE") == 0 || strcmp(szString, "REPORT") == 0 || strcmp(szString, "SHEET") == 0 || strcmp(szString, "TAB") == 0 || strcmp(szString, "TOOLBAR") == 0 || strcmp(szString, "VIEW") == 0 || strcmp(szString, "WINDOW") == 0) { iLevel++; } else if (strcmp(szString, "END") == 0 || strcmp(szString, "UNTIL") == 0 || strcmp(szString, "WHILE") == 0) { iLevel--; } } return(iLevel); } // Clarion Language Folding Procedure static void FoldClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle, WordList *[], Accessor &accStyler) { unsigned int uiEndPos = uiStartPos + iLength; int iLineCurrent = accStyler.GetLine(uiStartPos); int iLevelPrev = accStyler.LevelAt(iLineCurrent) & SC_FOLDLEVELNUMBERMASK; int iLevelCurrent = iLevelPrev; char chNext = accStyler[uiStartPos]; int iStyle = iInitStyle; int iStyleNext = accStyler.StyleAt(uiStartPos); int iVisibleChars = 0; int iLastStart = 0; for (unsigned int uiPos = uiStartPos; uiPos < uiEndPos; uiPos++) { char chChar = chNext; chNext = accStyler.SafeGetCharAt(uiPos + 1); int iStylePrev = iStyle; iStyle = iStyleNext; iStyleNext = accStyler.StyleAt(uiPos + 1); bool bEOL = (chChar == '\r' && chNext != '\n') || (chChar == '\n'); if (iStylePrev == SCE_CLW_DEFAULT) { if (iStyle == SCE_CLW_KEYWORD || iStyle == SCE_CLW_STRUCTURE_DATA_TYPE) { // Store last word start point. iLastStart = uiPos; } } if (iStylePrev == SCE_CLW_KEYWORD || iStylePrev == SCE_CLW_STRUCTURE_DATA_TYPE) { if(iswordchar(chChar) && !iswordchar(chNext)) { char chBuffer[100]; FillBuffer(iLastStart, uiPos, accStyler, chBuffer, sizeof(chBuffer)); iLevelCurrent = ClassifyClarionFoldPoint(iLevelCurrent,chBuffer); // if ((iLevelCurrent == SC_FOLDLEVELBASE + 1) && iLineCurrent > 1) { // accStyler.SetLevel(iLineCurrent-1,SC_FOLDLEVELBASE); // iLevelPrev = SC_FOLDLEVELBASE; // } } } if (bEOL) { int iLevel = iLevelPrev; if ((iLevelCurrent > iLevelPrev) && (iVisibleChars > 0)) iLevel |= SC_FOLDLEVELHEADERFLAG; if (iLevel != accStyler.LevelAt(iLineCurrent)) { accStyler.SetLevel(iLineCurrent,iLevel); } iLineCurrent++; iLevelPrev = iLevelCurrent; iVisibleChars = 0; } if (!isspacechar(chChar)) iVisibleChars++; } // Fill in the real level of the next line, keeping the current flags // as they will be filled in later. int iFlagsNext = accStyler.LevelAt(iLineCurrent) & ~SC_FOLDLEVELNUMBERMASK; accStyler.SetLevel(iLineCurrent, iLevelPrev | iFlagsNext); } // Word List Descriptions static const char * const rgWordListDescriptions[] = { "Clarion Keywords", "Compiler Directives", "Built-in Procedures and Functions", "Runtime Expressions", "Structure and Data Types", "Attributes", "Standard Equates", "Reserved Words (Labels)", "Reserved Words (Procedure Labels)", 0, }; // Case Sensitive Clarion Language Lexer LexerModule lmClw(SCLEX_CLW, ColouriseClarionDocSensitive, "clarion", FoldClarionDoc, rgWordListDescriptions); // Case Insensitive Clarion Language Lexer LexerModule lmClwNoCase(SCLEX_CLWNOCASE, ColouriseClarionDocInsensitive, "clarionnocase", FoldClarionDoc, rgWordListDescriptions); |
Added lexers/LexCOBOL.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
// Scintilla source code edit control /** @file LexCOBOL.cxx ** Lexer for COBOL ** Based on LexPascal.cxx ** Written by Laurent le Tynevez ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002 ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments) ** Updated by Rod Falck, Aug 2006 Converted to COBOL **/ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif #define IN_DIVISION 0x01 #define IN_DECLARATIVES 0x02 #define IN_SECTION 0x04 #define IN_PARAGRAPH 0x08 #define IN_FLAGS 0xF #define NOT_HEADER 0x10 inline bool isCOBOLoperator(char ch) { return isoperator(ch); } inline bool isCOBOLwordchar(char ch) { return isascii(ch) && (isalnum(ch) || ch == '-'); } inline bool isCOBOLwordstart(char ch) { return isascii(ch) && isalnum(ch); } static int CountBits(int nBits) { int count = 0; for (int i = 0; i < 32; ++i) { count += nBits & 1; nBits >>= 1; } return count; } static void getRange(unsigned int start, unsigned int end, Accessor &styler, char *s, unsigned int len) { unsigned int i = 0; while ((i < end - start + 1) && (i < len-1)) { s[i] = static_cast<char>(tolower(styler[start + i])); i++; } s[i] = '\0'; } static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr) { styler.ColourTo(end, attr); } static int classifyWordCOBOL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, int nContainment, bool *bAarea) { int ret = 0; WordList& a_keywords = *keywordlists[0]; WordList& b_keywords = *keywordlists[1]; WordList& c_keywords = *keywordlists[2]; char s[100]; getRange(start, end, styler, s, sizeof(s)); char chAttr = SCE_C_IDENTIFIER; if (isdigit(s[0]) || (s[0] == '.') || (s[0] == 'v')) { chAttr = SCE_C_NUMBER; char *p = s + 1; while (*p) { if ((!isdigit(*p) && (*p) != 'v') && isCOBOLwordchar(*p)) { chAttr = SCE_C_IDENTIFIER; break; } ++p; } } else { if (a_keywords.InList(s)) { chAttr = SCE_C_WORD; } else if (b_keywords.InList(s)) { chAttr = SCE_C_WORD2; } else if (c_keywords.InList(s)) { chAttr = SCE_C_UUID; } } if (*bAarea) { if (strcmp(s, "division") == 0) { ret = IN_DIVISION; // we've determined the containment, anything else is just ignored for those purposes *bAarea = false; } else if (strcmp(s, "declaratives") == 0) { ret = IN_DIVISION | IN_DECLARATIVES; if (nContainment & IN_DECLARATIVES) ret |= NOT_HEADER | IN_SECTION; // we've determined the containment, anything else is just ignored for those purposes *bAarea = false; } else if (strcmp(s, "section") == 0) { ret = (nContainment &~ IN_PARAGRAPH) | IN_SECTION; // we've determined the containment, anything else is just ignored for those purposes *bAarea = false; } else if (strcmp(s, "end") == 0 && (nContainment & IN_DECLARATIVES)) { ret = IN_DIVISION | IN_DECLARATIVES | IN_SECTION | NOT_HEADER; } else { ret = nContainment | IN_PARAGRAPH; } } ColourTo(styler, end, chAttr); return ret; } static void ColouriseCOBOLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { styler.StartAt(startPos); int state = initStyle; if (state == SCE_C_CHARACTER) // Does not leak onto next line state = SCE_C_DEFAULT; char chPrev = ' '; char chNext = styler[startPos]; unsigned int lengthDoc = startPos + length; int nContainment; int currentLine = styler.GetLine(startPos); if (currentLine > 0) { styler.SetLineState(currentLine, styler.GetLineState(currentLine-1)); nContainment = styler.GetLineState(currentLine); nContainment &= ~NOT_HEADER; } else { styler.SetLineState(currentLine, 0); nContainment = 0; } styler.StartSegment(startPos); bool bNewLine = true; bool bAarea = !isspacechar(chNext); int column = 0; for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); ++column; if (bNewLine) { column = 0; } if (column <= 1 && !bAarea) { bAarea = !isspacechar(ch); } bool bSetNewLine = false; if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) // Avoid triggering two times on Dos/Win // End of line if (state == SCE_C_CHARACTER) { ColourTo(styler, i, state); state = SCE_C_DEFAULT; } styler.SetLineState(currentLine, nContainment); currentLine++; bSetNewLine = true; if (nContainment & NOT_HEADER) nContainment &= ~(NOT_HEADER | IN_DECLARATIVES | IN_SECTION); } if (styler.IsLeadByte(ch)) { chNext = styler.SafeGetCharAt(i + 2); chPrev = ' '; i += 1; continue; } if (state == SCE_C_DEFAULT) { if (isCOBOLwordstart(ch) || (ch == '$' && isascii(chNext) && isalpha(chNext))) { ColourTo(styler, i-1, state); state = SCE_C_IDENTIFIER; } else if (column == 6 && ch == '*') { // Cobol comment line: asterisk in column 7. ColourTo(styler, i-1, state); state = SCE_C_COMMENTLINE; } else if (ch == '*' && chNext == '>') { // Cobol inline comment: asterisk, followed by greater than. ColourTo(styler, i-1, state); state = SCE_C_COMMENTLINE; } else if (column == 0 && ch == '*' && chNext != '*') { ColourTo(styler, i-1, state); state = SCE_C_COMMENTLINE; } else if (column == 0 && ch == '/' && chNext != '*') { ColourTo(styler, i-1, state); state = SCE_C_COMMENTLINE; } else if (column == 0 && ch == '*' && chNext == '*') { ColourTo(styler, i-1, state); state = SCE_C_COMMENTDOC; } else if (column == 0 && ch == '/' && chNext == '*') { ColourTo(styler, i-1, state); state = SCE_C_COMMENTDOC; } else if (ch == '"') { ColourTo(styler, i-1, state); state = SCE_C_STRING; } else if (ch == '\'') { ColourTo(styler, i-1, state); state = SCE_C_CHARACTER; } else if (ch == '?' && column == 0) { ColourTo(styler, i-1, state); state = SCE_C_PREPROCESSOR; } else if (isCOBOLoperator(ch)) { ColourTo(styler, i-1, state); ColourTo(styler, i, SCE_C_OPERATOR); } } else if (state == SCE_C_IDENTIFIER) { if (!isCOBOLwordchar(ch)) { int lStateChange = classifyWordCOBOL(styler.GetStartSegment(), i - 1, keywordlists, styler, nContainment, &bAarea); if(lStateChange != 0) { styler.SetLineState(currentLine, lStateChange); nContainment = lStateChange; } state = SCE_C_DEFAULT; chNext = styler.SafeGetCharAt(i + 1); if (ch == '"') { state = SCE_C_STRING; } else if (ch == '\'') { state = SCE_C_CHARACTER; } else if (isCOBOLoperator(ch)) { ColourTo(styler, i, SCE_C_OPERATOR); } } } else { if (state == SCE_C_PREPROCESSOR) { if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) { ColourTo(styler, i-1, state); state = SCE_C_DEFAULT; } } else if (state == SCE_C_COMMENT) { if (ch == '\r' || ch == '\n') { ColourTo(styler, i, state); state = SCE_C_DEFAULT; } } else if (state == SCE_C_COMMENTDOC) { if (ch == '\r' || ch == '\n') { if (((i > styler.GetStartSegment() + 2) || ( (initStyle == SCE_C_COMMENTDOC) && (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) { ColourTo(styler, i, state); state = SCE_C_DEFAULT; } } } else if (state == SCE_C_COMMENTLINE) { if (ch == '\r' || ch == '\n') { ColourTo(styler, i-1, state); state = SCE_C_DEFAULT; } } else if (state == SCE_C_STRING) { if (ch == '"') { ColourTo(styler, i, state); state = SCE_C_DEFAULT; } } else if (state == SCE_C_CHARACTER) { if (ch == '\'') { ColourTo(styler, i, state); state = SCE_C_DEFAULT; } } } chPrev = ch; bNewLine = bSetNewLine; if (bNewLine) { bAarea = false; } } ColourTo(styler, lengthDoc - 1, state); } static void FoldCOBOLDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) & SC_FOLDLEVELNUMBERMASK : 0xFFF; char chNext = styler[startPos]; bool bNewLine = true; bool bAarea = !isspacechar(chNext); int column = 0; bool bComment = false; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); ++column; if (bNewLine) { column = 0; bComment = (ch == '*' || ch == '/' || ch == '?'); } if (column <= 1 && !bAarea) { bAarea = !isspacechar(ch); } bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (atEOL) { int nContainment = styler.GetLineState(lineCurrent); int lev = CountBits(nContainment & IN_FLAGS) | SC_FOLDLEVELBASE; if (bAarea && !bComment) --lev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((bAarea) && (visibleChars > 0) && !(nContainment & NOT_HEADER) && !bComment) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } if ((lev & SC_FOLDLEVELNUMBERMASK) <= (levelPrev & SC_FOLDLEVELNUMBERMASK)) { // this level is at the same level or less than the previous line // therefore these is nothing for the previous header to collapse, so remove the header styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG); } levelPrev = lev; visibleChars = 0; bAarea = false; bNewLine = true; lineCurrent++; } else { bNewLine = false; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char * const COBOLWordListDesc[] = { "A Keywords", "B Keywords", "Extended Keywords", 0 }; LexerModule lmCOBOL(SCLEX_COBOL, ColouriseCOBOLDoc, "COBOL", FoldCOBOLDoc, COBOLWordListDesc); |
Added lexers/LexCPP.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 |
// Scintilla source code edit control /** @file LexCPP.cxx ** Lexer for C++, C, Java, and JavaScript. ** Further folding features and configuration properties added by "Udo Lechner" <dlchnr(at)gmx(dot)net> **/ // Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <string> #include <vector> #include <map> #include <algorithm> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #include "OptionSet.h" #include "SparseState.h" #include "SubStyles.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static bool IsSpaceEquiv(int state) { return (state <= SCE_C_COMMENTDOC) || // including SCE_C_DEFAULT, SCE_C_COMMENT, SCE_C_COMMENTLINE (state == SCE_C_COMMENTLINEDOC) || (state == SCE_C_COMMENTDOCKEYWORD) || (state == SCE_C_COMMENTDOCKEYWORDERROR); } // Preconditions: sc.currentPos points to a character after '+' or '-'. // The test for pos reaching 0 should be redundant, // and is in only for safety measures. // Limitation: this code will give the incorrect answer for code like // a = b+++/ptn/... // Putting a space between the '++' post-inc operator and the '+' binary op // fixes this, and is highly recommended for readability anyway. static bool FollowsPostfixOperator(StyleContext &sc, LexAccessor &styler) { int pos = (int) sc.currentPos; while (--pos > 0) { char ch = styler[pos]; if (ch == '+' || ch == '-') { return styler[pos - 1] == ch; } } return false; } static bool followsReturnKeyword(StyleContext &sc, LexAccessor &styler) { // Don't look at styles, so no need to flush. int pos = (int) sc.currentPos; int currentLine = styler.GetLine(pos); int lineStartPos = styler.LineStart(currentLine); char ch; while (--pos > lineStartPos) { ch = styler.SafeGetCharAt(pos); if (ch != ' ' && ch != '\t') { break; } } const char *retBack = "nruter"; const char *s = retBack; while (*s && pos >= lineStartPos && styler.SafeGetCharAt(pos) == *s) { s++; pos--; } return !*s; } static std::string GetRestOfLine(LexAccessor &styler, int start, bool allowSpace) { std::string restOfLine; int i =0; char ch = styler.SafeGetCharAt(start, '\n'); int endLine = styler.LineEnd(styler.GetLine(start)); while (((start+i) < endLine) && (ch != '\r')) { char chNext = styler.SafeGetCharAt(start + i + 1, '\n'); if (ch == '/' && (chNext == '/' || chNext == '*')) break; if (allowSpace || (ch != ' ')) restOfLine += ch; i++; ch = chNext; } return restOfLine; } static bool IsStreamCommentStyle(int style) { return style == SCE_C_COMMENT || style == SCE_C_COMMENTDOC || style == SCE_C_COMMENTDOCKEYWORD || style == SCE_C_COMMENTDOCKEYWORDERROR; } static std::vector<std::string> Tokenize(const std::string &s) { // Break into space separated tokens std::string word; std::vector<std::string> tokens; for (const char *cp = s.c_str(); *cp; cp++) { if ((*cp == ' ') || (*cp == '\t')) { if (!word.empty()) { tokens.push_back(word); word = ""; } } else { word += *cp; } } if (!word.empty()) { tokens.push_back(word); } return tokens; } struct PPDefinition { int line; std::string key; std::string value; bool isUndef; PPDefinition(int line_, const std::string &key_, const std::string &value_, bool isUndef_ = false) : line(line_), key(key_), value(value_), isUndef(isUndef_) { } }; class LinePPState { int state; int ifTaken; int level; bool ValidLevel() const { return level >= 0 && level < 32; } int maskLevel() const { return 1 << level; } public: LinePPState() : state(0), ifTaken(0), level(-1) { } bool IsInactive() const { return state != 0; } bool CurrentIfTaken() { return (ifTaken & maskLevel()) != 0; } void StartSection(bool on) { level++; if (ValidLevel()) { if (on) { state &= ~maskLevel(); ifTaken |= maskLevel(); } else { state |= maskLevel(); ifTaken &= ~maskLevel(); } } } void EndSection() { if (ValidLevel()) { state &= ~maskLevel(); ifTaken &= ~maskLevel(); } level--; } void InvertCurrentLevel() { if (ValidLevel()) { state ^= maskLevel(); ifTaken |= maskLevel(); } } }; // Hold the preprocessor state for each line seen. // Currently one entry per line but could become sparse with just one entry per preprocessor line. class PPStates { std::vector<LinePPState> vlls; public: LinePPState ForLine(int line) { if ((line > 0) && (vlls.size() > static_cast<size_t>(line))) { return vlls[line]; } else { return LinePPState(); } } void Add(int line, LinePPState lls) { vlls.resize(line+1); vlls[line] = lls; } }; // An individual named option for use in an OptionSet // Options used for LexerCPP struct OptionsCPP { bool stylingWithinPreprocessor; bool identifiersAllowDollars; bool trackPreprocessor; bool updatePreprocessor; bool triplequotedStrings; bool hashquotedStrings; bool fold; bool foldSyntaxBased; bool foldComment; bool foldCommentMultiline; bool foldCommentExplicit; std::string foldExplicitStart; std::string foldExplicitEnd; bool foldExplicitAnywhere; bool foldPreprocessor; bool foldCompact; bool foldAtElse; OptionsCPP() { stylingWithinPreprocessor = false; identifiersAllowDollars = true; trackPreprocessor = true; updatePreprocessor = true; triplequotedStrings = false; hashquotedStrings = false; fold = false; foldSyntaxBased = true; foldComment = false; foldCommentMultiline = true; foldCommentExplicit = true; foldExplicitStart = ""; foldExplicitEnd = ""; foldExplicitAnywhere = false; foldPreprocessor = false; foldCompact = false; foldAtElse = false; } }; static const char *const cppWordLists[] = { "Primary keywords and identifiers", "Secondary keywords and identifiers", "Documentation comment keywords", "Global classes and typedefs", "Preprocessor definitions", 0, }; struct OptionSetCPP : public OptionSet<OptionsCPP> { OptionSetCPP() { DefineProperty("styling.within.preprocessor", &OptionsCPP::stylingWithinPreprocessor, "For C++ code, determines whether all preprocessor code is styled in the " "preprocessor style (0, the default) or only from the initial # to the end " "of the command word(1)."); DefineProperty("lexer.cpp.allow.dollars", &OptionsCPP::identifiersAllowDollars, "Set to 0 to disallow the '$' character in identifiers with the cpp lexer."); DefineProperty("lexer.cpp.track.preprocessor", &OptionsCPP::trackPreprocessor, "Set to 1 to interpret #if/#else/#endif to grey out code that is not active."); DefineProperty("lexer.cpp.update.preprocessor", &OptionsCPP::updatePreprocessor, "Set to 1 to update preprocessor definitions when #define found."); DefineProperty("lexer.cpp.triplequoted.strings", &OptionsCPP::triplequotedStrings, "Set to 1 to enable highlighting of triple-quoted strings."); DefineProperty("lexer.cpp.hashquoted.strings", &OptionsCPP::hashquotedStrings, "Set to 1 to enable highlighting of hash-quoted strings."); DefineProperty("fold", &OptionsCPP::fold); DefineProperty("fold.cpp.syntax.based", &OptionsCPP::foldSyntaxBased, "Set this property to 0 to disable syntax based folding."); DefineProperty("fold.comment", &OptionsCPP::foldComment, "This option enables folding multi-line comments and explicit fold points when using the C++ lexer. " "Explicit fold points allows adding extra folding by placing a //{ comment at the start and a //} " "at the end of a section that should fold."); DefineProperty("fold.cpp.comment.multiline", &OptionsCPP::foldCommentMultiline, "Set this property to 0 to disable folding multi-line comments when fold.comment=1."); DefineProperty("fold.cpp.comment.explicit", &OptionsCPP::foldCommentExplicit, "Set this property to 0 to disable folding explicit fold points when fold.comment=1."); DefineProperty("fold.cpp.explicit.start", &OptionsCPP::foldExplicitStart, "The string to use for explicit fold start points, replacing the standard //{."); DefineProperty("fold.cpp.explicit.end", &OptionsCPP::foldExplicitEnd, "The string to use for explicit fold end points, replacing the standard //}."); DefineProperty("fold.cpp.explicit.anywhere", &OptionsCPP::foldExplicitAnywhere, "Set this property to 1 to enable explicit fold points anywhere, not just in line comments."); DefineProperty("fold.preprocessor", &OptionsCPP::foldPreprocessor, "This option enables folding preprocessor directives when using the C++ lexer. " "Includes C#'s explicit #region and #endregion folding directives."); DefineProperty("fold.compact", &OptionsCPP::foldCompact); DefineProperty("fold.at.else", &OptionsCPP::foldAtElse, "This option enables C++ folding on a \"} else {\" line of an if statement."); DefineWordListSets(cppWordLists); } }; static const char styleSubable[] = {SCE_C_IDENTIFIER, SCE_C_COMMENTDOCKEYWORD, 0}; class LexerCPP : public ILexerWithSubStyles { bool caseSensitive; CharacterSet setWord; CharacterSet setNegationOp; CharacterSet setArithmethicOp; CharacterSet setRelOp; CharacterSet setLogicalOp; PPStates vlls; std::vector<PPDefinition> ppDefineHistory; WordList keywords; WordList keywords2; WordList keywords3; WordList keywords4; WordList ppDefinitions; std::map<std::string, std::string> preprocessorDefinitionsStart; OptionsCPP options; OptionSetCPP osCPP; SparseState<std::string> rawStringTerminators; enum { activeFlag = 0x40 }; enum { ssIdentifier, ssDocKeyword }; SubStyles subStyles; public: LexerCPP(bool caseSensitive_) : caseSensitive(caseSensitive_), setWord(CharacterSet::setAlphaNum, "._", 0x80, true), setNegationOp(CharacterSet::setNone, "!"), setArithmethicOp(CharacterSet::setNone, "+-/*%"), setRelOp(CharacterSet::setNone, "=!<>"), setLogicalOp(CharacterSet::setNone, "|&"), subStyles(styleSubable, 0x80, 0x40, activeFlag) { } virtual ~LexerCPP() { } void SCI_METHOD Release() { delete this; } int SCI_METHOD Version() const { return lvSubStyles; } const char * SCI_METHOD PropertyNames() { return osCPP.PropertyNames(); } int SCI_METHOD PropertyType(const char *name) { return osCPP.PropertyType(name); } const char * SCI_METHOD DescribeProperty(const char *name) { return osCPP.DescribeProperty(name); } int SCI_METHOD PropertySet(const char *key, const char *val); const char * SCI_METHOD DescribeWordListSets() { return osCPP.DescribeWordListSets(); } int SCI_METHOD WordListSet(int n, const char *wl); void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess); void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess); void * SCI_METHOD PrivateCall(int, void *) { return 0; } int SCI_METHOD LineEndTypesSupported() { return SC_LINE_END_TYPE_UNICODE; }; int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) { return subStyles.Allocate(styleBase, numberStyles); } int SCI_METHOD SubStylesStart(int styleBase) { return subStyles.Start(styleBase); } int SCI_METHOD SubStylesLength(int styleBase) { return subStyles.Length(styleBase); } void SCI_METHOD FreeSubStyles() { subStyles.Free(); } void SCI_METHOD SetIdentifiers(int style, const char *identifiers) { subStyles.SetIdentifiers(style, identifiers); } int SCI_METHOD DistanceToSecondaryStyles() { return activeFlag; } const char * SCI_METHOD GetSubStyleBases() { return styleSubable; } static ILexer *LexerFactoryCPP() { return new LexerCPP(true); } static ILexer *LexerFactoryCPPInsensitive() { return new LexerCPP(false); } static int MaskActive(int style) { return style & ~activeFlag; } void EvaluateTokens(std::vector<std::string> &tokens); bool EvaluateExpression(const std::string &expr, const std::map<std::string, std::string> &preprocessorDefinitions); }; int SCI_METHOD LexerCPP::PropertySet(const char *key, const char *val) { if (osCPP.PropertySet(&options, key, val)) { if (strcmp(key, "lexer.cpp.allow.dollars") == 0) { setWord = CharacterSet(CharacterSet::setAlphaNum, "._", 0x80, true); if (options.identifiersAllowDollars) { setWord.Add('$'); } } return 0; } return -1; } int SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) { WordList *wordListN = 0; switch (n) { case 0: wordListN = &keywords; break; case 1: wordListN = &keywords2; break; case 2: wordListN = &keywords3; break; case 3: wordListN = &keywords4; break; case 4: wordListN = &ppDefinitions; break; } int firstModification = -1; if (wordListN) { WordList wlNew; wlNew.Set(wl); if (*wordListN != wlNew) { wordListN->Set(wl); firstModification = 0; if (n == 4) { // Rebuild preprocessorDefinitions preprocessorDefinitionsStart.clear(); for (int nDefinition = 0; nDefinition < ppDefinitions.len; nDefinition++) { char *cpDefinition = ppDefinitions.words[nDefinition]; char *cpEquals = strchr(cpDefinition, '='); if (cpEquals) { std::string name(cpDefinition, cpEquals - cpDefinition); std::string val(cpEquals+1); preprocessorDefinitionsStart[name] = val; } else { std::string name(cpDefinition); std::string val("1"); preprocessorDefinitionsStart[name] = val; } } } } } return firstModification; } // Functor used to truncate history struct After { int line; After(int line_) : line(line_) {} bool operator()(PPDefinition &p) const { return p.line > line; } }; void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { LexAccessor styler(pAccess); CharacterSet setOKBeforeRE(CharacterSet::setNone, "([{=,:;!%^&*|?~+-"); CharacterSet setCouldBePostOp(CharacterSet::setNone, "+-"); CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]"); CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); CharacterSet setInvalidRawFirst(CharacterSet::setNone, " )\\\t\v\f\n"); if (options.identifiersAllowDollars) { setWordStart.Add('$'); } int chPrevNonWhite = ' '; int visibleChars = 0; bool lastWordWasUUID = false; int styleBeforeDCKeyword = SCE_C_DEFAULT; bool continuationLine = false; bool isIncludePreprocessor = false; bool isStringInPreprocessor = false; bool inRERange = false; int lineCurrent = styler.GetLine(startPos); if ((MaskActive(initStyle) == SCE_C_PREPROCESSOR) || (MaskActive(initStyle) == SCE_C_COMMENTLINE) || (MaskActive(initStyle) == SCE_C_COMMENTLINEDOC)) { // Set continuationLine if last character of previous line is '\' if (lineCurrent > 0) { int endLinePrevious = styler.LineEnd(lineCurrent - 1); if (endLinePrevious > 0) { continuationLine = styler.SafeGetCharAt(endLinePrevious-1) == '\\'; } } } // look back to set chPrevNonWhite properly for better regex colouring if (startPos > 0) { int back = startPos; while (--back && IsSpaceEquiv(MaskActive(styler.StyleAt(back)))) ; if (MaskActive(styler.StyleAt(back)) == SCE_C_OPERATOR) { chPrevNonWhite = styler.SafeGetCharAt(back); } } StyleContext sc(startPos, length, initStyle, styler, static_cast<char>(0xff)); LinePPState preproc = vlls.ForLine(lineCurrent); bool definitionsChanged = false; // Truncate ppDefineHistory before current line if (!options.updatePreprocessor) ppDefineHistory.clear(); std::vector<PPDefinition>::iterator itInvalid = std::find_if(ppDefineHistory.begin(), ppDefineHistory.end(), After(lineCurrent-1)); if (itInvalid != ppDefineHistory.end()) { ppDefineHistory.erase(itInvalid, ppDefineHistory.end()); definitionsChanged = true; } std::map<std::string, std::string> preprocessorDefinitions = preprocessorDefinitionsStart; for (std::vector<PPDefinition>::iterator itDef = ppDefineHistory.begin(); itDef != ppDefineHistory.end(); ++itDef) { if (itDef->isUndef) preprocessorDefinitions.erase(itDef->key); else preprocessorDefinitions[itDef->key] = itDef->value; } std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1); SparseState<std::string> rawSTNew(lineCurrent); int activitySet = preproc.IsInactive() ? activeFlag : 0; const WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_C_IDENTIFIER); const WordClassifier &classifierDocKeyWords = subStyles.Classifier(SCE_C_COMMENTDOCKEYWORD); int lineEndNext = styler.LineEnd(lineCurrent); for (; sc.More();) { if (sc.atLineStart) { // Using MaskActive() is not needed in the following statement. // Inside inactive preprocessor declaration, state will be reset anyway at the end of this block. if ((sc.state == SCE_C_STRING) || (sc.state == SCE_C_CHARACTER)) { // Prevent SCE_C_STRINGEOL from leaking back to previous line which // ends with a line continuation by locking in the state upto this position. sc.SetState(sc.state); } if ((MaskActive(sc.state) == SCE_C_PREPROCESSOR) && (!continuationLine)) { sc.SetState(SCE_C_DEFAULT|activitySet); } // Reset states to begining of colourise so no surprises // if different sets of lines lexed. visibleChars = 0; lastWordWasUUID = false; isIncludePreprocessor = false; inRERange = false; if (preproc.IsInactive()) { activitySet = activeFlag; sc.SetState(sc.state | activitySet); } } if (sc.atLineEnd) { lineCurrent++; lineEndNext = styler.LineEnd(lineCurrent); vlls.Add(lineCurrent, preproc); if (rawStringTerminator != "") { rawSTNew.Set(lineCurrent-1, rawStringTerminator); } } // Handle line continuation generically. if (sc.ch == '\\') { if (static_cast<int>((sc.currentPos+1)) >= lineEndNext) { lineCurrent++; lineEndNext = styler.LineEnd(lineCurrent); vlls.Add(lineCurrent, preproc); sc.Forward(); if (sc.ch == '\r' && sc.chNext == '\n') { // Even in UTF-8, \r and \n are separate sc.Forward(); } continuationLine = true; sc.Forward(); continue; } } const bool atLineEndBeforeSwitch = sc.atLineEnd; // Determine if the current state should terminate. switch (MaskActive(sc.state)) { case SCE_C_OPERATOR: sc.SetState(SCE_C_DEFAULT|activitySet); break; case SCE_C_NUMBER: // We accept almost anything because of hex. and number suffixes if (!(setWord.Contains(sc.ch) || ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E' || sc.chPrev == 'p' || sc.chPrev == 'P')))) { sc.SetState(SCE_C_DEFAULT|activitySet); } break; case SCE_C_IDENTIFIER: if (sc.atLineStart || sc.atLineEnd || !setWord.Contains(sc.ch) || (sc.ch == '.')) { char s[1000]; if (caseSensitive) { sc.GetCurrent(s, sizeof(s)); } else { sc.GetCurrentLowered(s, sizeof(s)); } if (keywords.InList(s)) { lastWordWasUUID = strcmp(s, "uuid") == 0; sc.ChangeState(SCE_C_WORD|activitySet); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_C_WORD2|activitySet); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_C_GLOBALCLASS|activitySet); } else { int subStyle = classifierIdentifiers.ValueFor(s); if (subStyle >= 0) { sc.ChangeState(subStyle|activitySet); } } const bool literalString = sc.ch == '\"'; if (literalString || sc.ch == '\'') { size_t lenS = strlen(s); const bool raw = literalString && sc.chPrev == 'R' && !setInvalidRawFirst.Contains(sc.chNext); if (raw) s[lenS--] = '\0'; bool valid = (lenS == 0) || ((lenS == 1) && ((s[0] == 'L') || (s[0] == 'u') || (s[0] == 'U'))) || ((lenS == 2) && literalString && (s[0] == 'u') && (s[1] == '8')); if (valid) { if (literalString) sc.ChangeState((raw ? SCE_C_STRINGRAW : SCE_C_STRING)|activitySet); else sc.ChangeState(SCE_C_CHARACTER|activitySet); } } sc.SetState(SCE_C_DEFAULT|activitySet); } break; case SCE_C_PREPROCESSOR: if (options.stylingWithinPreprocessor) { if (IsASpace(sc.ch)) { sc.SetState(SCE_C_DEFAULT|activitySet); } } else if (isStringInPreprocessor && (sc.Match('>') || sc.Match('\"'))) { isStringInPreprocessor = false; } else if (!isStringInPreprocessor) { if ((isIncludePreprocessor && sc.Match('<')) || sc.Match('\"')) { isStringInPreprocessor = true; } else if (sc.Match('/', '*')) { sc.SetState(SCE_C_PREPROCESSORCOMMENT|activitySet); sc.Forward(); // Eat the * } else if (sc.Match('/', '/')) { sc.SetState(SCE_C_DEFAULT|activitySet); } } break; case SCE_C_PREPROCESSORCOMMENT: if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_C_PREPROCESSOR|activitySet); continue; // Without advancing in case of '\'. } break; case SCE_C_COMMENT: if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_C_DEFAULT|activitySet); } break; case SCE_C_COMMENTDOC: if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_C_DEFAULT|activitySet); } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support // Verify that we have the conditions to mark a comment-doc-keyword if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) { styleBeforeDCKeyword = SCE_C_COMMENTDOC; sc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet); } } break; case SCE_C_COMMENTLINE: if (sc.atLineStart && !continuationLine) { sc.SetState(SCE_C_DEFAULT|activitySet); } break; case SCE_C_COMMENTLINEDOC: if (sc.atLineStart && !continuationLine) { sc.SetState(SCE_C_DEFAULT|activitySet); } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support // Verify that we have the conditions to mark a comment-doc-keyword if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) { styleBeforeDCKeyword = SCE_C_COMMENTLINEDOC; sc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet); } } break; case SCE_C_COMMENTDOCKEYWORD: if ((styleBeforeDCKeyword == SCE_C_COMMENTDOC) && sc.Match('*', '/')) { sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR); sc.Forward(); sc.ForwardSetState(SCE_C_DEFAULT|activitySet); } else if (!setDoxygen.Contains(sc.ch)) { char s[100]; if (caseSensitive) { sc.GetCurrent(s, sizeof(s)); } else { sc.GetCurrentLowered(s, sizeof(s)); } if (!IsASpace(sc.ch)) { sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet); } else if (!keywords3.InList(s + 1)) { int subStyleCDKW = classifierDocKeyWords.ValueFor(s+1); if (subStyleCDKW >= 0) { sc.ChangeState(subStyleCDKW|activitySet); } else { sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet); } } sc.SetState(styleBeforeDCKeyword|activitySet); } break; case SCE_C_STRING: if (sc.atLineEnd) { sc.ChangeState(SCE_C_STRINGEOL|activitySet); } else if (isIncludePreprocessor) { if (sc.ch == '>') { sc.ForwardSetState(SCE_C_DEFAULT|activitySet); isIncludePreprocessor = false; } } else if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_C_DEFAULT|activitySet); } break; case SCE_C_HASHQUOTEDSTRING: if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_C_DEFAULT|activitySet); } break; case SCE_C_STRINGRAW: if (sc.Match(rawStringTerminator.c_str())) { for (size_t termPos=rawStringTerminator.size(); termPos; termPos--) sc.Forward(); sc.SetState(SCE_C_DEFAULT|activitySet); rawStringTerminator = ""; } break; case SCE_C_CHARACTER: if (sc.atLineEnd) { sc.ChangeState(SCE_C_STRINGEOL|activitySet); } else if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\'') { sc.ForwardSetState(SCE_C_DEFAULT|activitySet); } break; case SCE_C_REGEX: if (sc.atLineStart) { sc.SetState(SCE_C_DEFAULT|activitySet); } else if (! inRERange && sc.ch == '/') { sc.Forward(); while ((sc.ch < 0x80) && islower(sc.ch)) sc.Forward(); // gobble regex flags sc.SetState(SCE_C_DEFAULT|activitySet); } else if (sc.ch == '\\' && (static_cast<int>(sc.currentPos+1) < lineEndNext)) { // Gobble up the escaped character sc.Forward(); } else if (sc.ch == '[') { inRERange = true; } else if (sc.ch == ']') { inRERange = false; } break; case SCE_C_STRINGEOL: if (sc.atLineStart) { sc.SetState(SCE_C_DEFAULT|activitySet); } break; case SCE_C_VERBATIM: if (sc.ch == '\"') { if (sc.chNext == '\"') { sc.Forward(); } else { sc.ForwardSetState(SCE_C_DEFAULT|activitySet); } } break; case SCE_C_TRIPLEVERBATIM: if (sc.Match("\"\"\"")) { while (sc.Match('"')) { sc.Forward(); } sc.SetState(SCE_C_DEFAULT|activitySet); } break; case SCE_C_UUID: if (sc.atLineEnd || sc.ch == ')') { sc.SetState(SCE_C_DEFAULT|activitySet); } } if (sc.atLineEnd && !atLineEndBeforeSwitch) { // State exit processing consumed characters up to end of line. lineCurrent++; lineEndNext = styler.LineEnd(lineCurrent); vlls.Add(lineCurrent, preproc); } // Determine if a new state should be entered. if (MaskActive(sc.state) == SCE_C_DEFAULT) { if (sc.Match('@', '\"')) { sc.SetState(SCE_C_VERBATIM|activitySet); sc.Forward(); } else if (options.triplequotedStrings && sc.Match("\"\"\"")) { sc.SetState(SCE_C_TRIPLEVERBATIM|activitySet); sc.Forward(2); } else if (options.hashquotedStrings && sc.Match('#', '\"')) { sc.SetState(SCE_C_HASHQUOTEDSTRING|activitySet); sc.Forward(); } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { if (lastWordWasUUID) { sc.SetState(SCE_C_UUID|activitySet); lastWordWasUUID = false; } else { sc.SetState(SCE_C_NUMBER|activitySet); } } else if (!sc.atLineEnd && (setWordStart.Contains(sc.ch) || (sc.ch == '@'))) { if (lastWordWasUUID) { sc.SetState(SCE_C_UUID|activitySet); lastWordWasUUID = false; } else { sc.SetState(SCE_C_IDENTIFIER|activitySet); } } else if (sc.Match('/', '*')) { if (sc.Match("/**") || sc.Match("/*!")) { // Support of Qt/Doxygen doc. style sc.SetState(SCE_C_COMMENTDOC|activitySet); } else { sc.SetState(SCE_C_COMMENT|activitySet); } sc.Forward(); // Eat the * so it isn't used for the end of the comment } else if (sc.Match('/', '/')) { if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!")) // Support of Qt/Doxygen doc. style sc.SetState(SCE_C_COMMENTLINEDOC|activitySet); else sc.SetState(SCE_C_COMMENTLINE|activitySet); } else if (sc.ch == '/' && (setOKBeforeRE.Contains(chPrevNonWhite) || followsReturnKeyword(sc, styler)) && (!setCouldBePostOp.Contains(chPrevNonWhite) || !FollowsPostfixOperator(sc, styler))) { sc.SetState(SCE_C_REGEX|activitySet); // JavaScript's RegEx inRERange = false; } else if (sc.ch == '\"') { if (sc.chPrev == 'R') { styler.Flush(); if (MaskActive(styler.StyleAt(sc.currentPos - 1)) == SCE_C_STRINGRAW) { sc.SetState(SCE_C_STRINGRAW|activitySet); rawStringTerminator = ")"; for (int termPos = sc.currentPos + 1;; termPos++) { char chTerminator = styler.SafeGetCharAt(termPos, '('); if (chTerminator == '(') break; rawStringTerminator += chTerminator; } rawStringTerminator += '\"'; } else { sc.SetState(SCE_C_STRING|activitySet); } } else { sc.SetState(SCE_C_STRING|activitySet); } isIncludePreprocessor = false; // ensure that '>' won't end the string } else if (isIncludePreprocessor && sc.ch == '<') { sc.SetState(SCE_C_STRING|activitySet); } else if (sc.ch == '\'') { sc.SetState(SCE_C_CHARACTER|activitySet); } else if (sc.ch == '#' && visibleChars == 0) { // Preprocessor commands are alone on their line sc.SetState(SCE_C_PREPROCESSOR|activitySet); // Skip whitespace between # and preprocessor word do { sc.Forward(); } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More()); if (sc.atLineEnd) { sc.SetState(SCE_C_DEFAULT|activitySet); } else if (sc.Match("include")) { isIncludePreprocessor = true; } else { if (options.trackPreprocessor) { if (sc.Match("ifdef") || sc.Match("ifndef")) { bool isIfDef = sc.Match("ifdef"); int i = isIfDef ? 5 : 6; std::string restOfLine = GetRestOfLine(styler, sc.currentPos + i + 1, false); bool foundDef = preprocessorDefinitions.find(restOfLine) != preprocessorDefinitions.end(); preproc.StartSection(isIfDef == foundDef); } else if (sc.Match("if")) { std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 2, true); bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions); preproc.StartSection(ifGood); } else if (sc.Match("else")) { if (!preproc.CurrentIfTaken()) { preproc.InvertCurrentLevel(); activitySet = preproc.IsInactive() ? activeFlag : 0; if (!activitySet) sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); } else if (!preproc.IsInactive()) { preproc.InvertCurrentLevel(); activitySet = preproc.IsInactive() ? activeFlag : 0; if (!activitySet) sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); } } else if (sc.Match("elif")) { // Ensure only one chosen out of #if .. #elif .. #elif .. #else .. #endif if (!preproc.CurrentIfTaken()) { // Similar to #if std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 2, true); bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions); if (ifGood) { preproc.InvertCurrentLevel(); activitySet = preproc.IsInactive() ? activeFlag : 0; if (!activitySet) sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); } } else if (!preproc.IsInactive()) { preproc.InvertCurrentLevel(); activitySet = preproc.IsInactive() ? activeFlag : 0; if (!activitySet) sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); } } else if (sc.Match("endif")) { preproc.EndSection(); activitySet = preproc.IsInactive() ? activeFlag : 0; sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); } else if (sc.Match("define")) { if (options.updatePreprocessor && !preproc.IsInactive()) { std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 6, true); if (restOfLine.find(")") == std::string::npos) { // Don't handle macros with arguments std::vector<std::string> tokens = Tokenize(restOfLine); std::string key; std::string value("1"); if (tokens.size() >= 1) { key = tokens[0]; if (tokens.size() >= 2) { value = tokens[1]; } preprocessorDefinitions[key] = value; ppDefineHistory.push_back(PPDefinition(lineCurrent, key, value)); definitionsChanged = true; } } } } else if (sc.Match("undef")) { if (options.updatePreprocessor && !preproc.IsInactive()) { std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 5, true); std::vector<std::string> tokens = Tokenize(restOfLine); std::string key; if (tokens.size() >= 1) { key = tokens[0]; preprocessorDefinitions.erase(key); ppDefineHistory.push_back(PPDefinition(lineCurrent, key, "", true)); definitionsChanged = true; } } } } } } else if (isoperator(sc.ch)) { sc.SetState(SCE_C_OPERATOR|activitySet); } } if (!IsASpace(sc.ch) && !IsSpaceEquiv(MaskActive(sc.state))) { chPrevNonWhite = sc.ch; visibleChars++; } continuationLine = false; sc.Forward(); } const bool rawStringsChanged = rawStringTerminators.Merge(rawSTNew, lineCurrent); if (definitionsChanged || rawStringsChanged) styler.ChangeLexerState(startPos, startPos + length); sc.Complete(); } // Store both the current line's fold level and the next lines in the // level store to make it easy to pick up with each increment // and to make it possible to fiddle the current level for "} else {". void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { if (!options.fold) return; LexAccessor styler(pAccess); unsigned int endPos = startPos + length; int visibleChars = 0; bool inLineComment = false; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; unsigned int lineStartNext = styler.LineStart(lineCurrent+1); int levelMinCurrent = levelCurrent; int levelNext = levelCurrent; char chNext = styler[startPos]; int styleNext = MaskActive(styler.StyleAt(startPos)); int style = MaskActive(initStyle); const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty(); for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = MaskActive(styler.StyleAt(i + 1)); bool atEOL = i == (lineStartNext-1); if ((style == SCE_C_COMMENTLINE) || (style == SCE_C_COMMENTLINEDOC)) inLineComment = true; if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style) && !inLineComment) { if (!IsStreamCommentStyle(stylePrev)) { levelNext++; } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelNext--; } } if (options.foldComment && options.foldCommentExplicit && ((style == SCE_C_COMMENTLINE) || options.foldExplicitAnywhere)) { if (userDefinedFoldMarkers) { if (styler.Match(i, options.foldExplicitStart.c_str())) { levelNext++; } else if (styler.Match(i, options.foldExplicitEnd.c_str())) { levelNext--; } } else { if ((ch == '/') && (chNext == '/')) { char chNext2 = styler.SafeGetCharAt(i + 2); if (chNext2 == '{') { levelNext++; } else if (chNext2 == '}') { levelNext--; } } } } if (options.foldPreprocessor && (style == SCE_C_PREPROCESSOR)) { if (ch == '#') { unsigned int j = i + 1; while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { j++; } if (styler.Match(j, "region") || styler.Match(j, "if")) { levelNext++; } else if (styler.Match(j, "end")) { levelNext--; } } } if (options.foldSyntaxBased && (style == SCE_C_OPERATOR)) { if (ch == '{') { // Measure the minimum before a '{' to allow // folding on "} else {" if (levelMinCurrent > levelNext) { levelMinCurrent = levelNext; } levelNext++; } else if (ch == '}') { levelNext--; } } if (!IsASpace(ch)) visibleChars++; if (atEOL || (i == endPos-1)) { int levelUse = levelCurrent; if (options.foldSyntaxBased && options.foldAtElse) { levelUse = levelMinCurrent; } int lev = levelUse | levelNext << 16; if (visibleChars == 0 && options.foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; lineStartNext = styler.LineStart(lineCurrent+1); levelCurrent = levelNext; levelMinCurrent = levelCurrent; if (atEOL && (i == static_cast<unsigned int>(styler.Length()-1))) { // There is an empty line at end of file so give it same level and empty styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG); } visibleChars = 0; inLineComment = false; } } } void LexerCPP::EvaluateTokens(std::vector<std::string> &tokens) { // Evaluate defined() statements to either 0 or 1 for (size_t i=0; (i+2)<tokens.size();) { if ((tokens[i] == "defined") && (tokens[i+1] == "(")) { const char *val = "0"; if (tokens[i+2] == ")") { // defined() tokens.erase(tokens.begin() + i + 1, tokens.begin() + i + 3); } else if (((i+3)<tokens.size()) && (tokens[i+3] == ")")) { // defined(<int>) tokens.erase(tokens.begin() + i + 1, tokens.begin() + i + 4); val = "1"; } tokens[i] = val; } else { i++; } } // Find bracketed subexpressions and recurse on them std::vector<std::string>::iterator itBracket = std::find(tokens.begin(), tokens.end(), "("); std::vector<std::string>::iterator itEndBracket = std::find(tokens.begin(), tokens.end(), ")"); while ((itBracket != tokens.end()) && (itEndBracket != tokens.end()) && (itEndBracket > itBracket)) { std::vector<std::string> inBracket(itBracket + 1, itEndBracket); EvaluateTokens(inBracket); // The insertion is done before the removal because there were failures with the opposite approach tokens.insert(itBracket, inBracket.begin(), inBracket.end()); itBracket = std::find(tokens.begin(), tokens.end(), "("); itEndBracket = std::find(tokens.begin(), tokens.end(), ")"); tokens.erase(itBracket, itEndBracket + 1); itBracket = std::find(tokens.begin(), tokens.end(), "("); itEndBracket = std::find(tokens.begin(), tokens.end(), ")"); } // Evaluate logical negations for (size_t j=0; (j+1)<tokens.size();) { if (setNegationOp.Contains(tokens[j][0])) { int isTrue = atoi(tokens[j+1].c_str()); if (tokens[j] == "!") isTrue = !isTrue; std::vector<std::string>::iterator itInsert = tokens.erase(tokens.begin() + j, tokens.begin() + j + 2); tokens.insert(itInsert, isTrue ? "1" : "0"); } else { j++; } } // Evaluate expressions in precedence order enum precedence { precArithmetic, precRelative, precLogical }; for (int prec=precArithmetic; prec <= precLogical; prec++) { // Looking at 3 tokens at a time so end at 2 before end for (size_t k=0; (k+2)<tokens.size();) { char chOp = tokens[k+1][0]; if ( ((prec==precArithmetic) && setArithmethicOp.Contains(chOp)) || ((prec==precRelative) && setRelOp.Contains(chOp)) || ((prec==precLogical) && setLogicalOp.Contains(chOp)) ) { int valA = atoi(tokens[k].c_str()); int valB = atoi(tokens[k+2].c_str()); int result = 0; if (tokens[k+1] == "+") result = valA + valB; else if (tokens[k+1] == "-") result = valA - valB; else if (tokens[k+1] == "*") result = valA * valB; else if (tokens[k+1] == "/") result = valA / (valB ? valB : 1); else if (tokens[k+1] == "%") result = valA % (valB ? valB : 1); else if (tokens[k+1] == "<") result = valA < valB; else if (tokens[k+1] == "<=") result = valA <= valB; else if (tokens[k+1] == ">") result = valA > valB; else if (tokens[k+1] == ">=") result = valA >= valB; else if (tokens[k+1] == "==") result = valA == valB; else if (tokens[k+1] == "!=") result = valA != valB; else if (tokens[k+1] == "||") result = valA || valB; else if (tokens[k+1] == "&&") result = valA && valB; char sResult[30]; sprintf(sResult, "%d", result); std::vector<std::string>::iterator itInsert = tokens.erase(tokens.begin() + k, tokens.begin() + k + 3); tokens.insert(itInsert, sResult); } else { k++; } } } } bool LexerCPP::EvaluateExpression(const std::string &expr, const std::map<std::string, std::string> &preprocessorDefinitions) { // Break into tokens, replacing with definitions std::string word; std::vector<std::string> tokens; const char *cp = expr.c_str(); for (;;) { if (setWord.Contains(static_cast<unsigned char>(*cp))) { word += *cp; } else { std::map<std::string, std::string>::const_iterator it = preprocessorDefinitions.find(word); if (it != preprocessorDefinitions.end()) { tokens.push_back(it->second); } else if (!word.empty() && ((word[0] >= '0' && word[0] <= '9') || (word == "defined"))) { tokens.push_back(word); } word = ""; if (!*cp) { break; } if ((*cp != ' ') && (*cp != '\t')) { std::string op(cp, 1); if (setRelOp.Contains(static_cast<unsigned char>(*cp))) { if (setRelOp.Contains(static_cast<unsigned char>(cp[1]))) { op += cp[1]; cp++; } } else if (setLogicalOp.Contains(static_cast<unsigned char>(*cp))) { if (setLogicalOp.Contains(static_cast<unsigned char>(cp[1]))) { op += cp[1]; cp++; } } tokens.push_back(op); } } cp++; } EvaluateTokens(tokens); // "0" or "" -> false else true bool isFalse = tokens.empty() || ((tokens.size() == 1) && ((tokens[0] == "") || tokens[0] == "0")); return !isFalse; } LexerModule lmCPP(SCLEX_CPP, LexerCPP::LexerFactoryCPP, "cpp", cppWordLists); LexerModule lmCPPNoCase(SCLEX_CPPNOCASE, LexerCPP::LexerFactoryCPPInsensitive, "cppnocase", cppWordLists); |
Added lexers/LexCSS.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 |
// Scintilla source code edit control /** @file LexCSS.cxx ** Lexer for Cascading Style Sheets ** Written by Jakub Vrna ** Improved by Philippe Lhoste (CSS2) ** Improved by Ross McKay (SCSS mode; see http://sass-lang.com/ ) **/ // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. // TODO: handle SCSS nested properties like font: { weight: bold; size: 1em; } // TODO: handle SCSS interpolation: #{} // TODO: add features for Less if somebody feels like contributing; http://lesscss.org/ // TODO: refactor this monster so that the next poor slob can read it! #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(const unsigned int ch) { /* FIXME: * The CSS spec allows "ISO 10646 characters U+00A1 and higher" to be treated as word chars. * Unfortunately, we are only getting string bytes here, and not full unicode characters. We cannot guarantee * that our byte is between U+0080 - U+00A0 (to return false), so we have to allow all characters U+0080 and higher */ return ch >= 0x80 || isalnum(ch) || ch == '-' || ch == '_'; } inline bool IsCssOperator(const int ch) { if (!((ch < 0x80) && isalnum(ch)) && (ch == '{' || ch == '}' || ch == ':' || ch == ',' || ch == ';' || ch == '.' || ch == '#' || ch == '!' || ch == '@' || /* CSS2 */ ch == '*' || ch == '>' || ch == '+' || ch == '=' || ch == '~' || ch == '|' || ch == '[' || ch == ']' || ch == '(' || ch == ')')) { return true; } return false; } // look behind (from start of document to our start position) to determine current nesting level inline int NestingLevelLookBehind(unsigned int startPos, Accessor &styler) { int ch; int nestingLevel = 0; for (unsigned int i = 0; i < startPos; i++) { ch = styler.SafeGetCharAt(i); if (ch == '{') nestingLevel++; else if (ch == '}') nestingLevel--; } return nestingLevel; } static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &css1Props = *keywordlists[0]; WordList &pseudoClasses = *keywordlists[1]; WordList &css2Props = *keywordlists[2]; WordList &css3Props = *keywordlists[3]; WordList &pseudoElements = *keywordlists[4]; WordList &exProps = *keywordlists[5]; WordList &exPseudoClasses = *keywordlists[6]; WordList &exPseudoElements = *keywordlists[7]; StyleContext sc(startPos, length, initStyle, styler); int lastState = -1; // before operator int lastStateC = -1; // before comment int lastStateS = -1; // before single-quoted/double-quoted string int lastStateVar = -1; // before variable (SCSS) int lastStateVal = -1; // before value (SCSS) int op = ' '; // last operator int opPrev = ' '; // last operator bool insideParentheses = false; // true if currently in a CSS url() or similar construct // property lexer.css.scss.language // Set to 1 for Sassy CSS (.scss) bool isScssDocument = styler.GetPropertyInt("lexer.css.scss.language") != 0; // property lexer.css.less.language // Set to 1 for Less CSS (.less) bool isLessDocument = styler.GetPropertyInt("lexer.css.less.language") != 0; // property lexer.css.hss.language // Set to 1 for HSS (.hss) bool isHssDocument = styler.GetPropertyInt("lexer.css.hss.language") != 0; // SCSS/LESS/HSS have the concept of variable bool hasVariables = isScssDocument || isLessDocument || isHssDocument; char varPrefix = 0; if (hasVariables) varPrefix = isLessDocument ? '@' : '$'; // SCSS/LESS/HSS support single-line comments typedef enum _CommentModes { eCommentBlock = 0, eCommentLine = 1} CommentMode; CommentMode comment_mode = eCommentBlock; bool hasSingleLineComments = isScssDocument || isLessDocument || isHssDocument; // must keep track of nesting level in document types that support it (SCSS/LESS/HSS) bool hasNesting = false; int nestingLevel = 0; if (isScssDocument || isLessDocument || isHssDocument) { hasNesting = true; nestingLevel = NestingLevelLookBehind(startPos, styler); } // "the loop" for (; sc.More(); sc.Forward()) { if (sc.state == SCE_CSS_COMMENT && ((comment_mode == eCommentBlock && sc.Match('*', '/')) || (comment_mode == eCommentLine && sc.atLineEnd))) { if (lastStateC == -1) { // backtrack to get last state: // comments are like whitespace, so we must return to the previous state unsigned int i = startPos; for (; i > 0; i--) { if ((lastStateC = styler.StyleAt(i-1)) != SCE_CSS_COMMENT) { if (lastStateC == SCE_CSS_OPERATOR) { op = styler.SafeGetCharAt(i-1); opPrev = styler.SafeGetCharAt(i-2); while (--i) { lastState = styler.StyleAt(i-1); if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT) break; } if (i == 0) lastState = SCE_CSS_DEFAULT; } break; } } if (i == 0) lastStateC = SCE_CSS_DEFAULT; } if (comment_mode == eCommentBlock) { sc.Forward(); sc.ForwardSetState(lastStateC); } else /* eCommentLine */ { sc.SetState(lastStateC); } } if (sc.state == SCE_CSS_COMMENT) continue; if (sc.state == SCE_CSS_DOUBLESTRING || sc.state == SCE_CSS_SINGLESTRING) { if (sc.ch != (sc.state == SCE_CSS_DOUBLESTRING ? '\"' : '\'')) continue; unsigned int i = sc.currentPos; while (i && styler[i-1] == '\\') i--; if ((sc.currentPos - i) % 2 == 1) continue; sc.ForwardSetState(lastStateS); } if (sc.state == SCE_CSS_OPERATOR) { if (op == ' ') { unsigned int i = startPos; op = styler.SafeGetCharAt(i-1); opPrev = styler.SafeGetCharAt(i-2); while (--i) { lastState = styler.StyleAt(i-1); if (lastState != SCE_CSS_OPERATOR && lastState != SCE_CSS_COMMENT) break; } } switch (op) { case '@': if (lastState == SCE_CSS_DEFAULT || hasNesting) sc.SetState(SCE_CSS_DIRECTIVE); break; case '>': case '+': if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID || lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS) sc.SetState(SCE_CSS_DEFAULT); break; case '[': if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID || lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS) sc.SetState(SCE_CSS_ATTRIBUTE); break; case ']': if (lastState == SCE_CSS_ATTRIBUTE) sc.SetState(SCE_CSS_TAG); break; case '{': nestingLevel++; switch (lastState) { case SCE_CSS_MEDIA: sc.SetState(SCE_CSS_DEFAULT); break; case SCE_CSS_TAG: case SCE_CSS_DIRECTIVE: sc.SetState(SCE_CSS_IDENTIFIER); break; } break; case '}': if (--nestingLevel < 0) nestingLevel = 0; switch (lastState) { case SCE_CSS_DEFAULT: case SCE_CSS_VALUE: case SCE_CSS_IMPORTANT: case SCE_CSS_IDENTIFIER: case SCE_CSS_IDENTIFIER2: case SCE_CSS_IDENTIFIER3: if (hasNesting) sc.SetState(nestingLevel > 0 ? SCE_CSS_IDENTIFIER : SCE_CSS_DEFAULT); else sc.SetState(SCE_CSS_DEFAULT); break; } break; case '(': if (lastState == SCE_CSS_PSEUDOCLASS) sc.SetState(SCE_CSS_TAG); else if (lastState == SCE_CSS_EXTENDED_PSEUDOCLASS) sc.SetState(SCE_CSS_EXTENDED_PSEUDOCLASS); break; case ')': if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID || lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS || lastState == SCE_CSS_PSEUDOELEMENT || lastState == SCE_CSS_EXTENDED_PSEUDOELEMENT) sc.SetState(SCE_CSS_TAG); break; case ':': switch (lastState) { case SCE_CSS_TAG: case SCE_CSS_DEFAULT: case SCE_CSS_CLASS: case SCE_CSS_ID: case SCE_CSS_PSEUDOCLASS: case SCE_CSS_EXTENDED_PSEUDOCLASS: case SCE_CSS_UNKNOWN_PSEUDOCLASS: case SCE_CSS_PSEUDOELEMENT: case SCE_CSS_EXTENDED_PSEUDOELEMENT: sc.SetState(SCE_CSS_PSEUDOCLASS); break; case SCE_CSS_IDENTIFIER: case SCE_CSS_IDENTIFIER2: case SCE_CSS_IDENTIFIER3: case SCE_CSS_EXTENDED_IDENTIFIER: case SCE_CSS_UNKNOWN_IDENTIFIER: case SCE_CSS_VARIABLE: sc.SetState(SCE_CSS_VALUE); lastStateVal = lastState; break; } break; case '.': if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID || lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS) sc.SetState(SCE_CSS_CLASS); break; case '#': if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DEFAULT || lastState == SCE_CSS_CLASS || lastState == SCE_CSS_ID || lastState == SCE_CSS_PSEUDOCLASS || lastState == SCE_CSS_EXTENDED_PSEUDOCLASS || lastState == SCE_CSS_UNKNOWN_PSEUDOCLASS) sc.SetState(SCE_CSS_ID); break; case ',': case '|': case '~': if (lastState == SCE_CSS_TAG) sc.SetState(SCE_CSS_DEFAULT); break; case ';': switch (lastState) { case SCE_CSS_DIRECTIVE: if (hasNesting) { sc.SetState(nestingLevel > 0 ? SCE_CSS_IDENTIFIER : SCE_CSS_DEFAULT); } else { sc.SetState(SCE_CSS_DEFAULT); } break; case SCE_CSS_VALUE: case SCE_CSS_IMPORTANT: // data URLs can have semicolons; simplistically check for wrapping parentheses and move along if (insideParentheses) { sc.SetState(lastState); } else { if (lastStateVal == SCE_CSS_VARIABLE) { sc.SetState(SCE_CSS_DEFAULT); } else { sc.SetState(SCE_CSS_IDENTIFIER); } } break; case SCE_CSS_VARIABLE: if (lastStateVar == SCE_CSS_VALUE) { // data URLs can have semicolons; simplistically check for wrapping parentheses and move along if (insideParentheses) { sc.SetState(SCE_CSS_VALUE); } else { sc.SetState(SCE_CSS_IDENTIFIER); } } else { sc.SetState(SCE_CSS_DEFAULT); } break; } break; case '!': if (lastState == SCE_CSS_VALUE) sc.SetState(SCE_CSS_IMPORTANT); break; } } if (sc.ch == '*' && sc.state == SCE_CSS_DEFAULT) { sc.SetState(SCE_CSS_TAG); continue; } // check for inside parentheses (whether part of an "operator" or not) if (sc.ch == '(') insideParentheses = true; else if (sc.ch == ')') insideParentheses = false; // SCSS special modes if (hasVariables) { // variable name if (sc.ch == varPrefix) { switch (sc.state) { case SCE_CSS_DEFAULT: if (isLessDocument) // give priority to pseudo elements break; case SCE_CSS_VALUE: lastStateVar = sc.state; sc.SetState(SCE_CSS_VARIABLE); continue; } } if (sc.state == SCE_CSS_VARIABLE) { if (IsAWordChar(sc.ch)) { // still looking at the variable name continue; } if (lastStateVar == SCE_CSS_VALUE) { // not looking at the variable name any more, and it was part of a value sc.SetState(SCE_CSS_VALUE); } } // nested rule parent selector if (sc.ch == '&') { switch (sc.state) { case SCE_CSS_DEFAULT: case SCE_CSS_IDENTIFIER: sc.SetState(SCE_CSS_TAG); continue; } } } // nesting rules that apply to SCSS and Less if (hasNesting) { // check for nested rule selector if (sc.state == SCE_CSS_IDENTIFIER && (IsAWordChar(sc.ch) || sc.ch == ':' || sc.ch == '.' || sc.ch == '#')) { // look ahead to see whether { comes before next ; and } unsigned int endPos = startPos + length; int ch; for (unsigned int i = sc.currentPos; i < endPos; i++) { ch = styler.SafeGetCharAt(i); if (ch == ';' || ch == '}') break; if (ch == '{') { sc.SetState(SCE_CSS_DEFAULT); continue; } } } } if (IsAWordChar(sc.ch)) { if (sc.state == SCE_CSS_DEFAULT) sc.SetState(SCE_CSS_TAG); continue; } if (IsAWordChar(sc.chPrev) && ( sc.state == SCE_CSS_IDENTIFIER || sc.state == SCE_CSS_IDENTIFIER2 || sc.state == SCE_CSS_IDENTIFIER3 || sc.state == SCE_CSS_EXTENDED_IDENTIFIER || sc.state == SCE_CSS_UNKNOWN_IDENTIFIER || sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_PSEUDOELEMENT || sc.state == SCE_CSS_EXTENDED_PSEUDOCLASS || sc.state == SCE_CSS_EXTENDED_PSEUDOELEMENT || sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS || sc.state == SCE_CSS_IMPORTANT || sc.state == SCE_CSS_DIRECTIVE )) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); char *s2 = s; while (*s2 && !IsAWordChar(*s2)) s2++; switch (sc.state) { case SCE_CSS_IDENTIFIER: case SCE_CSS_IDENTIFIER2: case SCE_CSS_IDENTIFIER3: case SCE_CSS_EXTENDED_IDENTIFIER: case SCE_CSS_UNKNOWN_IDENTIFIER: if (css1Props.InList(s2)) sc.ChangeState(SCE_CSS_IDENTIFIER); else if (css2Props.InList(s2)) sc.ChangeState(SCE_CSS_IDENTIFIER2); else if (css3Props.InList(s2)) sc.ChangeState(SCE_CSS_IDENTIFIER3); else if (exProps.InList(s2)) sc.ChangeState(SCE_CSS_EXTENDED_IDENTIFIER); else sc.ChangeState(SCE_CSS_UNKNOWN_IDENTIFIER); break; case SCE_CSS_PSEUDOCLASS: case SCE_CSS_PSEUDOELEMENT: case SCE_CSS_EXTENDED_PSEUDOCLASS: case SCE_CSS_EXTENDED_PSEUDOELEMENT: case SCE_CSS_UNKNOWN_PSEUDOCLASS: if (op == ':' && opPrev != ':' && pseudoClasses.InList(s2)) sc.ChangeState(SCE_CSS_PSEUDOCLASS); else if (opPrev == ':' && pseudoElements.InList(s2)) sc.ChangeState(SCE_CSS_PSEUDOELEMENT); else if ((op == ':' || (op == '(' && lastState == SCE_CSS_EXTENDED_PSEUDOCLASS)) && opPrev != ':' && exPseudoClasses.InList(s2)) sc.ChangeState(SCE_CSS_EXTENDED_PSEUDOCLASS); else if (opPrev == ':' && exPseudoElements.InList(s2)) sc.ChangeState(SCE_CSS_EXTENDED_PSEUDOELEMENT); else sc.ChangeState(SCE_CSS_UNKNOWN_PSEUDOCLASS); break; case SCE_CSS_IMPORTANT: if (strcmp(s2, "important") != 0) sc.ChangeState(SCE_CSS_VALUE); break; case SCE_CSS_DIRECTIVE: if (op == '@' && strcmp(s2, "media") == 0) sc.ChangeState(SCE_CSS_MEDIA); break; } } if (sc.ch != '.' && sc.ch != ':' && sc.ch != '#' && ( sc.state == SCE_CSS_CLASS || sc.state == SCE_CSS_ID || (sc.ch != '(' && sc.ch != ')' && ( /* This line of the condition makes it possible to extend pseudo-classes with parentheses */ sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_PSEUDOELEMENT || sc.state == SCE_CSS_EXTENDED_PSEUDOCLASS || sc.state == SCE_CSS_EXTENDED_PSEUDOELEMENT || sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS )) )) sc.SetState(SCE_CSS_TAG); if (sc.Match('/', '*')) { lastStateC = sc.state; comment_mode = eCommentBlock; sc.SetState(SCE_CSS_COMMENT); sc.Forward(); } else if (hasSingleLineComments && sc.Match('/', '/') && !insideParentheses) { // note that we've had to treat ([...]// as the start of a URL not a comment, e.g. url(http://example.com), url(//example.com) lastStateC = sc.state; comment_mode = eCommentLine; sc.SetState(SCE_CSS_COMMENT); sc.Forward(); } else if ((sc.state == SCE_CSS_VALUE || sc.state == SCE_CSS_ATTRIBUTE) && (sc.ch == '\"' || sc.ch == '\'')) { lastStateS = sc.state; sc.SetState((sc.ch == '\"' ? SCE_CSS_DOUBLESTRING : SCE_CSS_SINGLESTRING)); } else if (IsCssOperator(sc.ch) && (sc.state != SCE_CSS_ATTRIBUTE || sc.ch == ']') && (sc.state != SCE_CSS_VALUE || sc.ch == ';' || sc.ch == '}' || sc.ch == '!') && ((sc.state != SCE_CSS_DIRECTIVE && sc.state != SCE_CSS_MEDIA) || sc.ch == ';' || sc.ch == '{') ) { if (sc.state != SCE_CSS_OPERATOR) lastState = sc.state; sc.SetState(SCE_CSS_OPERATOR); op = sc.ch; opPrev = sc.chPrev; } } sc.Complete(); } static void FoldCSSDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; bool inComment = (styler.StyleAt(startPos-1) == SCE_CSS_COMMENT); for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int style = styler.StyleAt(i); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment) { if (!inComment && (style == SCE_CSS_COMMENT)) levelCurrent++; else if (inComment && (style != SCE_CSS_COMMENT)) levelCurrent--; inComment = (style == SCE_CSS_COMMENT); } if (style == SCE_CSS_OPERATOR) { if (ch == '{') { levelCurrent++; } else if (ch == '}') { levelCurrent--; } } if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char * const cssWordListDesc[] = { "CSS1 Properties", "Pseudo-classes", "CSS2 Properties", "CSS3 Properties", "Pseudo-elements", "Browser-Specific CSS Properties", "Browser-Specific Pseudo-classes", "Browser-Specific Pseudo-elements", 0 }; LexerModule lmCss(SCLEX_CSS, ColouriseCssDoc, "css", FoldCSSDoc, cssWordListDesc); |
Added lexers/LexCaml.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 |
// Scintilla source code edit control /** @file LexCaml.cxx ** Lexer for Objective Caml. **/ // Copyright 2005-2009 by Robert Roessler <robertr@rftp.com> // The License.txt file describes the conditions under which this software may be distributed. /* Release History 20050204 Initial release. 20050205 Quick compiler standards/"cleanliness" adjustment. 20050206 Added cast for IsLeadByte(). 20050209 Changes to "external" build support. 20050306 Fix for 1st-char-in-doc "corner" case. 20050502 Fix for [harmless] one-past-the-end coloring. 20050515 Refined numeric token recognition logic. 20051125 Added 2nd "optional" keywords class. 20051129 Support "magic" (read-only) comments for RCaml. 20051204 Swtich to using StyleContext infrastructure. 20090629 Add full Standard ML '97 support. */ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "PropSetSimple.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" // Since the Microsoft __iscsym[f] funcs are not ANSI... inline int iscaml(int c) {return isalnum(c) || c == '_';} inline int iscamlf(int c) {return isalpha(c) || c == '_';} static const int baseT[24] = { 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A - L */ 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,16 /* M - X */ }; #ifdef SCI_NAMESPACE using namespace Scintilla; #endif #ifdef BUILD_AS_EXTERNAL_LEXER /* (actually seems to work!) */ #include <string> #include "WindowAccessor.h" #include "ExternalLexer.h" #undef EXT_LEXER_DECL #define EXT_LEXER_DECL __declspec( dllexport ) __stdcall #if PLAT_WIN #include <windows.h> #endif static void ColouriseCamlDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler); static void FoldCamlDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler); static void InternalLexOrFold(int lexOrFold, unsigned int startPos, int length, int initStyle, char *words[], WindowID window, char *props); static const char* LexerName = "caml"; #ifdef TRACE void Platform::DebugPrintf(const char *format, ...) { char buffer[2000]; va_list pArguments; va_start(pArguments, format); vsprintf(buffer,format,pArguments); va_end(pArguments); Platform::DebugDisplay(buffer); } #else void Platform::DebugPrintf(const char *, ...) { } #endif bool Platform::IsDBCSLeadByte(int codePage, char ch) { return ::IsDBCSLeadByteEx(codePage, ch) != 0; } long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, long lParam) { return ::SendMessage(reinterpret_cast<HWND>(w), msg, wParam, lParam); } long Platform::SendScintillaPointer(WindowID w, unsigned int msg, unsigned long wParam, void *lParam) { return ::SendMessage(reinterpret_cast<HWND>(w), msg, wParam, reinterpret_cast<LPARAM>(lParam)); } void EXT_LEXER_DECL Fold(unsigned int lexer, unsigned int startPos, int length, int initStyle, char *words[], WindowID window, char *props) { // below useless evaluation(s) to supress "not used" warnings lexer; // build expected data structures and do the Fold InternalLexOrFold(1, startPos, length, initStyle, words, window, props); } int EXT_LEXER_DECL GetLexerCount() { return 1; // just us [Objective] Caml lexers here! } void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength) { // below useless evaluation(s) to supress "not used" warnings Index; // return as much of our lexer name as will fit (what's up with Index?) if (buflength > 0) { buflength--; int n = strlen(LexerName); if (n > buflength) n = buflength; memcpy(name, LexerName, n), name[n] = '\0'; } } void EXT_LEXER_DECL Lex(unsigned int lexer, unsigned int startPos, int length, int initStyle, char *words[], WindowID window, char *props) { // below useless evaluation(s) to supress "not used" warnings lexer; // build expected data structures and do the Lex InternalLexOrFold(0, startPos, length, initStyle, words, window, props); } static void InternalLexOrFold(int foldOrLex, unsigned int startPos, int length, int initStyle, char *words[], WindowID window, char *props) { // create and initialize a WindowAccessor (including contained PropSet) PropSetSimple ps; ps.SetMultiple(props); WindowAccessor wa(window, ps); // create and initialize WordList(s) int nWL = 0; for (; words[nWL]; nWL++) ; // count # of WordList PTRs needed WordList** wl = new WordList* [nWL + 1];// alloc WordList PTRs int i = 0; for (; i < nWL; i++) { wl[i] = new WordList(); // (works or THROWS bad_alloc EXCEPTION) wl[i]->Set(words[i]); } wl[i] = 0; // call our "internal" folder/lexer (... then do Flush!) if (foldOrLex) FoldCamlDoc(startPos, length, initStyle, wl, wa); else ColouriseCamlDoc(startPos, length, initStyle, wl, wa); wa.Flush(); // clean up before leaving for (i = nWL - 1; i >= 0; i--) delete wl[i]; delete [] wl; } static #endif /* BUILD_AS_EXTERNAL_LEXER */ void ColouriseCamlDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { // initialize styler StyleContext sc(startPos, length, initStyle, styler); int chBase = 0, chToken = 0, chLit = 0; WordList& keywords = *keywordlists[0]; WordList& keywords2 = *keywordlists[1]; WordList& keywords3 = *keywordlists[2]; const bool isSML = keywords.InList("andalso"); const int useMagic = styler.GetPropertyInt("lexer.caml.magic", 0); // set up [initial] state info (terminating states that shouldn't "bleed") const int state_ = sc.state & 0x0f; if (state_ <= SCE_CAML_CHAR || (isSML && state_ == SCE_CAML_STRING)) sc.state = SCE_CAML_DEFAULT; int nesting = (state_ >= SCE_CAML_COMMENT)? (state_ - SCE_CAML_COMMENT): 0; // foreach char in range... while (sc.More()) { // set up [per-char] state info int state2 = -1; // (ASSUME no state change) int chColor = sc.currentPos - 1;// (ASSUME standard coloring range) bool advance = true; // (ASSUME scanner "eats" 1 char) // step state machine switch (sc.state & 0x0f) { case SCE_CAML_DEFAULT: chToken = sc.currentPos; // save [possible] token start (JIC) // it's wide open; what do we have? if (iscamlf(sc.ch)) state2 = SCE_CAML_IDENTIFIER; else if (!isSML && sc.Match('`') && iscamlf(sc.chNext)) state2 = SCE_CAML_TAGNAME; else if (!isSML && sc.Match('#') && isdigit(sc.chNext)) state2 = SCE_CAML_LINENUM; else if (isdigit(sc.ch)) { // it's a number, assume base 10 state2 = SCE_CAML_NUMBER, chBase = 10; if (sc.Match('0')) { // there MAY be a base specified... const char* baseC = "bBoOxX"; if (isSML) { if (sc.chNext == 'w') sc.Forward(); // (consume SML "word" indicator) baseC = "x"; } // ... change to specified base AS REQUIRED if (strchr(baseC, sc.chNext)) chBase = baseT[tolower(sc.chNext) - 'a'], sc.Forward(); } } else if (!isSML && sc.Match('\'')) // (Caml char literal?) state2 = SCE_CAML_CHAR, chLit = 0; else if (isSML && sc.Match('#', '"')) // (SML char literal?) state2 = SCE_CAML_CHAR, sc.Forward(); else if (sc.Match('"')) state2 = SCE_CAML_STRING; else if (sc.Match('(', '*')) state2 = SCE_CAML_COMMENT, sc.Forward(), sc.ch = ' '; // (*)... else if (strchr("!?~" /* Caml "prefix-symbol" */ "=<>@^|&+-*/$%" /* Caml "infix-symbol" */ "()[]{};,:.#", sc.ch) // Caml "bracket" or ;,:.# // SML "extra" ident chars || (isSML && (sc.Match('\\') || sc.Match('`')))) state2 = SCE_CAML_OPERATOR; break; case SCE_CAML_IDENTIFIER: // [try to] interpret as [additional] identifier char if (!(iscaml(sc.ch) || sc.Match('\''))) { const int n = sc.currentPos - chToken; if (n < 24) { // length is believable as keyword, [re-]construct token char t[24]; for (int i = -n; i < 0; i++) t[n + i] = static_cast<char>(sc.GetRelative(i)); t[n] = '\0'; // special-case "_" token as KEYWORD if ((n == 1 && sc.chPrev == '_') || keywords.InList(t)) sc.ChangeState(SCE_CAML_KEYWORD); else if (keywords2.InList(t)) sc.ChangeState(SCE_CAML_KEYWORD2); else if (keywords3.InList(t)) sc.ChangeState(SCE_CAML_KEYWORD3); } state2 = SCE_CAML_DEFAULT, advance = false; } break; case SCE_CAML_TAGNAME: // [try to] interpret as [additional] tagname char if (!(iscaml(sc.ch) || sc.Match('\''))) state2 = SCE_CAML_DEFAULT, advance = false; break; /*case SCE_CAML_KEYWORD: case SCE_CAML_KEYWORD2: case SCE_CAML_KEYWORD3: // [try to] interpret as [additional] keyword char if (!iscaml(ch)) state2 = SCE_CAML_DEFAULT, advance = false; break;*/ case SCE_CAML_LINENUM: // [try to] interpret as [additional] linenum directive char if (!isdigit(sc.ch)) state2 = SCE_CAML_DEFAULT, advance = false; break; case SCE_CAML_OPERATOR: { // [try to] interpret as [additional] operator char const char* o = 0; if (iscaml(sc.ch) || isspace(sc.ch) // ident or whitespace || (o = strchr(")]};,\'\"#", sc.ch),o) // "termination" chars || (!isSML && sc.Match('`')) // Caml extra term char || (!strchr("!$%&*+-./:<=>?@^|~", sc.ch)// "operator" chars // SML extra ident chars && !(isSML && (sc.Match('\\') || sc.Match('`'))))) { // check for INCLUSIVE termination if (o && strchr(")]};,", sc.ch)) { if ((sc.Match(')') && sc.chPrev == '(') || (sc.Match(']') && sc.chPrev == '[')) // special-case "()" and "[]" tokens as KEYWORDS sc.ChangeState(SCE_CAML_KEYWORD); chColor++; } else advance = false; state2 = SCE_CAML_DEFAULT; } break; } case SCE_CAML_NUMBER: // [try to] interpret as [additional] numeric literal char if ((!isSML && sc.Match('_')) || IsADigit(sc.ch, chBase)) break; // how about an integer suffix? if (!isSML && (sc.Match('l') || sc.Match('L') || sc.Match('n')) && (sc.chPrev == '_' || IsADigit(sc.chPrev, chBase))) break; // or a floating-point literal? if (chBase == 10) { // with a decimal point? if (sc.Match('.') && ((!isSML && sc.chPrev == '_') || IsADigit(sc.chPrev, chBase))) break; // with an exponent? (I) if ((sc.Match('e') || sc.Match('E')) && ((!isSML && (sc.chPrev == '.' || sc.chPrev == '_')) || IsADigit(sc.chPrev, chBase))) break; // with an exponent? (II) if (((!isSML && (sc.Match('+') || sc.Match('-'))) || (isSML && sc.Match('~'))) && (sc.chPrev == 'e' || sc.chPrev == 'E')) break; } // it looks like we have run out of number state2 = SCE_CAML_DEFAULT, advance = false; break; case SCE_CAML_CHAR: if (!isSML) { // [try to] interpret as [additional] char literal char if (sc.Match('\\')) { chLit = 1; // (definitely IS a char literal) if (sc.chPrev == '\\') sc.ch = ' '; // (...\\') // should we be terminating - one way or another? } else if ((sc.Match('\'') && sc.chPrev != '\\') || sc.atLineEnd) { state2 = SCE_CAML_DEFAULT; if (sc.Match('\'')) chColor++; else sc.ChangeState(SCE_CAML_IDENTIFIER); // ... maybe a char literal, maybe not } else if (chLit < 1 && sc.currentPos - chToken >= 2) sc.ChangeState(SCE_CAML_IDENTIFIER), advance = false; break; }/* else // fall through for SML char literal (handle like string) */ case SCE_CAML_STRING: // [try to] interpret as [additional] [SML char/] string literal char if (isSML && sc.Match('\\') && sc.chPrev != '\\' && isspace(sc.chNext)) state2 = SCE_CAML_WHITE; else if (sc.Match('\\') && sc.chPrev == '\\') sc.ch = ' '; // (...\\") // should we be terminating - one way or another? else if ((sc.Match('"') && sc.chPrev != '\\') || (isSML && sc.atLineEnd)) { state2 = SCE_CAML_DEFAULT; if (sc.Match('"')) chColor++; } break; case SCE_CAML_WHITE: // [try to] interpret as [additional] SML embedded whitespace char if (sc.Match('\\')) { // style this puppy NOW... state2 = SCE_CAML_STRING, sc.ch = ' ' /* (...\") */, chColor++, styler.ColourTo(chColor, SCE_CAML_WHITE), styler.Flush(); // ... then backtrack to determine original SML literal type int p = chColor - 2; for (; p >= 0 && styler.StyleAt(p) == SCE_CAML_WHITE; p--) ; if (p >= 0) state2 = static_cast<int>(styler.StyleAt(p)); // take care of state change NOW sc.ChangeState(state2), state2 = -1; } break; case SCE_CAML_COMMENT: case SCE_CAML_COMMENT1: case SCE_CAML_COMMENT2: case SCE_CAML_COMMENT3: // we're IN a comment - does this start a NESTED comment? if (sc.Match('(', '*')) state2 = sc.state + 1, chToken = sc.currentPos, sc.Forward(), sc.ch = ' ' /* (*)... */, nesting++; // [try to] interpret as [additional] comment char else if (sc.Match(')') && sc.chPrev == '*') { if (nesting) state2 = (sc.state & 0x0f) - 1, chToken = 0, nesting--; else state2 = SCE_CAML_DEFAULT; chColor++; // enable "magic" (read-only) comment AS REQUIRED } else if (useMagic && sc.currentPos - chToken == 4 && sc.Match('c') && sc.chPrev == 'r' && sc.GetRelative(-2) == '@') sc.state |= 0x10; // (switch to read-only comment style) break; } // handle state change and char coloring AS REQUIRED if (state2 >= 0) styler.ColourTo(chColor, sc.state), sc.ChangeState(state2); // move to next char UNLESS re-scanning current char if (advance) sc.Forward(); } // do any required terminal char coloring (JIC) sc.Complete(); } #ifdef BUILD_AS_EXTERNAL_LEXER static #endif /* BUILD_AS_EXTERNAL_LEXER */ void FoldCamlDoc( unsigned int, int, int, WordList *[], Accessor &) { } static const char * const camlWordListDesc[] = { "Keywords", // primary Objective Caml keywords "Keywords2", // "optional" keywords (typically from Pervasives) "Keywords3", // "optional" keywords (typically typenames) 0 }; #ifndef BUILD_AS_EXTERNAL_LEXER LexerModule lmCaml(SCLEX_CAML, ColouriseCamlDoc, "caml", FoldCamlDoc, camlWordListDesc); #endif /* BUILD_AS_EXTERNAL_LEXER */ |
Added lexers/LexCmake.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 |
// Scintilla source code edit control /** @file LexCmake.cxx ** Lexer for Cmake **/ // Copyright 2007 by Cristian Adam <cristian [dot] adam [at] gmx [dot] net> // based on the NSIS lexer // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static bool isCmakeNumber(char ch) { return(ch >= '0' && ch <= '9'); } static bool isCmakeChar(char ch) { return(ch == '.' ) || (ch == '_' ) || isCmakeNumber(ch) || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); } static bool isCmakeLetter(char ch) { return(ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); } static bool CmakeNextLineHasElse(unsigned int start, unsigned int end, Accessor &styler) { int nNextLine = -1; for ( unsigned int i = start; i < end; i++ ) { char cNext = styler.SafeGetCharAt( i ); if ( cNext == '\n' ) { nNextLine = i+1; break; } } if ( nNextLine == -1 ) // We never foudn the next line... return false; for ( unsigned int firstChar = nNextLine; firstChar < end; firstChar++ ) { char cNext = styler.SafeGetCharAt( firstChar ); if ( cNext == ' ' ) continue; if ( cNext == '\t' ) continue; if ( styler.Match(firstChar, "ELSE") || styler.Match(firstChar, "else")) return true; break; } return false; } static int calculateFoldCmake(unsigned int start, unsigned int end, int foldlevel, Accessor &styler, bool bElse) { // If the word is too long, it is not what we are looking for if ( end - start > 20 ) return foldlevel; int newFoldlevel = foldlevel; char s[20]; // The key word we are looking for has atmost 13 characters for (unsigned int i = 0; i < end - start + 1 && i < 19; i++) { s[i] = static_cast<char>( styler[ start + i ] ); s[i + 1] = '\0'; } if ( CompareCaseInsensitive(s, "IF") == 0 || CompareCaseInsensitive(s, "WHILE") == 0 || CompareCaseInsensitive(s, "MACRO") == 0 || CompareCaseInsensitive(s, "FOREACH") == 0 || CompareCaseInsensitive(s, "ELSEIF") == 0 ) newFoldlevel++; else if ( CompareCaseInsensitive(s, "ENDIF") == 0 || CompareCaseInsensitive(s, "ENDWHILE") == 0 || CompareCaseInsensitive(s, "ENDMACRO") == 0 || CompareCaseInsensitive(s, "ENDFOREACH") == 0) newFoldlevel--; else if ( bElse && CompareCaseInsensitive(s, "ELSEIF") == 0 ) newFoldlevel++; else if ( bElse && CompareCaseInsensitive(s, "ELSE") == 0 ) newFoldlevel++; return newFoldlevel; } static int classifyWordCmake(unsigned int start, unsigned int end, WordList *keywordLists[], Accessor &styler ) { char word[100] = {0}; char lowercaseWord[100] = {0}; WordList &Commands = *keywordLists[0]; WordList &Parameters = *keywordLists[1]; WordList &UserDefined = *keywordLists[2]; for (unsigned int i = 0; i < end - start + 1 && i < 99; i++) { word[i] = static_cast<char>( styler[ start + i ] ); lowercaseWord[i] = static_cast<char>(tolower(word[i])); } // Check for special words... if ( CompareCaseInsensitive(word, "MACRO") == 0 || CompareCaseInsensitive(word, "ENDMACRO") == 0 ) return SCE_CMAKE_MACRODEF; if ( CompareCaseInsensitive(word, "IF") == 0 || CompareCaseInsensitive(word, "ENDIF") == 0 ) return SCE_CMAKE_IFDEFINEDEF; if ( CompareCaseInsensitive(word, "ELSEIF") == 0 || CompareCaseInsensitive(word, "ELSE") == 0 ) return SCE_CMAKE_IFDEFINEDEF; if ( CompareCaseInsensitive(word, "WHILE") == 0 || CompareCaseInsensitive(word, "ENDWHILE") == 0) return SCE_CMAKE_WHILEDEF; if ( CompareCaseInsensitive(word, "FOREACH") == 0 || CompareCaseInsensitive(word, "ENDFOREACH") == 0) return SCE_CMAKE_FOREACHDEF; if ( Commands.InList(lowercaseWord) ) return SCE_CMAKE_COMMANDS; if ( Parameters.InList(word) ) return SCE_CMAKE_PARAMETERS; if ( UserDefined.InList(word) ) return SCE_CMAKE_USERDEFINED; if ( strlen(word) > 3 ) { if ( word[1] == '{' && word[strlen(word)-1] == '}' ) return SCE_CMAKE_VARIABLE; } // To check for numbers if ( isCmakeNumber( word[0] ) ) { bool bHasSimpleCmakeNumber = true; for (unsigned int j = 1; j < end - start + 1 && j < 99; j++) { if ( !isCmakeNumber( word[j] ) ) { bHasSimpleCmakeNumber = false; break; } } if ( bHasSimpleCmakeNumber ) return SCE_CMAKE_NUMBER; } return SCE_CMAKE_DEFAULT; } static void ColouriseCmakeDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) { int state = SCE_CMAKE_DEFAULT; if ( startPos > 0 ) state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox styler.StartAt( startPos ); styler.GetLine( startPos ); unsigned int nLengthDoc = startPos + length; styler.StartSegment( startPos ); char cCurrChar; bool bVarInString = false; bool bClassicVarInString = false; unsigned int i; for ( i = startPos; i < nLengthDoc; i++ ) { cCurrChar = styler.SafeGetCharAt( i ); char cNextChar = styler.SafeGetCharAt(i+1); switch (state) { case SCE_CMAKE_DEFAULT: if ( cCurrChar == '#' ) { // we have a comment line styler.ColourTo(i-1, state ); state = SCE_CMAKE_COMMENT; break; } if ( cCurrChar == '"' ) { styler.ColourTo(i-1, state ); state = SCE_CMAKE_STRINGDQ; bVarInString = false; bClassicVarInString = false; break; } if ( cCurrChar == '\'' ) { styler.ColourTo(i-1, state ); state = SCE_CMAKE_STRINGRQ; bVarInString = false; bClassicVarInString = false; break; } if ( cCurrChar == '`' ) { styler.ColourTo(i-1, state ); state = SCE_CMAKE_STRINGLQ; bVarInString = false; bClassicVarInString = false; break; } // CMake Variable if ( cCurrChar == '$' || isCmakeChar(cCurrChar)) { styler.ColourTo(i-1,state); state = SCE_CMAKE_VARIABLE; // If it is a number, we must check and set style here first... if ( isCmakeNumber(cCurrChar) && (cNextChar == '\t' || cNextChar == ' ' || cNextChar == '\r' || cNextChar == '\n' ) ) styler.ColourTo( i, SCE_CMAKE_NUMBER); break; } break; case SCE_CMAKE_COMMENT: if ( cNextChar == '\n' || cNextChar == '\r' ) { // Special case: if ( cCurrChar == '\\' ) { styler.ColourTo(i-2,state); styler.ColourTo(i,SCE_CMAKE_DEFAULT); } else { styler.ColourTo(i,state); state = SCE_CMAKE_DEFAULT; } } break; case SCE_CMAKE_STRINGDQ: case SCE_CMAKE_STRINGLQ: case SCE_CMAKE_STRINGRQ: if ( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' ) break; // Ignore the next character, even if it is a quote of some sort if ( cCurrChar == '"' && state == SCE_CMAKE_STRINGDQ ) { styler.ColourTo(i,state); state = SCE_CMAKE_DEFAULT; break; } if ( cCurrChar == '`' && state == SCE_CMAKE_STRINGLQ ) { styler.ColourTo(i,state); state = SCE_CMAKE_DEFAULT; break; } if ( cCurrChar == '\'' && state == SCE_CMAKE_STRINGRQ ) { styler.ColourTo(i,state); state = SCE_CMAKE_DEFAULT; break; } if ( cNextChar == '\r' || cNextChar == '\n' ) { int nCurLine = styler.GetLine(i+1); int nBack = i; // We need to check if the previous line has a \ in it... bool bNextLine = false; while ( nBack > 0 ) { if ( styler.GetLine(nBack) != nCurLine ) break; char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here if ( cTemp == '\\' ) { bNextLine = true; break; } if ( cTemp != '\r' && cTemp != '\n' && cTemp != '\t' && cTemp != ' ' ) break; nBack--; } if ( bNextLine ) { styler.ColourTo(i+1,state); } if ( bNextLine == false ) { styler.ColourTo(i,state); state = SCE_CMAKE_DEFAULT; } } break; case SCE_CMAKE_VARIABLE: // CMake Variable: if ( cCurrChar == '$' ) state = SCE_CMAKE_DEFAULT; else if ( cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) ) state = SCE_CMAKE_DEFAULT; else if ( (isCmakeChar(cCurrChar) && !isCmakeChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' ) { state = classifyWordCmake( styler.GetStartSegment(), i, keywordLists, styler ); styler.ColourTo( i, state); state = SCE_CMAKE_DEFAULT; } else if ( !isCmakeChar( cCurrChar ) && cCurrChar != '{' && cCurrChar != '}' ) { if ( classifyWordCmake( styler.GetStartSegment(), i-1, keywordLists, styler) == SCE_CMAKE_NUMBER ) styler.ColourTo( i-1, SCE_CMAKE_NUMBER ); state = SCE_CMAKE_DEFAULT; if ( cCurrChar == '"' ) { state = SCE_CMAKE_STRINGDQ; bVarInString = false; bClassicVarInString = false; } else if ( cCurrChar == '`' ) { state = SCE_CMAKE_STRINGLQ; bVarInString = false; bClassicVarInString = false; } else if ( cCurrChar == '\'' ) { state = SCE_CMAKE_STRINGRQ; bVarInString = false; bClassicVarInString = false; } else if ( cCurrChar == '#' ) { state = SCE_CMAKE_COMMENT; } } break; } if ( state == SCE_CMAKE_COMMENT) { styler.ColourTo(i,state); } else if ( state == SCE_CMAKE_STRINGDQ || state == SCE_CMAKE_STRINGLQ || state == SCE_CMAKE_STRINGRQ ) { bool bIngoreNextDollarSign = false; if ( bVarInString && cCurrChar == '$' ) { bVarInString = false; bIngoreNextDollarSign = true; } else if ( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) ) { styler.ColourTo( i+1, SCE_CMAKE_STRINGVAR); bVarInString = false; bIngoreNextDollarSign = false; } else if ( bVarInString && !isCmakeChar(cNextChar) ) { int nWordState = classifyWordCmake( styler.GetStartSegment(), i, keywordLists, styler); if ( nWordState == SCE_CMAKE_VARIABLE ) styler.ColourTo( i, SCE_CMAKE_STRINGVAR); bVarInString = false; } // Covers "${TEST}..." else if ( bClassicVarInString && cNextChar == '}' ) { styler.ColourTo( i+1, SCE_CMAKE_STRINGVAR); bClassicVarInString = false; } // Start of var in string if ( !bIngoreNextDollarSign && cCurrChar == '$' && cNextChar == '{' ) { styler.ColourTo( i-1, state); bClassicVarInString = true; bVarInString = false; } else if ( !bIngoreNextDollarSign && cCurrChar == '$' ) { styler.ColourTo( i-1, state); bVarInString = true; bClassicVarInString = false; } } } // Colourise remaining document styler.ColourTo(nLengthDoc-1,state); } static void FoldCmakeDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { // No folding enabled, no reason to continue... if ( styler.GetPropertyInt("fold") == 0 ) return; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1; int lineCurrent = styler.GetLine(startPos); unsigned int safeStartPos = styler.LineStart( lineCurrent ); bool bArg1 = true; int nWordStart = -1; int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelNext = levelCurrent; for (unsigned int i = safeStartPos; i < startPos + length; i++) { char chCurr = styler.SafeGetCharAt(i); if ( bArg1 ) { if ( nWordStart == -1 && (isCmakeLetter(chCurr)) ) { nWordStart = i; } else if ( isCmakeLetter(chCurr) == false && nWordStart > -1 ) { int newLevel = calculateFoldCmake( nWordStart, i-1, levelNext, styler, foldAtElse); if ( newLevel == levelNext ) { if ( foldAtElse ) { if ( CmakeNextLineHasElse(i, startPos + length, styler) ) levelNext--; } } else levelNext = newLevel; bArg1 = false; } } if ( chCurr == '\n' ) { if ( bArg1 && foldAtElse) { if ( CmakeNextLineHasElse(i, startPos + length, styler) ) levelNext--; } // If we are on a new line... int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; if (levelUse < levelNext ) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) styler.SetLevel(lineCurrent, lev); lineCurrent++; levelCurrent = levelNext; bArg1 = true; // New line, lets look at first argument again nWordStart = -1; } } int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) styler.SetLevel(lineCurrent, lev); } static const char * const cmakeWordLists[] = { "Commands", "Parameters", "UserDefined", 0, 0,}; LexerModule lmCmake(SCLEX_CMAKE, ColouriseCmakeDoc, "cmake", FoldCmakeDoc, cmakeWordLists); |
Added lexers/LexCoffeeScript.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 |
// Scintilla source code edit control /** @file LexCoffeeScript.cxx ** Lexer for CoffeeScript. **/ // Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org> // Based on the Scintilla C++ Lexer // Written by Eric Promislow <ericp@activestate.com> in 2011 for the Komodo IDE // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "Platform.h" #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static bool IsSpaceEquiv(int state) { return (state <= SCE_C_COMMENTDOC // including SCE_C_DEFAULT, SCE_C_COMMENT, SCE_C_COMMENTLINE || state == SCE_C_COMMENTLINEDOC || state == SCE_C_COMMENTDOCKEYWORD || state == SCE_C_COMMENTDOCKEYWORDERROR || state == SCE_COFFEESCRIPT_COMMENTBLOCK || state == SCE_COFFEESCRIPT_VERBOSE_REGEX || state == SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT || state == SCE_C_WORD || state == SCE_C_REGEX); } // Preconditions: sc.currentPos points to a character after '+' or '-'. // The test for pos reaching 0 should be redundant, // and is in only for safety measures. // Limitation: this code will give the incorrect answer for code like // a = b+++/ptn/... // Putting a space between the '++' post-inc operator and the '+' binary op // fixes this, and is highly recommended for readability anyway. static bool FollowsPostfixOperator(StyleContext &sc, Accessor &styler) { int pos = (int) sc.currentPos; while (--pos > 0) { char ch = styler[pos]; if (ch == '+' || ch == '-') { return styler[pos - 1] == ch; } } return false; } static bool followsReturnKeyword(StyleContext &sc, Accessor &styler) { // Don't look at styles, so no need to flush. int pos = (int) sc.currentPos; int currentLine = styler.GetLine(pos); int lineStartPos = styler.LineStart(currentLine); char ch; while (--pos > lineStartPos) { ch = styler.SafeGetCharAt(pos); if (ch != ' ' && ch != '\t') { break; } } const char *retBack = "nruter"; const char *s = retBack; while (*s && pos >= lineStartPos && styler.SafeGetCharAt(pos) == *s) { s++; pos--; } return !*s; } static void ColouriseCoffeeScriptDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; // property styling.within.preprocessor // For C++ code, determines whether all preprocessor code is styled in the preprocessor style (0, the default) // or only from the initial # to the end of the command word(1). bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0; CharacterSet setOKBeforeRE(CharacterSet::setNone, "([{=,:;!%^&*|?~+-"); CharacterSet setCouldBePostOp(CharacterSet::setNone, "+-"); CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]"); CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true); // property lexer.cpp.allow.dollars // Set to 0 to disallow the '$' character in identifiers with the cpp lexer. if (styler.GetPropertyInt("lexer.cpp.allow.dollars", 1) != 0) { setWordStart.Add('$'); setWord.Add('$'); } int chPrevNonWhite = ' '; int visibleChars = 0; bool lastWordWasUUID = false; int styleBeforeDCKeyword = SCE_C_DEFAULT; bool continuationLine = false; bool isIncludePreprocessor = false; if (initStyle == SCE_C_PREPROCESSOR) { // Set continuationLine if last character of previous line is '\' int lineCurrent = styler.GetLine(startPos); if (lineCurrent > 0) { int chBack = styler.SafeGetCharAt(startPos-1, 0); int chBack2 = styler.SafeGetCharAt(startPos-2, 0); int lineEndChar = '!'; if (chBack2 == '\r' && chBack == '\n') { lineEndChar = styler.SafeGetCharAt(startPos-3, 0); } else if (chBack == '\n' || chBack == '\r') { lineEndChar = chBack2; } continuationLine = lineEndChar == '\\'; } } // look back to set chPrevNonWhite properly for better regex colouring int endPos = startPos + length; if (startPos > 0) { unsigned int back = startPos; styler.Flush(); while (back > 0 && IsSpaceEquiv(styler.StyleAt(--back))) ; if (styler.StyleAt(back) == SCE_C_OPERATOR) { chPrevNonWhite = styler.SafeGetCharAt(back); } if (startPos != back) { initStyle = styler.StyleAt(back); } startPos = back; } StyleContext sc(startPos, endPos - startPos, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.atLineStart) { // Reset states to begining of colourise so no surprises // if different sets of lines lexed. visibleChars = 0; lastWordWasUUID = false; isIncludePreprocessor = false; } // Handle line continuation generically. if (sc.ch == '\\') { if (sc.chNext == '\n' || sc.chNext == '\r') { sc.Forward(); if (sc.ch == '\r' && sc.chNext == '\n') { sc.Forward(); } continuationLine = true; continue; } } // Determine if the current state should terminate. switch (sc.state) { case SCE_C_OPERATOR: sc.SetState(SCE_C_DEFAULT); break; case SCE_C_NUMBER: // We accept almost anything because of hex. and number suffixes if (!setWord.Contains(sc.ch)) { sc.SetState(SCE_C_DEFAULT); } break; case SCE_C_IDENTIFIER: if (!setWord.Contains(sc.ch) || (sc.ch == '.') || (sc.ch == '$')) { char s[1000]; sc.GetCurrent(s, sizeof(s)); if (keywords.InList(s)) { lastWordWasUUID = strcmp(s, "uuid") == 0; sc.ChangeState(SCE_C_WORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_C_WORD2); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_C_GLOBALCLASS); } sc.SetState(SCE_C_DEFAULT); } break; case SCE_C_PREPROCESSOR: if (sc.atLineStart && !continuationLine) { sc.SetState(SCE_C_DEFAULT); } else if (stylingWithinPreprocessor) { if (IsASpace(sc.ch)) { sc.SetState(SCE_C_DEFAULT); } } else { if (sc.Match('/', '*') || sc.Match('/', '/')) { sc.SetState(SCE_C_DEFAULT); } } break; case SCE_C_COMMENT: if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_C_DEFAULT); } break; case SCE_C_COMMENTDOC: if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_C_DEFAULT); } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support // Verify that we have the conditions to mark a comment-doc-keyword if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) { styleBeforeDCKeyword = SCE_C_COMMENTDOC; sc.SetState(SCE_C_COMMENTDOCKEYWORD); } } break; case SCE_C_COMMENTLINE: if (sc.atLineStart) { sc.SetState(SCE_C_DEFAULT); } break; case SCE_C_COMMENTLINEDOC: if (sc.atLineStart) { sc.SetState(SCE_C_DEFAULT); } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support // Verify that we have the conditions to mark a comment-doc-keyword if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) { styleBeforeDCKeyword = SCE_C_COMMENTLINEDOC; sc.SetState(SCE_C_COMMENTDOCKEYWORD); } } break; case SCE_C_COMMENTDOCKEYWORD: if ((styleBeforeDCKeyword == SCE_C_COMMENTDOC) && sc.Match('*', '/')) { sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR); sc.Forward(); sc.ForwardSetState(SCE_C_DEFAULT); } else if (!setDoxygen.Contains(sc.ch)) { char s[100]; sc.GetCurrent(s, sizeof(s)); if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) { sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR); } sc.SetState(styleBeforeDCKeyword); } break; case SCE_C_STRING: if (isIncludePreprocessor) { if (sc.ch == '>') { sc.ForwardSetState(SCE_C_DEFAULT); isIncludePreprocessor = false; } } else if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_C_DEFAULT); } break; case SCE_C_CHARACTER: if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\'') { sc.ForwardSetState(SCE_C_DEFAULT); } break; case SCE_C_REGEX: if (sc.atLineStart) { sc.SetState(SCE_C_DEFAULT); } else if (sc.ch == '/') { sc.Forward(); while ((sc.ch < 0x80) && islower(sc.ch)) sc.Forward(); // gobble regex flags sc.SetState(SCE_C_DEFAULT); } else if (sc.ch == '\\') { // Gobble up the quoted character if (sc.chNext == '\\' || sc.chNext == '/') { sc.Forward(); } } break; case SCE_C_STRINGEOL: if (sc.atLineStart) { sc.SetState(SCE_C_DEFAULT); } break; case SCE_C_VERBATIM: if (sc.ch == '\"') { if (sc.chNext == '\"') { sc.Forward(); } else { sc.ForwardSetState(SCE_C_DEFAULT); } } break; case SCE_C_UUID: if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') { sc.SetState(SCE_C_DEFAULT); } break; case SCE_COFFEESCRIPT_COMMENTBLOCK: if (sc.Match("###")) { sc.ChangeState(SCE_C_COMMENT); sc.Forward(); sc.Forward(); sc.ForwardSetState(SCE_C_DEFAULT); } else if (sc.ch == '\\') { sc.Forward(); } break; case SCE_COFFEESCRIPT_VERBOSE_REGEX: if (sc.Match("///")) { sc.Forward(); sc.Forward(); sc.ChangeState(SCE_C_REGEX); sc.ForwardSetState(SCE_C_DEFAULT); } else if (sc.Match('#')) { sc.ChangeState(SCE_C_REGEX); sc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT); } else if (sc.ch == '\\') { sc.Forward(); } break; case SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT: if (sc.atLineStart) { sc.ChangeState(SCE_C_COMMENT); sc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX); } break; } // Determine if a new state should be entered. if (sc.state == SCE_C_DEFAULT) { if (sc.Match('@', '\"')) { sc.SetState(SCE_C_VERBATIM); sc.Forward(); } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { if (lastWordWasUUID) { sc.SetState(SCE_C_UUID); lastWordWasUUID = false; } else { sc.SetState(SCE_C_NUMBER); } } else if (setWordStart.Contains(sc.ch) || (sc.ch == '@') || (sc.ch == '$')) { if (lastWordWasUUID) { sc.SetState(SCE_C_UUID); lastWordWasUUID = false; } else { sc.SetState(SCE_C_IDENTIFIER); } } else if (sc.Match('/', '*')) { if (sc.Match("/**") || sc.Match("/*!")) { // Support of Qt/Doxygen doc. style sc.SetState(SCE_C_COMMENTDOC); } else { sc.SetState(SCE_C_COMMENT); } sc.Forward(); // Eat the * so it isn't used for the end of the comment } else if (sc.Match("///")) { sc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX); } else if (sc.ch == '/' && (setOKBeforeRE.Contains(chPrevNonWhite) || followsReturnKeyword(sc, styler)) && (!setCouldBePostOp.Contains(chPrevNonWhite) || !FollowsPostfixOperator(sc, styler))) { sc.SetState(SCE_C_REGEX); // JavaScript's RegEx } else if (sc.ch == '\"') { sc.SetState(SCE_C_STRING); isIncludePreprocessor = false; // ensure that '>' won't end the string } else if (isIncludePreprocessor && sc.ch == '<') { sc.SetState(SCE_C_STRING); } else if (sc.ch == '\'') { sc.SetState(SCE_C_CHARACTER); } else if (sc.ch == '#') { if (sc.Match("###")) { sc.SetState(SCE_COFFEESCRIPT_COMMENTBLOCK); } else { sc.SetState(SCE_C_COMMENTLINE); } } else if (isoperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_C_OPERATOR); } } if (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) { chPrevNonWhite = sc.ch; visibleChars++; } continuationLine = false; } // Change temporary coffeescript states into standard C ones. switch (sc.state) { case SCE_COFFEESCRIPT_COMMENTBLOCK: sc.ChangeState(SCE_C_COMMENT); break; case SCE_COFFEESCRIPT_VERBOSE_REGEX: sc.ChangeState(SCE_C_REGEX); break; case SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT: sc.ChangeState(SCE_C_COMMENTLINE); break; } sc.Complete(); } static bool IsCommentLine(int line, Accessor &styler) { int pos = styler.LineStart(line); int eol_pos = styler.LineStart(line + 1) - 1; for (int i = pos; i < eol_pos; i++) { char ch = styler[i]; if (ch == '#') return true; else if (ch == '/' && i < eol_pos - 1 && styler[i + 1] == '*') return true; else if (ch != ' ' && ch != '\t') return false; } return false; } static void FoldCoffeeScriptDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { // A simplified version of FoldPyDoc const int maxPos = startPos + length; const int maxLines = styler.GetLine(maxPos - 1); // Requested last line const int docLines = styler.GetLine(styler.Length() - 1); // Available last line // property fold.coffeescript.comment const bool foldComment = styler.GetPropertyInt("fold.coffeescript.comment") != 0; const bool foldCompact = styler.GetPropertyInt("fold.compact") != 0; // Backtrack to previous non-blank line so we can determine indent level // for any white space lines // and so we can fix any preceding fold level (which is why we go back // at least one line in all cases) int spaceFlags = 0; int lineCurrent = styler.GetLine(startPos); int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL); while (lineCurrent > 0) { lineCurrent--; indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL); if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) && !IsCommentLine(lineCurrent, styler)) break; } int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK; // Set up initial loop state int prevComment = 0; if (lineCurrent >= 1) prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler); // Process all characters to end of requested range // or comment that hangs over the end of the range. Cap processing in all cases // to end of document (in case of comment at end). while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevComment)) { // Gather info int lev = indentCurrent; int lineNext = lineCurrent + 1; int indentNext = indentCurrent; if (lineNext <= docLines) { // Information about next line is only available if not at end of document indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); } const int comment = foldComment && IsCommentLine(lineCurrent, styler); const int comment_start = (comment && !prevComment && (lineNext <= docLines) && IsCommentLine(lineNext, styler) && (lev > SC_FOLDLEVELBASE)); const int comment_continue = (comment && prevComment); if (!comment) indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK; if (indentNext & SC_FOLDLEVELWHITEFLAG) indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel; if (comment_start) { // Place fold point at start of a block of comments lev |= SC_FOLDLEVELHEADERFLAG; } else if (comment_continue) { // Add level to rest of lines in the block lev = lev + 1; } // Skip past any blank lines for next indent level info; we skip also // comments (all comments, not just those starting in column 0) // which effectively folds them into surrounding code rather // than screwing up folding. while ((lineNext < docLines) && ((indentNext & SC_FOLDLEVELWHITEFLAG) || (lineNext <= docLines && IsCommentLine(lineNext, styler)))) { lineNext++; indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); } const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK; const int levelBeforeComments = Platform::Maximum(indentCurrentLevel,levelAfterComments); // Now set all the indent levels on the lines we skipped // Do this from end to start. Once we encounter one line // which is indented more than the line after the end of // the comment-block, use the level of the block before int skipLine = lineNext; int skipLevel = levelAfterComments; while (--skipLine > lineCurrent) { int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL); if (foldCompact) { if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments) skipLevel = levelBeforeComments; int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG; styler.SetLevel(skipLine, skipLevel | whiteFlag); } else { if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments && !(skipLineIndent & SC_FOLDLEVELWHITEFLAG) && !IsCommentLine(skipLine, styler)) skipLevel = levelBeforeComments; styler.SetLevel(skipLine, skipLevel); } } // Set fold header on non-comment line if (!comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) lev |= SC_FOLDLEVELHEADERFLAG; } // Keep track of block comment state of previous line prevComment = comment_start || comment_continue; // Set fold level for this line and move to next line styler.SetLevel(lineCurrent, lev); indentCurrent = indentNext; lineCurrent = lineNext; } } static const char *const csWordLists[] = { "Keywords", 0, }; LexerModule lmCoffeeScript(SCLEX_COFFEESCRIPT, ColouriseCoffeeScriptDoc, "coffeescript", FoldCoffeeScriptDoc, csWordLists); |
Added lexers/LexConf.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
// Scintilla source code edit control /** @file LexConf.cxx ** Lexer for Apache Configuration Files. ** ** First working version contributed by Ahmad Zawawi <ahmad.zawawi@gmail.com> on October 28, 2000. ** i created this lexer because i needed something pretty when dealing ** when Apache Configuration files... **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) { int state = SCE_CONF_DEFAULT; char chNext = styler[startPos]; int lengthDoc = startPos + length; // create a buffer large enough to take the largest chunk... char *buffer = new char[length]; int bufferCount = 0; // this assumes that we have 2 keyword list in conf.properties WordList &directives = *keywordLists[0]; WordList ¶ms = *keywordLists[1]; // go through all provided text segment // using the hand-written state machine shown below styler.StartAt(startPos); styler.StartSegment(startPos); for (int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if (styler.IsLeadByte(ch)) { chNext = styler.SafeGetCharAt(i + 2); i++; continue; } switch(state) { case SCE_CONF_DEFAULT: if( ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') { // whitespace is simply ignored here... styler.ColourTo(i,SCE_CONF_DEFAULT); break; } else if( ch == '#' ) { // signals the start of a comment... state = SCE_CONF_COMMENT; styler.ColourTo(i,SCE_CONF_COMMENT); } else if( ch == '.' /*|| ch == '/'*/) { // signals the start of a file... state = SCE_CONF_EXTENSION; styler.ColourTo(i,SCE_CONF_EXTENSION); } else if( ch == '"') { state = SCE_CONF_STRING; styler.ColourTo(i,SCE_CONF_STRING); } else if( isascii(ch) && ispunct(ch) ) { // signals an operator... // no state jump necessary for this // simple case... styler.ColourTo(i,SCE_CONF_OPERATOR); } else if( isascii(ch) && isalpha(ch) ) { // signals the start of an identifier bufferCount = 0; buffer[bufferCount++] = static_cast<char>(tolower(ch)); state = SCE_CONF_IDENTIFIER; } else if( isascii(ch) && isdigit(ch) ) { // signals the start of a number bufferCount = 0; buffer[bufferCount++] = ch; //styler.ColourTo(i,SCE_CONF_NUMBER); state = SCE_CONF_NUMBER; } else { // style it the default style.. styler.ColourTo(i,SCE_CONF_DEFAULT); } break; case SCE_CONF_COMMENT: // if we find a newline here, // we simply go to default state // else continue to work on it... if( ch == '\n' || ch == '\r' ) { state = SCE_CONF_DEFAULT; } else { styler.ColourTo(i,SCE_CONF_COMMENT); } break; case SCE_CONF_EXTENSION: // if we find a non-alphanumeric char, // we simply go to default state // else we're still dealing with an extension... if( (isascii(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '$') || (ch == '/') || (ch == '.') || (ch == '*') ) { styler.ColourTo(i,SCE_CONF_EXTENSION); } else { state = SCE_CONF_DEFAULT; chNext = styler[i--]; } break; case SCE_CONF_STRING: // if we find the end of a string char, we simply go to default state // else we're still dealing with an string... if( (ch == '"' && styler.SafeGetCharAt(i-1)!='\\') || (ch == '\n') || (ch == '\r') ) { state = SCE_CONF_DEFAULT; } styler.ColourTo(i,SCE_CONF_STRING); break; case SCE_CONF_IDENTIFIER: // stay in CONF_IDENTIFIER state until we find a non-alphanumeric if( (isascii(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '/') || (ch == '$') || (ch == '.') || (ch == '*')) { buffer[bufferCount++] = static_cast<char>(tolower(ch)); } else { state = SCE_CONF_DEFAULT; buffer[bufferCount] = '\0'; // check if the buffer contains a keyword, and highlight it if it is a keyword... if(directives.InList(buffer)) { styler.ColourTo(i-1,SCE_CONF_DIRECTIVE ); } else if(params.InList(buffer)) { styler.ColourTo(i-1,SCE_CONF_PARAMETER ); } else if(strchr(buffer,'/') || strchr(buffer,'.')) { styler.ColourTo(i-1,SCE_CONF_EXTENSION); } else { styler.ColourTo(i-1,SCE_CONF_DEFAULT); } // push back the faulty character chNext = styler[i--]; } break; case SCE_CONF_NUMBER: // stay in CONF_NUMBER state until we find a non-numeric if( (isascii(ch) && isdigit(ch)) || ch == '.') { buffer[bufferCount++] = ch; } else { state = SCE_CONF_DEFAULT; buffer[bufferCount] = '\0'; // Colourize here... if( strchr(buffer,'.') ) { // it is an IP address... styler.ColourTo(i-1,SCE_CONF_IP); } else { // normal number styler.ColourTo(i-1,SCE_CONF_NUMBER); } // push back a character chNext = styler[i--]; } break; } } delete []buffer; } static const char * const confWordListDesc[] = { "Directives", "Parameters", 0 }; LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf", 0, confWordListDesc); |
Added lexers/LexCrontab.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
// Scintilla source code edit control /** @file LexCrontab.cxx ** Lexer to use with extended crontab files used by a powerful ** Windows scheduler/event monitor/automation manager nnCron. ** (http://nemtsev.eserv.ru/) **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) { int state = SCE_NNCRONTAB_DEFAULT; char chNext = styler[startPos]; int lengthDoc = startPos + length; // create a buffer large enough to take the largest chunk... char *buffer = new char[length]; int bufferCount = 0; // used when highliting environment variables inside quoted string: bool insideString = false; // this assumes that we have 3 keyword list in conf.properties WordList §ion = *keywordLists[0]; WordList &keyword = *keywordLists[1]; WordList &modifier = *keywordLists[2]; // go through all provided text segment // using the hand-written state machine shown below styler.StartAt(startPos); styler.StartSegment(startPos); for (int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if (styler.IsLeadByte(ch)) { chNext = styler.SafeGetCharAt(i + 2); i++; continue; } switch(state) { case SCE_NNCRONTAB_DEFAULT: if( ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') { // whitespace is simply ignored here... styler.ColourTo(i,SCE_NNCRONTAB_DEFAULT); break; } else if( ch == '#' && styler.SafeGetCharAt(i+1) == '(') { // signals the start of a task... state = SCE_NNCRONTAB_TASK; styler.ColourTo(i,SCE_NNCRONTAB_TASK); } else if( ch == '\\' && (styler.SafeGetCharAt(i+1) == ' ' || styler.SafeGetCharAt(i+1) == '\t')) { // signals the start of an extended comment... state = SCE_NNCRONTAB_COMMENT; styler.ColourTo(i,SCE_NNCRONTAB_COMMENT); } else if( ch == '#' ) { // signals the start of a plain comment... state = SCE_NNCRONTAB_COMMENT; styler.ColourTo(i,SCE_NNCRONTAB_COMMENT); } else if( ch == ')' && styler.SafeGetCharAt(i+1) == '#') { // signals the end of a task... state = SCE_NNCRONTAB_TASK; styler.ColourTo(i,SCE_NNCRONTAB_TASK); } else if( ch == '"') { state = SCE_NNCRONTAB_STRING; styler.ColourTo(i,SCE_NNCRONTAB_STRING); } else if( ch == '%') { // signals environment variables state = SCE_NNCRONTAB_ENVIRONMENT; styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT); } else if( ch == '<' && styler.SafeGetCharAt(i+1) == '%') { // signals environment variables state = SCE_NNCRONTAB_ENVIRONMENT; styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT); } else if( ch == '*' ) { // signals an asterisk // no state jump necessary for this simple case... styler.ColourTo(i,SCE_NNCRONTAB_ASTERISK); } else if( (isascii(ch) && isalpha(ch)) || ch == '<' ) { // signals the start of an identifier bufferCount = 0; buffer[bufferCount++] = ch; state = SCE_NNCRONTAB_IDENTIFIER; } else if( isascii(ch) && isdigit(ch) ) { // signals the start of a number bufferCount = 0; buffer[bufferCount++] = ch; state = SCE_NNCRONTAB_NUMBER; } else { // style it the default style.. styler.ColourTo(i,SCE_NNCRONTAB_DEFAULT); } break; case SCE_NNCRONTAB_COMMENT: // if we find a newline here, // we simply go to default state // else continue to work on it... if( ch == '\n' || ch == '\r' ) { state = SCE_NNCRONTAB_DEFAULT; } else { styler.ColourTo(i,SCE_NNCRONTAB_COMMENT); } break; case SCE_NNCRONTAB_TASK: // if we find a newline here, // we simply go to default state // else continue to work on it... if( ch == '\n' || ch == '\r' ) { state = SCE_NNCRONTAB_DEFAULT; } else { styler.ColourTo(i,SCE_NNCRONTAB_TASK); } break; case SCE_NNCRONTAB_STRING: if( ch == '%' ) { state = SCE_NNCRONTAB_ENVIRONMENT; insideString = true; styler.ColourTo(i-1,SCE_NNCRONTAB_STRING); break; } // if we find the end of a string char, we simply go to default state // else we're still dealing with an string... if( (ch == '"' && styler.SafeGetCharAt(i-1)!='\\') || (ch == '\n') || (ch == '\r') ) { state = SCE_NNCRONTAB_DEFAULT; } styler.ColourTo(i,SCE_NNCRONTAB_STRING); break; case SCE_NNCRONTAB_ENVIRONMENT: // if we find the end of a string char, we simply go to default state // else we're still dealing with an string... if( ch == '%' && insideString ) { state = SCE_NNCRONTAB_STRING; insideString = false; break; } if( (ch == '%' && styler.SafeGetCharAt(i-1)!='\\') || (ch == '\n') || (ch == '\r') || (ch == '>') ) { state = SCE_NNCRONTAB_DEFAULT; styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT); break; } styler.ColourTo(i+1,SCE_NNCRONTAB_ENVIRONMENT); break; case SCE_NNCRONTAB_IDENTIFIER: // stay in CONF_IDENTIFIER state until we find a non-alphanumeric if( (isascii(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '/') || (ch == '$') || (ch == '.') || (ch == '<') || (ch == '>') || (ch == '@') ) { buffer[bufferCount++] = ch; } else { state = SCE_NNCRONTAB_DEFAULT; buffer[bufferCount] = '\0'; // check if the buffer contains a keyword, // and highlight it if it is a keyword... if(section.InList(buffer)) { styler.ColourTo(i,SCE_NNCRONTAB_SECTION ); } else if(keyword.InList(buffer)) { styler.ColourTo(i-1,SCE_NNCRONTAB_KEYWORD ); } // else if(strchr(buffer,'/') || strchr(buffer,'.')) { // styler.ColourTo(i-1,SCE_NNCRONTAB_EXTENSION); // } else if(modifier.InList(buffer)) { styler.ColourTo(i-1,SCE_NNCRONTAB_MODIFIER ); } else { styler.ColourTo(i-1,SCE_NNCRONTAB_DEFAULT); } // push back the faulty character chNext = styler[i--]; } break; case SCE_NNCRONTAB_NUMBER: // stay in CONF_NUMBER state until we find a non-numeric if( isascii(ch) && isdigit(ch) /* || ch == '.' */ ) { buffer[bufferCount++] = ch; } else { state = SCE_NNCRONTAB_DEFAULT; buffer[bufferCount] = '\0'; // Colourize here... (normal number) styler.ColourTo(i-1,SCE_NNCRONTAB_NUMBER); // push back a character chNext = styler[i--]; } break; } } delete []buffer; } static const char * const cronWordListDesc[] = { "Section keywords and Forth words", "nnCrontab keywords", "Modifiers", 0 }; LexerModule lmNncrontab(SCLEX_NNCRONTAB, ColouriseNncrontabDoc, "nncrontab", 0, cronWordListDesc); |
Added lexers/LexCsound.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
// Scintilla source code edit control /** @file LexCsound.cxx ** Lexer for Csound (Orchestra & Score) ** Written by Georg Ritter - <ritterfuture A T gmail D O T com> **/ // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '?'); } static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' || ch == '%' || ch == '@' || ch == '$' || ch == '?'); } static inline bool IsCsoundOperator(char ch) { if (isascii(ch) && isalnum(ch)) return false; // '.' left out as it is used to make up numbers if (ch == '*' || ch == '/' || ch == '-' || ch == '+' || ch == '(' || ch == ')' || ch == '=' || ch == '^' || ch == '[' || ch == ']' || ch == '<' || ch == '&' || ch == '>' || ch == ',' || ch == '|' || ch == '~' || ch == '%' || ch == ':') return true; return false; } static void ColouriseCsoundDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &opcode = *keywordlists[0]; WordList &headerStmt = *keywordlists[1]; WordList &otherKeyword = *keywordlists[2]; // Do not leak onto next line if (initStyle == SCE_CSOUND_STRINGEOL) initStyle = SCE_CSOUND_DEFAULT; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { // Handle line continuation generically. if (sc.ch == '\\') { if (sc.chNext == '\n' || sc.chNext == '\r') { sc.Forward(); if (sc.ch == '\r' && sc.chNext == '\n') { sc.Forward(); } continue; } } // Determine if the current state should terminate. if (sc.state == SCE_CSOUND_OPERATOR) { if (!IsCsoundOperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_CSOUND_DEFAULT); } }else if (sc.state == SCE_CSOUND_NUMBER) { if (!IsAWordChar(sc.ch)) { sc.SetState(SCE_CSOUND_DEFAULT); } } else if (sc.state == SCE_CSOUND_IDENTIFIER) { if (!IsAWordChar(sc.ch) ) { char s[100]; sc.GetCurrent(s, sizeof(s)); if (opcode.InList(s)) { sc.ChangeState(SCE_CSOUND_OPCODE); } else if (headerStmt.InList(s)) { sc.ChangeState(SCE_CSOUND_HEADERSTMT); } else if (otherKeyword.InList(s)) { sc.ChangeState(SCE_CSOUND_USERKEYWORD); } else if (s[0] == 'p') { sc.ChangeState(SCE_CSOUND_PARAM); } else if (s[0] == 'a') { sc.ChangeState(SCE_CSOUND_ARATE_VAR); } else if (s[0] == 'k') { sc.ChangeState(SCE_CSOUND_KRATE_VAR); } else if (s[0] == 'i') { // covers both i-rate variables and i-statements sc.ChangeState(SCE_CSOUND_IRATE_VAR); } else if (s[0] == 'g') { sc.ChangeState(SCE_CSOUND_GLOBAL_VAR); } sc.SetState(SCE_CSOUND_DEFAULT); } } else if (sc.state == SCE_CSOUND_COMMENT ) { if (sc.atLineEnd) { sc.SetState(SCE_CSOUND_DEFAULT); } } else if ((sc.state == SCE_CSOUND_ARATE_VAR) || (sc.state == SCE_CSOUND_KRATE_VAR) || (sc.state == SCE_CSOUND_IRATE_VAR)) { if (!IsAWordChar(sc.ch)) { sc.SetState(SCE_CSOUND_DEFAULT); } } // Determine if a new state should be entered. if (sc.state == SCE_CSOUND_DEFAULT) { if (sc.ch == ';'){ sc.SetState(SCE_CSOUND_COMMENT); } else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) { sc.SetState(SCE_CSOUND_NUMBER); } else if (IsAWordStart(sc.ch)) { sc.SetState(SCE_CSOUND_IDENTIFIER); } else if (IsCsoundOperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_CSOUND_OPERATOR); } else if (sc.ch == 'p') { sc.SetState(SCE_CSOUND_PARAM); } else if (sc.ch == 'a') { sc.SetState(SCE_CSOUND_ARATE_VAR); } else if (sc.ch == 'k') { sc.SetState(SCE_CSOUND_KRATE_VAR); } else if (sc.ch == 'i') { // covers both i-rate variables and i-statements sc.SetState(SCE_CSOUND_IRATE_VAR); } else if (sc.ch == 'g') { sc.SetState(SCE_CSOUND_GLOBAL_VAR); } } } sc.Complete(); } static void FoldCsoundInstruments(unsigned int startPos, int length, int /* initStyle */, WordList *[], Accessor &styler) { unsigned int lengthDoc = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; int stylePrev = 0; int styleNext = styler.StyleAt(startPos); for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if ((stylePrev != SCE_CSOUND_OPCODE) && (style == SCE_CSOUND_OPCODE)) { char s[20]; unsigned int j = 0; while ((j < (sizeof(s) - 1)) && (iswordchar(styler[i + j]))) { s[j] = styler[i + j]; j++; } s[j] = '\0'; if (strcmp(s, "instr") == 0) levelCurrent++; if (strcmp(s, "endin") == 0) levelCurrent--; } if (atEOL) { int lev = levelPrev; if (visibleChars == 0) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; stylePrev = style; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char * const csoundWordListDesc[] = { "Opcodes", "Header Statements", "User keywords", 0 }; LexerModule lmCsound(SCLEX_CSOUND, ColouriseCsoundDoc, "csound", FoldCsoundInstruments, csoundWordListDesc); |
Added lexers/LexD.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 |
/** @file LexD.cxx ** Lexer for D. ** ** Copyright (c) 2006 by Waldemar Augustyn <waldemar@wdmsys.com> ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net> **/ // Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include <string> #include <map> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #include "OptionSet.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif /* Nested comments require keeping the value of the nesting level for every position in the document. But since scintilla always styles line by line, we only need to store one value per line. The non-negative number indicates nesting level at the end of the line. */ // Underscore, letter, digit and universal alphas from C99 Appendix D. static bool IsWordStart(int ch) { return (isascii(ch) && (isalpha(ch) || ch == '_')) || !isascii(ch); } static bool IsWord(int ch) { return (isascii(ch) && (isalnum(ch) || ch == '_')) || !isascii(ch); } static bool IsDoxygen(int ch) { if (isascii(ch) && islower(ch)) return true; if (ch == '$' || ch == '@' || ch == '\\' || ch == '&' || ch == '#' || ch == '<' || ch == '>' || ch == '{' || ch == '}' || ch == '[' || ch == ']') return true; return false; } static bool IsStringSuffix(int ch) { return ch == 'c' || ch == 'w' || ch == 'd'; } static bool IsStreamCommentStyle(int style) { return style == SCE_D_COMMENT || style == SCE_D_COMMENTDOC || style == SCE_D_COMMENTDOCKEYWORD || style == SCE_D_COMMENTDOCKEYWORDERROR; } // An individual named option for use in an OptionSet // Options used for LexerD struct OptionsD { bool fold; bool foldSyntaxBased; bool foldComment; bool foldCommentMultiline; bool foldCommentExplicit; std::string foldExplicitStart; std::string foldExplicitEnd; bool foldExplicitAnywhere; bool foldCompact; int foldAtElseInt; bool foldAtElse; OptionsD() { fold = false; foldSyntaxBased = true; foldComment = false; foldCommentMultiline = true; foldCommentExplicit = true; foldExplicitStart = ""; foldExplicitEnd = ""; foldExplicitAnywhere = false; foldCompact = true; foldAtElseInt = -1; foldAtElse = false; } }; static const char * const dWordLists[] = { "Primary keywords and identifiers", "Secondary keywords and identifiers", "Documentation comment keywords", "Type definitions and aliases", "Keywords 5", "Keywords 6", "Keywords 7", 0, }; struct OptionSetD : public OptionSet<OptionsD> { OptionSetD() { DefineProperty("fold", &OptionsD::fold); DefineProperty("fold.d.syntax.based", &OptionsD::foldSyntaxBased, "Set this property to 0 to disable syntax based folding."); DefineProperty("fold.comment", &OptionsD::foldComment); DefineProperty("fold.d.comment.multiline", &OptionsD::foldCommentMultiline, "Set this property to 0 to disable folding multi-line comments when fold.comment=1."); DefineProperty("fold.d.comment.explicit", &OptionsD::foldCommentExplicit, "Set this property to 0 to disable folding explicit fold points when fold.comment=1."); DefineProperty("fold.d.explicit.start", &OptionsD::foldExplicitStart, "The string to use for explicit fold start points, replacing the standard //{."); DefineProperty("fold.d.explicit.end", &OptionsD::foldExplicitEnd, "The string to use for explicit fold end points, replacing the standard //}."); DefineProperty("fold.d.explicit.anywhere", &OptionsD::foldExplicitAnywhere, "Set this property to 1 to enable explicit fold points anywhere, not just in line comments."); DefineProperty("fold.compact", &OptionsD::foldCompact); DefineProperty("lexer.d.fold.at.else", &OptionsD::foldAtElseInt, "This option enables D folding on a \"} else {\" line of an if statement."); DefineProperty("fold.at.else", &OptionsD::foldAtElse); DefineWordListSets(dWordLists); } }; class LexerD : public ILexer { bool caseSensitive; WordList keywords; WordList keywords2; WordList keywords3; WordList keywords4; WordList keywords5; WordList keywords6; WordList keywords7; OptionsD options; OptionSetD osD; public: LexerD(bool caseSensitive_) : caseSensitive(caseSensitive_) { } virtual ~LexerD() { } void SCI_METHOD Release() { delete this; } int SCI_METHOD Version() const { return lvOriginal; } const char * SCI_METHOD PropertyNames() { return osD.PropertyNames(); } int SCI_METHOD PropertyType(const char *name) { return osD.PropertyType(name); } const char * SCI_METHOD DescribeProperty(const char *name) { return osD.DescribeProperty(name); } int SCI_METHOD PropertySet(const char *key, const char *val); const char * SCI_METHOD DescribeWordListSets() { return osD.DescribeWordListSets(); } int SCI_METHOD WordListSet(int n, const char *wl); void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess); void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess); void * SCI_METHOD PrivateCall(int, void *) { return 0; } static ILexer *LexerFactoryD() { return new LexerD(true); } static ILexer *LexerFactoryDInsensitive() { return new LexerD(false); } }; int SCI_METHOD LexerD::PropertySet(const char *key, const char *val) { if (osD.PropertySet(&options, key, val)) { return 0; } return -1; } int SCI_METHOD LexerD::WordListSet(int n, const char *wl) { WordList *wordListN = 0; switch (n) { case 0: wordListN = &keywords; break; case 1: wordListN = &keywords2; break; case 2: wordListN = &keywords3; break; case 3: wordListN = &keywords4; break; case 4: wordListN = &keywords5; break; case 5: wordListN = &keywords6; break; case 6: wordListN = &keywords7; break; } int firstModification = -1; if (wordListN) { WordList wlNew; wlNew.Set(wl); if (*wordListN != wlNew) { wordListN->Set(wl); firstModification = 0; } } return firstModification; } void SCI_METHOD LexerD::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { LexAccessor styler(pAccess); int styleBeforeDCKeyword = SCE_D_DEFAULT; StyleContext sc(startPos, length, initStyle, styler); int curLine = styler.GetLine(startPos); int curNcLevel = curLine > 0? styler.GetLineState(curLine-1): 0; bool numFloat = false; // Float literals have '+' and '-' signs bool numHex = false; for (; sc.More(); sc.Forward()) { if (sc.atLineStart) { curLine = styler.GetLine(sc.currentPos); styler.SetLineState(curLine, curNcLevel); } // Determine if the current state should terminate. switch (sc.state) { case SCE_D_OPERATOR: sc.SetState(SCE_D_DEFAULT); break; case SCE_D_NUMBER: // We accept almost anything because of hex. and number suffixes if (isascii(sc.ch) && (isalnum(sc.ch) || sc.ch == '_')) { continue; } else if (sc.ch == '.' && sc.chNext != '.' && !numFloat) { // Don't parse 0..2 as number. numFloat=true; continue; } else if ( ( sc.ch == '-' || sc.ch == '+' ) && ( /*sign and*/ ( !numHex && ( sc.chPrev == 'e' || sc.chPrev == 'E' ) ) || /*decimal or*/ ( sc.chPrev == 'p' || sc.chPrev == 'P' ) ) ) { /*hex*/ // Parse exponent sign in float literals: 2e+10 0x2e+10 continue; } else { sc.SetState(SCE_D_DEFAULT); } break; case SCE_D_IDENTIFIER: if (!IsWord(sc.ch)) { char s[1000]; if (caseSensitive) { sc.GetCurrent(s, sizeof(s)); } else { sc.GetCurrentLowered(s, sizeof(s)); } if (keywords.InList(s)) { sc.ChangeState(SCE_D_WORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_D_WORD2); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_D_TYPEDEF); } else if (keywords5.InList(s)) { sc.ChangeState(SCE_D_WORD5); } else if (keywords6.InList(s)) { sc.ChangeState(SCE_D_WORD6); } else if (keywords7.InList(s)) { sc.ChangeState(SCE_D_WORD7); } sc.SetState(SCE_D_DEFAULT); } break; case SCE_D_COMMENT: if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_D_DEFAULT); } break; case SCE_D_COMMENTDOC: if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_D_DEFAULT); } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support // Verify that we have the conditions to mark a comment-doc-keyword if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) { styleBeforeDCKeyword = SCE_D_COMMENTDOC; sc.SetState(SCE_D_COMMENTDOCKEYWORD); } } break; case SCE_D_COMMENTLINE: if (sc.atLineStart) { sc.SetState(SCE_D_DEFAULT); } break; case SCE_D_COMMENTLINEDOC: if (sc.atLineStart) { sc.SetState(SCE_D_DEFAULT); } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support // Verify that we have the conditions to mark a comment-doc-keyword if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) { styleBeforeDCKeyword = SCE_D_COMMENTLINEDOC; sc.SetState(SCE_D_COMMENTDOCKEYWORD); } } break; case SCE_D_COMMENTDOCKEYWORD: if ((styleBeforeDCKeyword == SCE_D_COMMENTDOC) && sc.Match('*', '/')) { sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR); sc.Forward(); sc.ForwardSetState(SCE_D_DEFAULT); } else if (!IsDoxygen(sc.ch)) { char s[100]; if (caseSensitive) { sc.GetCurrent(s, sizeof(s)); } else { sc.GetCurrentLowered(s, sizeof(s)); } if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) { sc.ChangeState(SCE_D_COMMENTDOCKEYWORDERROR); } sc.SetState(styleBeforeDCKeyword); } break; case SCE_D_COMMENTNESTED: if (sc.Match('+', '/')) { if (curNcLevel > 0) curNcLevel -= 1; curLine = styler.GetLine(sc.currentPos); styler.SetLineState(curLine, curNcLevel); sc.Forward(); if (curNcLevel == 0) { sc.ForwardSetState(SCE_D_DEFAULT); } } else if (sc.Match('/','+')) { curNcLevel += 1; curLine = styler.GetLine(sc.currentPos); styler.SetLineState(curLine, curNcLevel); sc.Forward(); } break; case SCE_D_STRING: if (sc.ch == '\\') { if (sc.chNext == '"' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '"') { if(IsStringSuffix(sc.chNext)) sc.Forward(); sc.ForwardSetState(SCE_D_DEFAULT); } break; case SCE_D_CHARACTER: if (sc.atLineEnd) { sc.ChangeState(SCE_D_STRINGEOL); } else if (sc.ch == '\\') { if (sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\'') { // Char has no suffixes sc.ForwardSetState(SCE_D_DEFAULT); } break; case SCE_D_STRINGEOL: if (sc.atLineStart) { sc.SetState(SCE_D_DEFAULT); } break; case SCE_D_STRINGB: if (sc.ch == '`') { if(IsStringSuffix(sc.chNext)) sc.Forward(); sc.ForwardSetState(SCE_D_DEFAULT); } break; case SCE_D_STRINGR: if (sc.ch == '"') { if(IsStringSuffix(sc.chNext)) sc.Forward(); sc.ForwardSetState(SCE_D_DEFAULT); } break; } // Determine if a new state should be entered. if (sc.state == SCE_D_DEFAULT) { if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_D_NUMBER); numFloat = sc.ch == '.'; // Remember hex literal numHex = sc.ch == '0' && ( sc.chNext == 'x' || sc.chNext == 'X' ); } else if ( (sc.ch == 'r' || sc.ch == 'x' || sc.ch == 'q') && sc.chNext == '"' ) { // Limited support for hex and delimited strings: parse as r"" sc.SetState(SCE_D_STRINGR); sc.Forward(); } else if (IsWordStart(sc.ch) || sc.ch == '$') { sc.SetState(SCE_D_IDENTIFIER); } else if (sc.Match('/','+')) { curNcLevel += 1; curLine = styler.GetLine(sc.currentPos); styler.SetLineState(curLine, curNcLevel); sc.SetState(SCE_D_COMMENTNESTED); sc.Forward(); } else if (sc.Match('/', '*')) { if (sc.Match("/**") || sc.Match("/*!")) { // Support of Qt/Doxygen doc. style sc.SetState(SCE_D_COMMENTDOC); } else { sc.SetState(SCE_D_COMMENT); } sc.Forward(); // Eat the * so it isn't used for the end of the comment } else if (sc.Match('/', '/')) { if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!")) // Support of Qt/Doxygen doc. style sc.SetState(SCE_D_COMMENTLINEDOC); else sc.SetState(SCE_D_COMMENTLINE); } else if (sc.ch == '"') { sc.SetState(SCE_D_STRING); } else if (sc.ch == '\'') { sc.SetState(SCE_D_CHARACTER); } else if (sc.ch == '`') { sc.SetState(SCE_D_STRINGB); } else if (isoperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_D_OPERATOR); if (sc.ch == '.' && sc.chNext == '.') sc.Forward(); // Range operator } } } sc.Complete(); } // Store both the current line's fold level and the next lines in the // level store to make it easy to pick up with each increment // and to make it possible to fiddle the current level for "} else {". void SCI_METHOD LexerD::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { if (!options.fold) return; LexAccessor styler(pAccess); unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelMinCurrent = levelCurrent; int levelNext = levelCurrent; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; bool foldAtElse = options.foldAtElseInt >= 0 ? options.foldAtElseInt != 0 : options.foldAtElse; const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty(); for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) { if (!IsStreamCommentStyle(stylePrev)) { levelNext++; } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelNext--; } } if (options.foldComment && options.foldCommentExplicit && ((style == SCE_D_COMMENTLINE) || options.foldExplicitAnywhere)) { if (userDefinedFoldMarkers) { if (styler.Match(i, options.foldExplicitStart.c_str())) { levelNext++; } else if (styler.Match(i, options.foldExplicitEnd.c_str())) { levelNext--; } } else { if ((ch == '/') && (chNext == '/')) { char chNext2 = styler.SafeGetCharAt(i + 2); if (chNext2 == '{') { levelNext++; } else if (chNext2 == '}') { levelNext--; } } } } if (options.foldSyntaxBased && (style == SCE_D_OPERATOR)) { if (ch == '{') { // Measure the minimum before a '{' to allow // folding on "} else {" if (levelMinCurrent > levelNext) { levelMinCurrent = levelNext; } levelNext++; } else if (ch == '}') { levelNext--; } } if (atEOL || (i == endPos-1)) { if (options.foldComment && options.foldCommentMultiline) { // Handle nested comments int nc; nc = styler.GetLineState(lineCurrent); nc -= lineCurrent>0? styler.GetLineState(lineCurrent-1): 0; levelNext += nc; } int levelUse = levelCurrent; if (options.foldSyntaxBased && foldAtElse) { levelUse = levelMinCurrent; } int lev = levelUse | levelNext << 16; if (visibleChars == 0 && options.foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelCurrent = levelNext; levelMinCurrent = levelCurrent; visibleChars = 0; } if (!IsASpace(ch)) visibleChars++; } } LexerModule lmD(SCLEX_D, LexerD::LexerFactoryD, "d", dWordLists); |
Added lexers/LexECL.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 |
// Scintilla source code edit control /** @file LexECL.cxx ** Lexer for ECL. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #ifdef _MSC_VER #pragma warning(disable: 4786) #endif #ifdef __BORLANDC__ // Borland C++ displays warnings in vector header without this #pragma option -w-ccc -w-rch #endif #include <string> #include <vector> #include <map> #include <algorithm> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "PropSetSimple.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #include "OptionSet.h" #define SET_LOWER "abcdefghijklmnopqrstuvwxyz" #define SET_UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ" #define SET_DIGITS "0123456789" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static bool IsSpaceEquiv(int state) { return (state <= SCE_ECL_COMMENTDOC) || // including SCE_ECL_DEFAULT, SCE_ECL_COMMENT, SCE_ECL_COMMENTLINE (state == SCE_ECL_COMMENTLINEDOC) || (state == SCE_ECL_COMMENTDOCKEYWORD) || (state == SCE_ECL_COMMENTDOCKEYWORDERROR); } static void ColouriseEclDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords0 = *keywordlists[0]; WordList &keywords1 = *keywordlists[1]; WordList &keywords2 = *keywordlists[2]; WordList &keywords3 = *keywordlists[3]; //Value Types WordList &keywords4 = *keywordlists[4]; WordList &keywords5 = *keywordlists[5]; WordList &keywords6 = *keywordlists[6]; //Javadoc Tags WordList cplusplus; cplusplus.Set("beginc endc"); bool stylingWithinPreprocessor = false; CharacterSet setOKBeforeRE(CharacterSet::setNone, "(=,"); CharacterSet setDoxygen(CharacterSet::setLower, "$@\\&<>#{}[]"); CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true); CharacterSet setQualified(CharacterSet::setNone, "uUxX"); int chPrevNonWhite = ' '; int visibleChars = 0; bool lastWordWasUUID = false; int styleBeforeDCKeyword = SCE_ECL_DEFAULT; bool continuationLine = false; if (initStyle == SCE_ECL_PREPROCESSOR) { // Set continuationLine if last character of previous line is '\' int lineCurrent = styler.GetLine(startPos); if (lineCurrent > 0) { int chBack = styler.SafeGetCharAt(startPos-1, 0); int chBack2 = styler.SafeGetCharAt(startPos-2, 0); int lineEndChar = '!'; if (chBack2 == '\r' && chBack == '\n') { lineEndChar = styler.SafeGetCharAt(startPos-3, 0); } else if (chBack == '\n' || chBack == '\r') { lineEndChar = chBack2; } continuationLine = lineEndChar == '\\'; } } // look back to set chPrevNonWhite properly for better regex colouring if (startPos > 0) { int back = startPos; while (--back && IsSpaceEquiv(styler.StyleAt(back))) ; if (styler.StyleAt(back) == SCE_ECL_OPERATOR) { chPrevNonWhite = styler.SafeGetCharAt(back); } } StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.atLineStart) { if (sc.state == SCE_ECL_STRING) { // Prevent SCE_ECL_STRINGEOL from leaking back to previous line which // ends with a line continuation by locking in the state upto this position. sc.SetState(SCE_ECL_STRING); } // Reset states to begining of colourise so no surprises // if different sets of lines lexed. visibleChars = 0; lastWordWasUUID = false; } // Handle line continuation generically. if (sc.ch == '\\') { if (sc.chNext == '\n' || sc.chNext == '\r') { sc.Forward(); if (sc.ch == '\r' && sc.chNext == '\n') { sc.Forward(); } continuationLine = true; continue; } } // Determine if the current state should terminate. switch (sc.state) { case SCE_ECL_ADDED: case SCE_ECL_DELETED: case SCE_ECL_CHANGED: case SCE_ECL_MOVED: if (sc.atLineStart) sc.SetState(SCE_ECL_DEFAULT); break; case SCE_ECL_OPERATOR: sc.SetState(SCE_ECL_DEFAULT); break; case SCE_ECL_NUMBER: // We accept almost anything because of hex. and number suffixes if (!setWord.Contains(sc.ch)) { sc.SetState(SCE_ECL_DEFAULT); } break; case SCE_ECL_IDENTIFIER: if (!setWord.Contains(sc.ch) || (sc.ch == '.')) { char s[1000]; sc.GetCurrentLowered(s, sizeof(s)); if (keywords0.InList(s)) { lastWordWasUUID = strcmp(s, "uuid") == 0; sc.ChangeState(SCE_ECL_WORD0); } else if (keywords1.InList(s)) { sc.ChangeState(SCE_ECL_WORD1); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_ECL_WORD2); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_ECL_WORD4); } else if (keywords5.InList(s)) { sc.ChangeState(SCE_ECL_WORD5); } else //Data types are of from KEYWORD## { int i = static_cast<int>(strlen(s)) - 1; while(i >= 0 && (isdigit(s[i]) || s[i] == '_')) --i; char s2[1000]; strncpy(s2, s, i + 1); s2[i + 1] = 0; if (keywords3.InList(s2)) { sc.ChangeState(SCE_ECL_WORD3); } } sc.SetState(SCE_ECL_DEFAULT); } break; case SCE_ECL_PREPROCESSOR: if (sc.atLineStart && !continuationLine) { sc.SetState(SCE_ECL_DEFAULT); } else if (stylingWithinPreprocessor) { if (IsASpace(sc.ch)) { sc.SetState(SCE_ECL_DEFAULT); } } else { if (sc.Match('/', '*') || sc.Match('/', '/')) { sc.SetState(SCE_ECL_DEFAULT); } } break; case SCE_ECL_COMMENT: if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_ECL_DEFAULT); } break; case SCE_ECL_COMMENTDOC: if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_ECL_DEFAULT); } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support // Verify that we have the conditions to mark a comment-doc-keyword if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) { styleBeforeDCKeyword = SCE_ECL_COMMENTDOC; sc.SetState(SCE_ECL_COMMENTDOCKEYWORD); } } break; case SCE_ECL_COMMENTLINE: if (sc.atLineStart) { sc.SetState(SCE_ECL_DEFAULT); } break; case SCE_ECL_COMMENTLINEDOC: if (sc.atLineStart) { sc.SetState(SCE_ECL_DEFAULT); } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support // Verify that we have the conditions to mark a comment-doc-keyword if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) { styleBeforeDCKeyword = SCE_ECL_COMMENTLINEDOC; sc.SetState(SCE_ECL_COMMENTDOCKEYWORD); } } break; case SCE_ECL_COMMENTDOCKEYWORD: if ((styleBeforeDCKeyword == SCE_ECL_COMMENTDOC) && sc.Match('*', '/')) { sc.ChangeState(SCE_ECL_COMMENTDOCKEYWORDERROR); sc.Forward(); sc.ForwardSetState(SCE_ECL_DEFAULT); } else if (!setDoxygen.Contains(sc.ch)) { char s[1000]; sc.GetCurrentLowered(s, sizeof(s)); if (!IsASpace(sc.ch) || !keywords6.InList(s+1)) { sc.ChangeState(SCE_ECL_COMMENTDOCKEYWORDERROR); } sc.SetState(styleBeforeDCKeyword); } break; case SCE_ECL_STRING: if (sc.atLineEnd) { sc.ChangeState(SCE_ECL_STRINGEOL); } else if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_ECL_DEFAULT); } break; case SCE_ECL_CHARACTER: if (sc.atLineEnd) { sc.ChangeState(SCE_ECL_STRINGEOL); } else if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\'') { sc.ForwardSetState(SCE_ECL_DEFAULT); } break; case SCE_ECL_REGEX: if (sc.atLineStart) { sc.SetState(SCE_ECL_DEFAULT); } else if (sc.ch == '/') { sc.Forward(); while ((sc.ch < 0x80) && islower(sc.ch)) sc.Forward(); // gobble regex flags sc.SetState(SCE_ECL_DEFAULT); } else if (sc.ch == '\\') { // Gobble up the quoted character if (sc.chNext == '\\' || sc.chNext == '/') { sc.Forward(); } } break; case SCE_ECL_STRINGEOL: if (sc.atLineStart) { sc.SetState(SCE_ECL_DEFAULT); } break; case SCE_ECL_VERBATIM: if (sc.ch == '\"') { if (sc.chNext == '\"') { sc.Forward(); } else { sc.ForwardSetState(SCE_ECL_DEFAULT); } } break; case SCE_ECL_UUID: if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') { sc.SetState(SCE_ECL_DEFAULT); } break; } // Determine if a new state should be entered. int lineCurrent = styler.GetLine(sc.currentPos); int lineState = styler.GetLineState(lineCurrent); if (sc.state == SCE_ECL_DEFAULT) { if (lineState) { sc.SetState(lineState); } else if (sc.Match('@', '\"')) { sc.SetState(SCE_ECL_VERBATIM); sc.Forward(); } else if (setQualified.Contains(sc.ch) && sc.chNext == '\'') { sc.SetState(SCE_ECL_CHARACTER); sc.Forward(); } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { if (lastWordWasUUID) { sc.SetState(SCE_ECL_UUID); lastWordWasUUID = false; } else { sc.SetState(SCE_ECL_NUMBER); } } else if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) { if (lastWordWasUUID) { sc.SetState(SCE_ECL_UUID); lastWordWasUUID = false; } else { sc.SetState(SCE_ECL_IDENTIFIER); } } else if (sc.Match('/', '*')) { if (sc.Match("/**") || sc.Match("/*!")) { // Support of Qt/Doxygen doc. style sc.SetState(SCE_ECL_COMMENTDOC); } else { sc.SetState(SCE_ECL_COMMENT); } sc.Forward(); // Eat the * so it isn't used for the end of the comment } else if (sc.Match('/', '/')) { if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!")) // Support of Qt/Doxygen doc. style sc.SetState(SCE_ECL_COMMENTLINEDOC); else sc.SetState(SCE_ECL_COMMENTLINE); } else if (sc.ch == '/' && setOKBeforeRE.Contains(chPrevNonWhite)) { sc.SetState(SCE_ECL_REGEX); // JavaScript's RegEx // } else if (sc.ch == '\"') { // sc.SetState(SCE_ECL_STRING); } else if (sc.ch == '\'') { sc.SetState(SCE_ECL_CHARACTER); } else if (sc.ch == '#' && visibleChars == 0) { // Preprocessor commands are alone on their line sc.SetState(SCE_ECL_PREPROCESSOR); // Skip whitespace between # and preprocessor word do { sc.Forward(); } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More()); if (sc.atLineEnd) { sc.SetState(SCE_ECL_DEFAULT); } } else if (isoperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_ECL_OPERATOR); } } if (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) { chPrevNonWhite = sc.ch; visibleChars++; } continuationLine = false; } sc.Complete(); } static bool IsStreamCommentStyle(int style) { return style == SCE_ECL_COMMENT || style == SCE_ECL_COMMENTDOC || style == SCE_ECL_COMMENTDOCKEYWORD || style == SCE_ECL_COMMENTDOCKEYWORDERROR; } bool MatchNoCase(Accessor & styler, unsigned int & pos, const char *s) { int i=0; for (; *s; i++) { char compare_char = tolower(*s); char styler_char = tolower(styler.SafeGetCharAt(pos+i)); if (compare_char != styler_char) return false; s++; } pos+=i-1; return true; } // Store both the current line's fold level and the next lines in the // level store to make it easy to pick up with each increment // and to make it possible to fiddle the current level for "} else {". static void FoldEclDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = true; bool foldPreprocessor = true; bool foldCompact = true; bool foldAtElse = true; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelMinCurrent = levelCurrent; int levelNext = levelCurrent; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment && IsStreamCommentStyle(style)) { if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_ECL_COMMENTLINEDOC)) { levelNext++; } else if (!IsStreamCommentStyle(styleNext) && (styleNext != SCE_ECL_COMMENTLINEDOC) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelNext--; } } if (foldComment && (style == SCE_ECL_COMMENTLINE)) { if ((ch == '/') && (chNext == '/')) { char chNext2 = styler.SafeGetCharAt(i + 2); if (chNext2 == '{') { levelNext++; } else if (chNext2 == '}') { levelNext--; } } } if (foldPreprocessor && (style == SCE_ECL_PREPROCESSOR)) { if (ch == '#') { unsigned int j = i + 1; while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { j++; } if (MatchNoCase(styler, j, "region") || MatchNoCase(styler, j, "if")) { levelNext++; } else if (MatchNoCase(styler, j, "endregion") || MatchNoCase(styler, j, "end")) { levelNext--; } } } if (style == SCE_ECL_OPERATOR) { if (ch == '{') { // Measure the minimum before a '{' to allow // folding on "} else {" if (levelMinCurrent > levelNext) { levelMinCurrent = levelNext; } levelNext++; } else if (ch == '}') { levelNext--; } } if (style == SCE_ECL_WORD2) { if (MatchNoCase(styler, i, "record") || MatchNoCase(styler, i, "transform") || MatchNoCase(styler, i, "type") || MatchNoCase(styler, i, "function") || MatchNoCase(styler, i, "module") || MatchNoCase(styler, i, "service") || MatchNoCase(styler, i, "interface") || MatchNoCase(styler, i, "ifblock") || MatchNoCase(styler, i, "macro") || MatchNoCase(styler, i, "beginc++")) { levelNext++; } else if (MatchNoCase(styler, i, "endmacro") || MatchNoCase(styler, i, "endc++") || MatchNoCase(styler, i, "end")) { levelNext--; } } if (atEOL || (i == endPos-1)) { int levelUse = levelCurrent; if (foldAtElse) { levelUse = levelMinCurrent; } int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelCurrent = levelNext; levelMinCurrent = levelCurrent; if (atEOL && (i == static_cast<unsigned int>(styler.Length()-1))) { // There is an empty line at end of file so give it same level and empty styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG); } visibleChars = 0; } if (!IsASpace(ch)) visibleChars++; } } static const char * const EclWordListDesc[] = { "Keywords", 0 }; LexerModule lmECL( SCLEX_ECL, ColouriseEclDoc, "ecl", FoldEclDoc, EclWordListDesc); |
Added lexers/LexEScript.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
// Scintilla source code edit control /** @file LexESCRIPT.cxx ** Lexer for ESCRIPT **/ // Copyright 2003 by Patrizio Bekerle (patrizio@bekerle.com) #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_'); } static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_'); } static void ColouriseESCRIPTDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; // Do not leak onto next line /*if (initStyle == SCE_ESCRIPT_STRINGEOL) initStyle = SCE_ESCRIPT_DEFAULT;*/ StyleContext sc(startPos, length, initStyle, styler); bool caseSensitive = styler.GetPropertyInt("escript.case.sensitive", 0) != 0; for (; sc.More(); sc.Forward()) { /*if (sc.atLineStart && (sc.state == SCE_ESCRIPT_STRING)) { // Prevent SCE_ESCRIPT_STRINGEOL from leaking back to previous line sc.SetState(SCE_ESCRIPT_STRING); }*/ // Handle line continuation generically. if (sc.ch == '\\') { if (sc.chNext == '\n' || sc.chNext == '\r') { sc.Forward(); if (sc.ch == '\r' && sc.chNext == '\n') { sc.Forward(); } continue; } } // Determine if the current state should terminate. if (sc.state == SCE_ESCRIPT_OPERATOR || sc.state == SCE_ESCRIPT_BRACE) { sc.SetState(SCE_ESCRIPT_DEFAULT); } else if (sc.state == SCE_ESCRIPT_NUMBER) { if (!IsADigit(sc.ch) || sc.ch != '.') { sc.SetState(SCE_ESCRIPT_DEFAULT); } } else if (sc.state == SCE_ESCRIPT_IDENTIFIER) { if (!IsAWordChar(sc.ch) || (sc.ch == '.')) { char s[100]; if (caseSensitive) { sc.GetCurrent(s, sizeof(s)); } else { sc.GetCurrentLowered(s, sizeof(s)); } // sc.GetCurrentLowered(s, sizeof(s)); if (keywords.InList(s)) { sc.ChangeState(SCE_ESCRIPT_WORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_ESCRIPT_WORD2); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_ESCRIPT_WORD3); // sc.state = SCE_ESCRIPT_IDENTIFIER; } sc.SetState(SCE_ESCRIPT_DEFAULT); } } else if (sc.state == SCE_ESCRIPT_COMMENT) { if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_ESCRIPT_DEFAULT); } } else if (sc.state == SCE_ESCRIPT_COMMENTDOC) { if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_ESCRIPT_DEFAULT); } } else if (sc.state == SCE_ESCRIPT_COMMENTLINE) { if (sc.atLineEnd) { sc.SetState(SCE_ESCRIPT_DEFAULT); } } else if (sc.state == SCE_ESCRIPT_STRING) { if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_ESCRIPT_DEFAULT); } } // Determine if a new state should be entered. if (sc.state == SCE_ESCRIPT_DEFAULT) { if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_ESCRIPT_NUMBER); } else if (IsAWordStart(sc.ch) || (sc.ch == '#')) { sc.SetState(SCE_ESCRIPT_IDENTIFIER); } else if (sc.Match('/', '*')) { sc.SetState(SCE_ESCRIPT_COMMENT); sc.Forward(); // Eat the * so it isn't used for the end of the comment } else if (sc.Match('/', '/')) { sc.SetState(SCE_ESCRIPT_COMMENTLINE); } else if (sc.ch == '\"') { sc.SetState(SCE_ESCRIPT_STRING); //} else if (isoperator(static_cast<char>(sc.ch))) { } else if (sc.ch == '+' || sc.ch == '-' || sc.ch == '*' || sc.ch == '/' || sc.ch == '=' || sc.ch == '<' || sc.ch == '>' || sc.ch == '&' || sc.ch == '|' || sc.ch == '!' || sc.ch == '?' || sc.ch == ':') { sc.SetState(SCE_ESCRIPT_OPERATOR); } else if (sc.ch == '{' || sc.ch == '}') { sc.SetState(SCE_ESCRIPT_BRACE); } } } sc.Complete(); } static int classifyFoldPointESCRIPT(const char* s, const char* prevWord) { int lev = 0; if (strcmp(prevWord, "end") == 0) return lev; if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0) return -1; if (strcmp(s, "for") == 0 || strcmp(s, "foreach") == 0 || strcmp(s, "program") == 0 || strcmp(s, "function") == 0 || strcmp(s, "while") == 0 || strcmp(s, "case") == 0 || strcmp(s, "if") == 0 ) { lev = 1; } else if ( strcmp(s, "endfor") == 0 || strcmp(s, "endforeach") == 0 || strcmp(s, "endprogram") == 0 || strcmp(s, "endfunction") == 0 || strcmp(s, "endwhile") == 0 || strcmp(s, "endcase") == 0 || strcmp(s, "endif") == 0 ) { lev = -1; } return lev; } static bool IsStreamCommentStyle(int style) { return style == SCE_ESCRIPT_COMMENT || style == SCE_ESCRIPT_COMMENTDOC || style == SCE_ESCRIPT_COMMENTLINE; } static void FoldESCRIPTDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { //~ bool foldComment = styler.GetPropertyInt("fold.comment") != 0; // Do not know how to fold the comment at the moment. bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldComment = true; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; int lastStart = 0; char prevWord[32] = ""; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment && IsStreamCommentStyle(style)) { if (!IsStreamCommentStyle(stylePrev)) { levelCurrent++; } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelCurrent--; } } if (foldComment && (style == SCE_ESCRIPT_COMMENTLINE)) { if ((ch == '/') && (chNext == '/')) { char chNext2 = styler.SafeGetCharAt(i + 2); if (chNext2 == '{') { levelCurrent++; } else if (chNext2 == '}') { levelCurrent--; } } } if (stylePrev == SCE_ESCRIPT_DEFAULT && style == SCE_ESCRIPT_WORD3) { // Store last word start point. lastStart = i; } if (style == SCE_ESCRIPT_WORD3) { if(iswordchar(ch) && !iswordchar(chNext)) { char s[32]; unsigned int j; for(j = 0; ( j < 31 ) && ( j < i-lastStart+1 ); j++) { s[j] = static_cast<char>(tolower(styler[lastStart + j])); } s[j] = '\0'; levelCurrent += classifyFoldPointESCRIPT(s, prevWord); strcpy(prevWord, s); } } if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; strcpy(prevWord, ""); } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char * const ESCRIPTWordLists[] = { "Primary keywords and identifiers", "Intrinsic functions", "Extended and user defined functions", 0, }; LexerModule lmESCRIPT(SCLEX_ESCRIPT, ColouriseESCRIPTDoc, "escript", FoldESCRIPTDoc, ESCRIPTWordLists); |
Added lexers/LexEiffel.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
// Scintilla source code edit control /** @file LexEiffel.cxx ** Lexer for Eiffel. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool isEiffelOperator(unsigned int ch) { // '.' left out as it is used to make up numbers return ch == '*' || ch == '/' || ch == '\\' || ch == '-' || ch == '+' || ch == '(' || ch == ')' || ch == '=' || ch == '{' || ch == '}' || ch == '~' || ch == '[' || ch == ']' || ch == ';' || ch == '<' || ch == '>' || ch == ',' || ch == '.' || ch == '^' || ch == '%' || ch == ':' || ch == '!' || ch == '@' || ch == '?'; } static inline bool IsAWordChar(unsigned int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_'); } static inline bool IsAWordStart(unsigned int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_'); } static void ColouriseEiffelDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.state == SCE_EIFFEL_STRINGEOL) { if (sc.ch != '\r' && sc.ch != '\n') { sc.SetState(SCE_EIFFEL_DEFAULT); } } else if (sc.state == SCE_EIFFEL_OPERATOR) { sc.SetState(SCE_EIFFEL_DEFAULT); } else if (sc.state == SCE_EIFFEL_WORD) { if (!IsAWordChar(sc.ch)) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (!keywords.InList(s)) { sc.ChangeState(SCE_EIFFEL_IDENTIFIER); } sc.SetState(SCE_EIFFEL_DEFAULT); } } else if (sc.state == SCE_EIFFEL_NUMBER) { if (!IsAWordChar(sc.ch)) { sc.SetState(SCE_EIFFEL_DEFAULT); } } else if (sc.state == SCE_EIFFEL_COMMENTLINE) { if (sc.ch == '\r' || sc.ch == '\n') { sc.SetState(SCE_EIFFEL_DEFAULT); } } else if (sc.state == SCE_EIFFEL_STRING) { if (sc.ch == '%') { sc.Forward(); } else if (sc.ch == '\"') { sc.Forward(); sc.SetState(SCE_EIFFEL_DEFAULT); } } else if (sc.state == SCE_EIFFEL_CHARACTER) { if (sc.ch == '\r' || sc.ch == '\n') { sc.SetState(SCE_EIFFEL_STRINGEOL); } else if (sc.ch == '%') { sc.Forward(); } else if (sc.ch == '\'') { sc.Forward(); sc.SetState(SCE_EIFFEL_DEFAULT); } } if (sc.state == SCE_EIFFEL_DEFAULT) { if (sc.ch == '-' && sc.chNext == '-') { sc.SetState(SCE_EIFFEL_COMMENTLINE); } else if (sc.ch == '\"') { sc.SetState(SCE_EIFFEL_STRING); } else if (sc.ch == '\'') { sc.SetState(SCE_EIFFEL_CHARACTER); } else if (IsADigit(sc.ch) || (sc.ch == '.')) { sc.SetState(SCE_EIFFEL_NUMBER); } else if (IsAWordStart(sc.ch)) { sc.SetState(SCE_EIFFEL_WORD); } else if (isEiffelOperator(sc.ch)) { sc.SetState(SCE_EIFFEL_OPERATOR); } } } sc.Complete(); } static bool IsEiffelComment(Accessor &styler, int pos, int len) { return len>1 && styler[pos]=='-' && styler[pos+1]=='-'; } static void FoldEiffelDocIndent(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { int lengthDoc = startPos + length; // Backtrack to previous line in case need to fix its fold status int lineCurrent = styler.GetLine(startPos); if (startPos > 0) { if (lineCurrent > 0) { lineCurrent--; startPos = styler.LineStart(lineCurrent); } } int spaceFlags = 0; int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsEiffelComment); char chNext = styler[startPos]; for (int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) { int lev = indentCurrent; int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsEiffelComment); if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { // Only non whitespace lines can be headers if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) { lev |= SC_FOLDLEVELHEADERFLAG; } else if (indentNext & SC_FOLDLEVELWHITEFLAG) { // Line after is blank so check the next - maybe should continue further? int spaceFlags2 = 0; int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsEiffelComment); if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) { lev |= SC_FOLDLEVELHEADERFLAG; } } } indentCurrent = indentNext; styler.SetLevel(lineCurrent, lev); lineCurrent++; } } } static void FoldEiffelDocKeyWords(unsigned int startPos, int length, int /* initStyle */, WordList *[], Accessor &styler) { unsigned int lengthDoc = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; int stylePrev = 0; int styleNext = styler.StyleAt(startPos); // lastDeferred should be determined by looking back to last keyword in case // the "deferred" is on a line before "class" bool lastDeferred = false; for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if ((stylePrev != SCE_EIFFEL_WORD) && (style == SCE_EIFFEL_WORD)) { char s[20]; unsigned int j = 0; while ((j < (sizeof(s) - 1)) && (iswordchar(styler[i + j]))) { s[j] = styler[i + j]; j++; } s[j] = '\0'; if ( (strcmp(s, "check") == 0) || (strcmp(s, "debug") == 0) || (strcmp(s, "deferred") == 0) || (strcmp(s, "do") == 0) || (strcmp(s, "from") == 0) || (strcmp(s, "if") == 0) || (strcmp(s, "inspect") == 0) || (strcmp(s, "once") == 0) ) levelCurrent++; if (!lastDeferred && (strcmp(s, "class") == 0)) levelCurrent++; if (strcmp(s, "end") == 0) levelCurrent--; lastDeferred = strcmp(s, "deferred") == 0; } if (atEOL) { int lev = levelPrev; if (visibleChars == 0) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; stylePrev = style; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char * const eiffelWordListDesc[] = { "Keywords", 0 }; LexerModule lmEiffel(SCLEX_EIFFEL, ColouriseEiffelDoc, "eiffel", FoldEiffelDocIndent, eiffelWordListDesc); LexerModule lmEiffelkw(SCLEX_EIFFELKW, ColouriseEiffelDoc, "eiffelkw", FoldEiffelDocKeyWords, eiffelWordListDesc); |
Added lexers/LexErlang.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 |
// Scintilla source code edit control // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. /** @file LexErlang.cxx ** Lexer for Erlang. ** Enhanced by Etienne 'Lenain' Girondel (lenaing@gmail.com) ** Originally wrote by Peter-Henry Mander, ** based on Matlab lexer by Jos Fonseca. **/ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static int is_radix(int radix, int ch) { int digit; if (36 < radix || 2 > radix) return 0; if (isdigit(ch)) { digit = ch - '0'; } else if (isalnum(ch)) { digit = toupper(ch) - 'A' + 10; } else { return 0; } return (digit < radix); } typedef enum { STATE_NULL, COMMENT, COMMENT_FUNCTION, COMMENT_MODULE, COMMENT_DOC, COMMENT_DOC_MACRO, ATOM_UNQUOTED, ATOM_QUOTED, NODE_NAME_UNQUOTED, NODE_NAME_QUOTED, MACRO_START, MACRO_UNQUOTED, MACRO_QUOTED, RECORD_START, RECORD_UNQUOTED, RECORD_QUOTED, NUMERAL_START, NUMERAL_BASE_VALUE, NUMERAL_FLOAT, NUMERAL_EXPONENT, PREPROCESSOR } atom_parse_state_t; static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (ch != ' ') && (isalnum(ch) || ch == '_'); } static void ColouriseErlangDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { StyleContext sc(startPos, length, initStyle, styler); WordList &reservedWords = *keywordlists[0]; WordList &erlangBIFs = *keywordlists[1]; WordList &erlangPreproc = *keywordlists[2]; WordList &erlangModulesAtt = *keywordlists[3]; WordList &erlangDoc = *keywordlists[4]; WordList &erlangDocMacro = *keywordlists[5]; int radix_digits = 0; int exponent_digits = 0; atom_parse_state_t parse_state = STATE_NULL; atom_parse_state_t old_parse_state = STATE_NULL; bool to_late_to_comment = false; char cur[100]; int old_style = SCE_ERLANG_DEFAULT; styler.StartAt(startPos); for (; sc.More(); sc.Forward()) { int style = SCE_ERLANG_DEFAULT; if (STATE_NULL != parse_state) { switch (parse_state) { case STATE_NULL : sc.SetState(SCE_ERLANG_DEFAULT); break; /* COMMENTS ------------------------------------------------------*/ case COMMENT : { if (sc.ch != '%') { to_late_to_comment = true; } else if (!to_late_to_comment && sc.ch == '%') { // Switch to comment level 2 (Function) sc.ChangeState(SCE_ERLANG_COMMENT_FUNCTION); old_style = SCE_ERLANG_COMMENT_FUNCTION; parse_state = COMMENT_FUNCTION; sc.Forward(); } } // V--- Falling through! case COMMENT_FUNCTION : { if (sc.ch != '%') { to_late_to_comment = true; } else if (!to_late_to_comment && sc.ch == '%') { // Switch to comment level 3 (Module) sc.ChangeState(SCE_ERLANG_COMMENT_MODULE); old_style = SCE_ERLANG_COMMENT_MODULE; parse_state = COMMENT_MODULE; sc.Forward(); } } // V--- Falling through! case COMMENT_MODULE : { if (parse_state != COMMENT) { // Search for comment documentation if (sc.chNext == '@') { old_parse_state = parse_state; parse_state = ('{' == sc.ch) ? COMMENT_DOC_MACRO : COMMENT_DOC; sc.ForwardSetState(sc.state); } } // All comments types fall here. if (sc.atLineEnd) { to_late_to_comment = false; sc.SetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } } break; case COMMENT_DOC : // V--- Falling through! case COMMENT_DOC_MACRO : { if (!isalnum(sc.ch)) { // Try to match documentation comment sc.GetCurrent(cur, sizeof(cur)); if (parse_state == COMMENT_DOC_MACRO && erlangDocMacro.InList(cur)) { sc.ChangeState(SCE_ERLANG_COMMENT_DOC_MACRO); while (sc.ch != '}' && !sc.atLineEnd) sc.Forward(); } else if (erlangDoc.InList(cur)) { sc.ChangeState(SCE_ERLANG_COMMENT_DOC); } else { sc.ChangeState(old_style); } // Switch back to old state sc.SetState(old_style); parse_state = old_parse_state; } if (sc.atLineEnd) { to_late_to_comment = false; sc.ChangeState(old_style); sc.SetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } } break; /* -------------------------------------------------------------- */ /* Atoms ---------------------------------------------------------*/ case ATOM_UNQUOTED : { if ('@' == sc.ch){ parse_state = NODE_NAME_UNQUOTED; } else if (sc.ch == ':') { // Searching for module name if (sc.chNext == ' ') { // error sc.ChangeState(SCE_ERLANG_UNKNOWN); parse_state = STATE_NULL; } else { sc.Forward(); if (isalnum(sc.ch)) { sc.GetCurrent(cur, sizeof(cur)); sc.ChangeState(SCE_ERLANG_MODULES); sc.SetState(SCE_ERLANG_MODULES); } } } else if (!IsAWordChar(sc.ch)) { sc.GetCurrent(cur, sizeof(cur)); if (reservedWords.InList(cur)) { style = SCE_ERLANG_KEYWORD; } else if (erlangBIFs.InList(cur) && strcmp(cur,"erlang:")){ style = SCE_ERLANG_BIFS; } else if (sc.ch == '(' || '/' == sc.ch){ style = SCE_ERLANG_FUNCTION_NAME; } else { style = SCE_ERLANG_ATOM; } sc.ChangeState(style); sc.SetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } } break; case ATOM_QUOTED : { if ( '@' == sc.ch ){ parse_state = NODE_NAME_QUOTED; } else if ('\'' == sc.ch && '\\' != sc.chPrev) { sc.ChangeState(SCE_ERLANG_ATOM); sc.ForwardSetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } } break; /* -------------------------------------------------------------- */ /* Node names ----------------------------------------------------*/ case NODE_NAME_UNQUOTED : { if ('@' == sc.ch) { sc.SetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } else if (!IsAWordChar(sc.ch)) { sc.ChangeState(SCE_ERLANG_NODE_NAME); sc.SetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } } break; case NODE_NAME_QUOTED : { if ('@' == sc.ch) { sc.SetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } else if ('\'' == sc.ch && '\\' != sc.chPrev) { sc.ChangeState(SCE_ERLANG_NODE_NAME_QUOTED); sc.ForwardSetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } } break; /* -------------------------------------------------------------- */ /* Records -------------------------------------------------------*/ case RECORD_START : { if ('\'' == sc.ch) { parse_state = RECORD_QUOTED; } else if (isalpha(sc.ch) && islower(sc.ch)) { parse_state = RECORD_UNQUOTED; } else { // error sc.SetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } } break; case RECORD_UNQUOTED : { if (!IsAWordChar(sc.ch)) { sc.ChangeState(SCE_ERLANG_RECORD); sc.SetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } } break; case RECORD_QUOTED : { if ('\'' == sc.ch && '\\' != sc.chPrev) { sc.ChangeState(SCE_ERLANG_RECORD_QUOTED); sc.ForwardSetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } } break; /* -------------------------------------------------------------- */ /* Macros --------------------------------------------------------*/ case MACRO_START : { if ('\'' == sc.ch) { parse_state = MACRO_QUOTED; } else if (isalpha(sc.ch)) { parse_state = MACRO_UNQUOTED; } else { // error sc.SetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } } break; case MACRO_UNQUOTED : { if (!IsAWordChar(sc.ch)) { sc.ChangeState(SCE_ERLANG_MACRO); sc.SetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } } break; case MACRO_QUOTED : { if ('\'' == sc.ch && '\\' != sc.chPrev) { sc.ChangeState(SCE_ERLANG_MACRO_QUOTED); sc.ForwardSetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } } break; /* -------------------------------------------------------------- */ /* Numerics ------------------------------------------------------*/ /* Simple integer */ case NUMERAL_START : { if (isdigit(sc.ch)) { radix_digits *= 10; radix_digits += sc.ch - '0'; // Assuming ASCII here! } else if ('#' == sc.ch) { if (2 > radix_digits || 36 < radix_digits) { sc.SetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } else { parse_state = NUMERAL_BASE_VALUE; } } else if ('.' == sc.ch && isdigit(sc.chNext)) { radix_digits = 0; parse_state = NUMERAL_FLOAT; } else if ('e' == sc.ch || 'E' == sc.ch) { exponent_digits = 0; parse_state = NUMERAL_EXPONENT; } else { radix_digits = 0; sc.ChangeState(SCE_ERLANG_NUMBER); sc.SetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } } break; /* Integer in other base than 10 (x#yyy) */ case NUMERAL_BASE_VALUE : { if (!is_radix(radix_digits,sc.ch)) { radix_digits = 0; if (!isalnum(sc.ch)) sc.ChangeState(SCE_ERLANG_NUMBER); sc.SetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } } break; /* Float (x.yyy) */ case NUMERAL_FLOAT : { if ('e' == sc.ch || 'E' == sc.ch) { exponent_digits = 0; parse_state = NUMERAL_EXPONENT; } else if (!isdigit(sc.ch)) { sc.ChangeState(SCE_ERLANG_NUMBER); sc.SetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } } break; /* Exponent, either integer or float (xEyy, x.yyEzzz) */ case NUMERAL_EXPONENT : { if (('-' == sc.ch || '+' == sc.ch) && (isdigit(sc.chNext))) { sc.Forward(); } else if (!isdigit(sc.ch)) { if (0 < exponent_digits) sc.ChangeState(SCE_ERLANG_NUMBER); sc.SetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } else { ++exponent_digits; } } break; /* -------------------------------------------------------------- */ /* Preprocessor --------------------------------------------------*/ case PREPROCESSOR : { if (!IsAWordChar(sc.ch)) { sc.GetCurrent(cur, sizeof(cur)); if (erlangPreproc.InList(cur)) { style = SCE_ERLANG_PREPROC; } else if (erlangModulesAtt.InList(cur)) { style = SCE_ERLANG_MODULES_ATT; } sc.ChangeState(style); sc.SetState(SCE_ERLANG_DEFAULT); parse_state = STATE_NULL; } } break; } } /* End of : STATE_NULL != parse_state */ else { switch (sc.state) { case SCE_ERLANG_VARIABLE : { if (!IsAWordChar(sc.ch)) sc.SetState(SCE_ERLANG_DEFAULT); } break; case SCE_ERLANG_STRING : { if (sc.ch == '\"' && sc.chPrev != '\\') sc.ForwardSetState(SCE_ERLANG_DEFAULT); } break; case SCE_ERLANG_COMMENT : { if (sc.atLineEnd) sc.SetState(SCE_ERLANG_DEFAULT); } break; case SCE_ERLANG_CHARACTER : { if (sc.chPrev == '\\') { sc.ForwardSetState(SCE_ERLANG_DEFAULT); } else if (sc.ch != '\\') { sc.ForwardSetState(SCE_ERLANG_DEFAULT); } } break; case SCE_ERLANG_OPERATOR : { if (sc.chPrev == '.') { if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') { sc.ForwardSetState(SCE_ERLANG_DEFAULT); } else if (sc.ch == '\'') { sc.ForwardSetState(SCE_ERLANG_DEFAULT); } else { sc.SetState(SCE_ERLANG_DEFAULT); } } else { sc.SetState(SCE_ERLANG_DEFAULT); } } break; } } if (sc.state == SCE_ERLANG_DEFAULT) { bool no_new_state = false; switch (sc.ch) { case '\"' : sc.SetState(SCE_ERLANG_STRING); break; case '$' : sc.SetState(SCE_ERLANG_CHARACTER); break; case '%' : { parse_state = COMMENT; sc.SetState(SCE_ERLANG_COMMENT); } break; case '#' : { parse_state = RECORD_START; sc.SetState(SCE_ERLANG_UNKNOWN); } break; case '?' : { parse_state = MACRO_START; sc.SetState(SCE_ERLANG_UNKNOWN); } break; case '\'' : { parse_state = ATOM_QUOTED; sc.SetState(SCE_ERLANG_UNKNOWN); } break; case '+' : case '-' : { if (IsADigit(sc.chNext)) { parse_state = NUMERAL_START; radix_digits = 0; sc.SetState(SCE_ERLANG_UNKNOWN); } else if (sc.ch != '+') { parse_state = PREPROCESSOR; sc.SetState(SCE_ERLANG_UNKNOWN); } } break; default : no_new_state = true; } if (no_new_state) { if (isdigit(sc.ch)) { parse_state = NUMERAL_START; radix_digits = sc.ch - '0'; sc.SetState(SCE_ERLANG_UNKNOWN); } else if (isupper(sc.ch) || '_' == sc.ch) { sc.SetState(SCE_ERLANG_VARIABLE); } else if (isalpha(sc.ch)) { parse_state = ATOM_UNQUOTED; sc.SetState(SCE_ERLANG_UNKNOWN); } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '\\') { sc.SetState(SCE_ERLANG_OPERATOR); } } } } sc.Complete(); } static int ClassifyErlangFoldPoint( Accessor &styler, int styleNext, int keyword_start ) { int lev = 0; if (styler.Match(keyword_start,"case") || ( styler.Match(keyword_start,"fun") && (SCE_ERLANG_FUNCTION_NAME != styleNext) ) || styler.Match(keyword_start,"if") || styler.Match(keyword_start,"query") || styler.Match(keyword_start,"receive") ) { ++lev; } else if (styler.Match(keyword_start,"end")) { --lev; } return lev; } static void FoldErlangDoc( unsigned int startPos, int length, int initStyle, WordList** /*keywordlists*/, Accessor &styler ) { unsigned int endPos = startPos + length; int currentLine = styler.GetLine(startPos); int lev; int previousLevel = styler.LevelAt(currentLine) & SC_FOLDLEVELNUMBERMASK; int currentLevel = previousLevel; int styleNext = styler.StyleAt(startPos); int style = initStyle; int stylePrev; int keyword_start = 0; char ch; char chNext = styler.SafeGetCharAt(startPos); bool atEOL; for (unsigned int i = startPos; i < endPos; i++) { ch = chNext; chNext = styler.SafeGetCharAt(i + 1); // Get styles stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); atEOL = ((ch == '\r') && (chNext != '\n')) || (ch == '\n'); if (stylePrev != SCE_ERLANG_KEYWORD && style == SCE_ERLANG_KEYWORD) { keyword_start = i; } // Fold on keywords if (stylePrev == SCE_ERLANG_KEYWORD && style != SCE_ERLANG_KEYWORD && style != SCE_ERLANG_ATOM ) { currentLevel += ClassifyErlangFoldPoint(styler, styleNext, keyword_start); } // Fold on comments if (style == SCE_ERLANG_COMMENT || style == SCE_ERLANG_COMMENT_MODULE || style == SCE_ERLANG_COMMENT_FUNCTION) { if (ch == '%' && chNext == '{') { currentLevel++; } else if (ch == '%' && chNext == '}') { currentLevel--; } } // Fold on braces if (style == SCE_ERLANG_OPERATOR) { if (ch == '{' || ch == '(' || ch == '[') { currentLevel++; } else if (ch == '}' || ch == ')' || ch == ']') { currentLevel--; } } if (atEOL) { lev = previousLevel; if (currentLevel > previousLevel) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(currentLine)) styler.SetLevel(currentLine, lev); currentLine++; previousLevel = currentLevel; } } // Fill in the real level of the next line, keeping the current flags as they will be filled in later styler.SetLevel(currentLine, previousLevel | (styler.LevelAt(currentLine) & ~SC_FOLDLEVELNUMBERMASK)); } static const char * const erlangWordListDesc[] = { "Erlang Reserved words", "Erlang BIFs", "Erlang Preprocessor", "Erlang Module Attributes", "Erlang Documentation", "Erlang Documentation Macro", 0 }; LexerModule lmErlang( SCLEX_ERLANG, ColouriseErlangDoc, "erlang", FoldErlangDoc, erlangWordListDesc); |
Added lexers/LexFlagship.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 |
// Scintilla source code edit control /** @file LexFlagShip.cxx ** Lexer for Harbour and FlagShip. ** (Syntactically compatible to other xBase dialects, like Clipper, dBase, Clip, FoxPro etc.) **/ // Copyright 2005 by Randy Butler // Copyright 2010 by Xavi <jarabal/at/gmail.com> (Harbour) // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // Extended to accept accented characters static inline bool IsAWordChar(int ch) { return ch >= 0x80 || (isalnum(ch) || ch == '_'); } static void ColouriseFlagShipDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; WordList &keywords5 = *keywordlists[4]; // property lexer.flagship.styling.within.preprocessor // For Harbour code, determines whether all preprocessor code is styled in the preprocessor style (0) or only from the // initial # to the end of the command word(1, the default). It also determines how to present text, dump, and disabled code. bool stylingWithinPreprocessor = styler.GetPropertyInt("lexer.flagship.styling.within.preprocessor", 1) != 0; CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]"); int visibleChars = 0; int closeStringChar = 0; int styleBeforeDCKeyword = SCE_FS_DEFAULT; bool bEnableCode = initStyle < SCE_FS_DISABLEDCODE; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { // Determine if the current state should terminate. switch (sc.state) { case SCE_FS_OPERATOR: case SCE_FS_OPERATOR_C: case SCE_FS_WORDOPERATOR: sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C); break; case SCE_FS_IDENTIFIER: case SCE_FS_IDENTIFIER_C: if (!IsAWordChar(sc.ch)) { char s[64]; sc.GetCurrentLowered(s, sizeof(s)); if (keywords.InList(s)) { sc.ChangeState(bEnableCode ? SCE_FS_KEYWORD : SCE_FS_KEYWORD_C); } else if (keywords2.InList(s)) { sc.ChangeState(bEnableCode ? SCE_FS_KEYWORD2 : SCE_FS_KEYWORD2_C); } else if (bEnableCode && keywords3.InList(s)) { sc.ChangeState(SCE_FS_KEYWORD3); } else if (bEnableCode && keywords4.InList(s)) { sc.ChangeState(SCE_FS_KEYWORD4); }// Else, it is really an identifier... sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C); } break; case SCE_FS_NUMBER: if (!IsAWordChar(sc.ch) && !(sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_FS_DEFAULT); } break; case SCE_FS_NUMBER_C: if (!IsAWordChar(sc.ch) && sc.ch != '.') { sc.SetState(SCE_FS_DEFAULT_C); } break; case SCE_FS_CONSTANT: if (!IsAWordChar(sc.ch)) { sc.SetState(SCE_FS_DEFAULT); } break; case SCE_FS_STRING: case SCE_FS_STRING_C: if (sc.ch == closeStringChar) { sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C); } else if (sc.atLineEnd) { sc.ChangeState(bEnableCode ? SCE_FS_STRINGEOL : SCE_FS_STRINGEOL_C); } break; case SCE_FS_STRINGEOL: case SCE_FS_STRINGEOL_C: if (sc.atLineStart) { sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C); } break; case SCE_FS_COMMENTDOC: case SCE_FS_COMMENTDOC_C: if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C); } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support // Verify that we have the conditions to mark a comment-doc-keyword if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) { styleBeforeDCKeyword = bEnableCode ? SCE_FS_COMMENTDOC : SCE_FS_COMMENTDOC_C; sc.SetState(SCE_FS_COMMENTDOCKEYWORD); } } break; case SCE_FS_COMMENT: case SCE_FS_COMMENTLINE: if (sc.atLineStart) { sc.SetState(SCE_FS_DEFAULT); } break; case SCE_FS_COMMENTLINEDOC: case SCE_FS_COMMENTLINEDOC_C: if (sc.atLineStart) { sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C); } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support // Verify that we have the conditions to mark a comment-doc-keyword if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) { styleBeforeDCKeyword = bEnableCode ? SCE_FS_COMMENTLINEDOC : SCE_FS_COMMENTLINEDOC_C; sc.SetState(SCE_FS_COMMENTDOCKEYWORD); } } break; case SCE_FS_COMMENTDOCKEYWORD: if ((styleBeforeDCKeyword == SCE_FS_COMMENTDOC || styleBeforeDCKeyword == SCE_FS_COMMENTDOC_C) && sc.Match('*', '/')) { sc.ChangeState(SCE_FS_COMMENTDOCKEYWORDERROR); sc.Forward(); sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C); } else if (!setDoxygen.Contains(sc.ch)) { char s[64]; sc.GetCurrentLowered(s, sizeof(s)); if (!IsASpace(sc.ch) || !keywords5.InList(s + 1)) { sc.ChangeState(SCE_FS_COMMENTDOCKEYWORDERROR); } sc.SetState(styleBeforeDCKeyword); } break; case SCE_FS_PREPROCESSOR: case SCE_FS_PREPROCESSOR_C: if (sc.atLineEnd) { if (!(sc.chPrev == ';' || sc.GetRelative(-2) == ';')) { sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C); } } else if (stylingWithinPreprocessor) { if (IsASpaceOrTab(sc.ch)) { sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C); } } else if (sc.Match('/', '*') || sc.Match('/', '/') || sc.Match('&', '&')) { sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C); } break; case SCE_FS_DISABLEDCODE: if (sc.ch == '#' && visibleChars == 0) { sc.SetState(bEnableCode ? SCE_FS_PREPROCESSOR : SCE_FS_PREPROCESSOR_C); do { // Skip whitespace between # and preprocessor word sc.Forward(); } while (IsASpaceOrTab(sc.ch) && sc.More()); if (sc.MatchIgnoreCase("pragma")) { sc.Forward(6); do { // Skip more whitespace until keyword sc.Forward(); } while (IsASpaceOrTab(sc.ch) && sc.More()); if (sc.MatchIgnoreCase("enddump") || sc.MatchIgnoreCase("__endtext")) { bEnableCode = true; sc.SetState(SCE_FS_DISABLEDCODE); sc.Forward(sc.ch == '_' ? 8 : 6); sc.ForwardSetState(SCE_FS_DEFAULT); } else { sc.ChangeState(SCE_FS_DISABLEDCODE); } } else { sc.ChangeState(SCE_FS_DISABLEDCODE); } } break; case SCE_FS_DATE: if (sc.ch == '}') { sc.ForwardSetState(SCE_FS_DEFAULT); } else if (sc.atLineEnd) { sc.ChangeState(SCE_FS_STRINGEOL); } } // Determine if a new state should be entered. if (sc.state == SCE_FS_DEFAULT || sc.state == SCE_FS_DEFAULT_C) { if (bEnableCode && (sc.MatchIgnoreCase(".and.") || sc.MatchIgnoreCase(".not."))) { sc.SetState(SCE_FS_WORDOPERATOR); sc.Forward(4); } else if (bEnableCode && sc.MatchIgnoreCase(".or.")) { sc.SetState(SCE_FS_WORDOPERATOR); sc.Forward(3); } else if (bEnableCode && (sc.MatchIgnoreCase(".t.") || sc.MatchIgnoreCase(".f.") || (!IsAWordChar(sc.GetRelative(3)) && sc.MatchIgnoreCase("nil")))) { sc.SetState(SCE_FS_CONSTANT); sc.Forward(2); } else if (sc.Match('/', '*')) { sc.SetState(bEnableCode ? SCE_FS_COMMENTDOC : SCE_FS_COMMENTDOC_C); sc.Forward(); } else if (bEnableCode && sc.Match('&', '&')) { sc.SetState(SCE_FS_COMMENTLINE); sc.Forward(); } else if (sc.Match('/', '/')) { sc.SetState(bEnableCode ? SCE_FS_COMMENTLINEDOC : SCE_FS_COMMENTLINEDOC_C); sc.Forward(); } else if (bEnableCode && sc.ch == '*' && visibleChars == 0) { sc.SetState(SCE_FS_COMMENT); } else if (sc.ch == '\"' || sc.ch == '\'') { sc.SetState(bEnableCode ? SCE_FS_STRING : SCE_FS_STRING_C); closeStringChar = sc.ch; } else if (closeStringChar == '>' && sc.ch == '<') { sc.SetState(bEnableCode ? SCE_FS_STRING : SCE_FS_STRING_C); } else if (sc.ch == '#' && visibleChars == 0) { sc.SetState(bEnableCode ? SCE_FS_PREPROCESSOR : SCE_FS_PREPROCESSOR_C); do { // Skip whitespace between # and preprocessor word sc.Forward(); } while (IsASpaceOrTab(sc.ch) && sc.More()); if (sc.atLineEnd) { sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C); } else if (sc.MatchIgnoreCase("include")) { if (stylingWithinPreprocessor) { closeStringChar = '>'; } } else if (sc.MatchIgnoreCase("pragma")) { sc.Forward(6); do { // Skip more whitespace until keyword sc.Forward(); } while (IsASpaceOrTab(sc.ch) && sc.More()); if (sc.MatchIgnoreCase("begindump") || sc.MatchIgnoreCase("__cstream")) { bEnableCode = false; if (stylingWithinPreprocessor) { sc.SetState(SCE_FS_DISABLEDCODE); sc.Forward(8); sc.ForwardSetState(SCE_FS_DEFAULT_C); } else { sc.SetState(SCE_FS_DISABLEDCODE); } } else if (sc.MatchIgnoreCase("enddump") || sc.MatchIgnoreCase("__endtext")) { bEnableCode = true; sc.SetState(SCE_FS_DISABLEDCODE); sc.Forward(sc.ch == '_' ? 8 : 6); sc.ForwardSetState(SCE_FS_DEFAULT); } } } else if (bEnableCode && sc.ch == '{') { int p = 0; int chSeek; unsigned int endPos(startPos + length); do { // Skip whitespace chSeek = sc.GetRelative(++p); } while (IsASpaceOrTab(chSeek) && (sc.currentPos + p < endPos)); if (chSeek == '^') { sc.SetState(SCE_FS_DATE); } else { sc.SetState(SCE_FS_OPERATOR); } } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(bEnableCode ? SCE_FS_NUMBER : SCE_FS_NUMBER_C); } else if (IsAWordChar(sc.ch)) { sc.SetState(bEnableCode ? SCE_FS_IDENTIFIER : SCE_FS_IDENTIFIER_C); } else if (isoperator(static_cast<char>(sc.ch)) || (bEnableCode && sc.ch == '@')) { sc.SetState(bEnableCode ? SCE_FS_OPERATOR : SCE_FS_OPERATOR_C); } } if (sc.atLineEnd) { visibleChars = 0; closeStringChar = 0; } if (!IsASpace(sc.ch)) { visibleChars++; } } sc.Complete(); } static void FoldFlagShipDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { int endPos = startPos + length; // Backtrack to previous line in case need to fix its fold status int lineCurrent = styler.GetLine(startPos); if (startPos > 0 && lineCurrent > 0) { lineCurrent--; startPos = styler.LineStart(lineCurrent); } int spaceFlags = 0; int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags); char chNext = styler[startPos]; for (int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos-1)) { int lev = indentCurrent; int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags); if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) { lev |= SC_FOLDLEVELHEADERFLAG; } else if (indentNext & SC_FOLDLEVELWHITEFLAG) { int spaceFlags2 = 0; int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2); if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) { lev |= SC_FOLDLEVELHEADERFLAG; } } } indentCurrent = indentNext; styler.SetLevel(lineCurrent, lev); lineCurrent++; } } } static const char * const FSWordListDesc[] = { "Keywords Commands", "Std Library Functions", "Procedure, return, exit", "Class (oop)", "Doxygen keywords", 0 }; LexerModule lmFlagShip(SCLEX_FLAGSHIP, ColouriseFlagShipDoc, "flagship", FoldFlagShipDoc, FSWordListDesc); |
Added lexers/LexForth.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
// Scintilla source code edit control /** @file LexForth.cxx ** Lexer for FORTH **/ // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '?' || ch == '"' || ch == '@' || ch == '!' || ch == '[' || ch == ']' || ch == '/' || ch == '+' || ch == '-' || ch == '*' || ch == '<' || ch == '>' || ch == '=' || ch == ';' || ch == '(' || ch == ')' ); } static inline bool IsAWordStart(int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.'); } static inline bool IsANumChar(int ch) { return (ch < 0x80) && (isxdigit(ch) || ch == '.' || ch == 'e' || ch == 'E' ); } static inline bool IsASpaceChar(int ch) { return (ch < 0x80) && isspace(ch); } static void ColouriseForthDoc(unsigned int startPos, int length, int initStyle, WordList *keywordLists[], Accessor &styler) { WordList &control = *keywordLists[0]; WordList &keyword = *keywordLists[1]; WordList &defword = *keywordLists[2]; WordList &preword1 = *keywordLists[3]; WordList &preword2 = *keywordLists[4]; WordList &strings = *keywordLists[5]; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { // Determine if the current state should terminate. if (sc.state == SCE_FORTH_COMMENT) { if (sc.atLineEnd) { sc.SetState(SCE_FORTH_DEFAULT); } }else if (sc.state == SCE_FORTH_COMMENT_ML) { if (sc.ch == ')') { sc.ForwardSetState(SCE_FORTH_DEFAULT); } }else if (sc.state == SCE_FORTH_IDENTIFIER || sc.state == SCE_FORTH_NUMBER) { // handle numbers here too, because what we thought was a number might // turn out to be a keyword e.g. 2DUP if (IsASpaceChar(sc.ch) ) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); int newState = sc.state == SCE_FORTH_NUMBER ? SCE_FORTH_NUMBER : SCE_FORTH_DEFAULT; if (control.InList(s)) { sc.ChangeState(SCE_FORTH_CONTROL); } else if (keyword.InList(s)) { sc.ChangeState(SCE_FORTH_KEYWORD); } else if (defword.InList(s)) { sc.ChangeState(SCE_FORTH_DEFWORD); } else if (preword1.InList(s)) { sc.ChangeState(SCE_FORTH_PREWORD1); } else if (preword2.InList(s)) { sc.ChangeState(SCE_FORTH_PREWORD2); } else if (strings.InList(s)) { sc.ChangeState(SCE_FORTH_STRING); newState = SCE_FORTH_STRING; } sc.SetState(newState); } if (sc.state == SCE_FORTH_NUMBER) { if (IsASpaceChar(sc.ch)) { sc.SetState(SCE_FORTH_DEFAULT); } else if (!IsANumChar(sc.ch)) { sc.ChangeState(SCE_FORTH_IDENTIFIER); } } }else if (sc.state == SCE_FORTH_STRING) { if (sc.ch == '\"') { sc.ForwardSetState(SCE_FORTH_DEFAULT); } }else if (sc.state == SCE_FORTH_LOCALE) { if (sc.ch == '}') { sc.ForwardSetState(SCE_FORTH_DEFAULT); } }else if (sc.state == SCE_FORTH_DEFWORD) { if (IsASpaceChar(sc.ch)) { sc.SetState(SCE_FORTH_DEFAULT); } } // Determine if a new state should be entered. if (sc.state == SCE_FORTH_DEFAULT) { if (sc.ch == '\\'){ sc.SetState(SCE_FORTH_COMMENT); } else if (sc.ch == '(' && (sc.atLineStart || IsASpaceChar(sc.chPrev)) && (sc.atLineEnd || IsASpaceChar(sc.chNext))) { sc.SetState(SCE_FORTH_COMMENT_ML); } else if ( (sc.ch == '$' && (isascii(sc.chNext) && isxdigit(sc.chNext))) ) { // number starting with $ is a hex number sc.SetState(SCE_FORTH_NUMBER); while(sc.More() && isascii(sc.chNext) && isxdigit(sc.chNext)) sc.Forward(); } else if ( (sc.ch == '%' && (isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))) ) { // number starting with % is binary sc.SetState(SCE_FORTH_NUMBER); while(sc.More() && isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1')) sc.Forward(); } else if ( isascii(sc.ch) && (isxdigit(sc.ch) || ((sc.ch == '.' || sc.ch == '-') && isascii(sc.chNext) && isxdigit(sc.chNext)) ) ){ sc.SetState(SCE_FORTH_NUMBER); } else if (IsAWordStart(sc.ch)) { sc.SetState(SCE_FORTH_IDENTIFIER); } else if (sc.ch == '{') { sc.SetState(SCE_FORTH_LOCALE); } else if (sc.ch == ':' && isascii(sc.chNext) && isspace(sc.chNext)) { // highlight word definitions e.g. : GCD ( n n -- n ) ..... ; // ^ ^^^ sc.SetState(SCE_FORTH_DEFWORD); while(sc.More() && isascii(sc.chNext) && isspace(sc.chNext)) sc.Forward(); } else if (sc.ch == ';' && (sc.atLineStart || IsASpaceChar(sc.chPrev)) && (sc.atLineEnd || IsASpaceChar(sc.chNext)) ) { // mark the ';' that ends a word sc.SetState(SCE_FORTH_DEFWORD); sc.ForwardSetState(SCE_FORTH_DEFAULT); } } } sc.Complete(); } static void FoldForthDoc(unsigned int, int, int, WordList *[], Accessor &) { } static const char * const forthWordLists[] = { "control keywords", "keywords", "definition words", "prewords with one argument", "prewords with two arguments", "string definition keywords", 0, }; LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth", FoldForthDoc, forthWordLists); |
Added lexers/LexFortran.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 |
// Scintilla source code edit control /** @file LexFortran.cxx ** Lexer for Fortran. ** Writen by Chuan-jian Shen, Last changed Sep. 2003 **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. /***************************************/ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> /***************************************/ #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" /***************************************/ #ifdef SCI_NAMESPACE using namespace Scintilla; #endif /***********************************************/ static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '%'); } /**********************************************/ static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch)); } /***************************************/ inline bool IsABlank(unsigned int ch) { return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ; } /***************************************/ inline bool IsALineEnd(char ch) { return ((ch == '\n') || (ch == '\r')) ; } /***************************************/ unsigned int GetContinuedPos(unsigned int pos, Accessor &styler) { while (!IsALineEnd(styler.SafeGetCharAt(pos++))) continue; if (styler.SafeGetCharAt(pos) == '\n') pos++; while (IsABlank(styler.SafeGetCharAt(pos++))) continue; char chCur = styler.SafeGetCharAt(pos); if (chCur == '&') { while (IsABlank(styler.SafeGetCharAt(++pos))) continue; return pos; } else { return pos; } } /***************************************/ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler, bool isFixFormat) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; /***************************************/ int posLineStart = 0, numNonBlank = 0, prevState = 0; int endPos = startPos + length; /***************************************/ // backtrack to the nearest keyword while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_F_WORD)) { startPos--; } startPos = styler.LineStart(styler.GetLine(startPos)); initStyle = styler.StyleAt(startPos - 1); StyleContext sc(startPos, endPos-startPos, initStyle, styler); /***************************************/ for (; sc.More(); sc.Forward()) { // remember the start position of the line if (sc.atLineStart) { posLineStart = sc.currentPos; numNonBlank = 0; sc.SetState(SCE_F_DEFAULT); } if (!IsASpaceOrTab(sc.ch)) numNonBlank ++; /***********************************************/ // Handle the fix format generically int toLineStart = sc.currentPos - posLineStart; if (isFixFormat && (toLineStart < 6 || toLineStart >= 72)) { if ((toLineStart == 0 && (tolower(sc.ch) == 'c' || sc.ch == '*')) || sc.ch == '!') { if (sc.MatchIgnoreCase("cdec$") || sc.MatchIgnoreCase("*dec$") || sc.MatchIgnoreCase("!dec$") || sc.MatchIgnoreCase("cdir$") || sc.MatchIgnoreCase("*dir$") || sc.MatchIgnoreCase("!dir$") || sc.MatchIgnoreCase("cms$") || sc.MatchIgnoreCase("*ms$") || sc.MatchIgnoreCase("!ms$") || sc.chNext == '$') { sc.SetState(SCE_F_PREPROCESSOR); } else { sc.SetState(SCE_F_COMMENT); } while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end } else if (toLineStart >= 72) { sc.SetState(SCE_F_COMMENT); while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end } else if (toLineStart < 5) { if (IsADigit(sc.ch)) sc.SetState(SCE_F_LABEL); else sc.SetState(SCE_F_DEFAULT); } else if (toLineStart == 5) { //if (!IsASpace(sc.ch) && sc.ch != '0') { if (sc.ch != '\r' && sc.ch != '\n') { sc.SetState(SCE_F_CONTINUATION); if (!IsASpace(sc.ch) && sc.ch != '0') sc.ForwardSetState(prevState); } else sc.SetState(SCE_F_DEFAULT); } continue; } /***************************************/ // Hanndle preprocessor directives if (sc.ch == '#' && numNonBlank == 1) { sc.SetState(SCE_F_PREPROCESSOR); while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end } /***************************************/ // Handle line continuation generically. if (!isFixFormat && sc.ch == '&' && sc.state != SCE_F_COMMENT) { char chTemp = ' '; int j = 1; while (IsABlank(chTemp) && j<132) { chTemp = static_cast<char>(sc.GetRelative(j)); j++; } if (chTemp == '!') { sc.SetState(SCE_F_CONTINUATION); if (sc.chNext == '!') sc.ForwardSetState(SCE_F_COMMENT); } else if (chTemp == '\r' || chTemp == '\n') { int currentState = sc.state; sc.SetState(SCE_F_CONTINUATION); sc.ForwardSetState(SCE_F_DEFAULT); while (IsASpace(sc.ch) && sc.More()) sc.Forward(); if (sc.ch == '&') { sc.SetState(SCE_F_CONTINUATION); sc.Forward(); } sc.SetState(currentState); } } /***************************************/ // Determine if the current state should terminate. if (sc.state == SCE_F_OPERATOR) { sc.SetState(SCE_F_DEFAULT); } else if (sc.state == SCE_F_NUMBER) { if (!(IsAWordChar(sc.ch) || sc.ch=='\'' || sc.ch=='\"' || sc.ch=='.')) { sc.SetState(SCE_F_DEFAULT); } } else if (sc.state == SCE_F_IDENTIFIER) { if (!IsAWordChar(sc.ch) || (sc.ch == '%')) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (keywords.InList(s)) { sc.ChangeState(SCE_F_WORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_F_WORD2); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_F_WORD3); } sc.SetState(SCE_F_DEFAULT); } } else if (sc.state == SCE_F_COMMENT || sc.state == SCE_F_PREPROCESSOR) { if (sc.ch == '\r' || sc.ch == '\n') { sc.SetState(SCE_F_DEFAULT); } } else if (sc.state == SCE_F_STRING1) { prevState = sc.state; if (sc.ch == '\'') { if (sc.chNext == '\'') { sc.Forward(); } else { sc.ForwardSetState(SCE_F_DEFAULT); prevState = SCE_F_DEFAULT; } } else if (sc.atLineEnd) { sc.ChangeState(SCE_F_STRINGEOL); sc.ForwardSetState(SCE_F_DEFAULT); } } else if (sc.state == SCE_F_STRING2) { prevState = sc.state; if (sc.atLineEnd) { sc.ChangeState(SCE_F_STRINGEOL); sc.ForwardSetState(SCE_F_DEFAULT); } else if (sc.ch == '\"') { if (sc.chNext == '\"') { sc.Forward(); } else { sc.ForwardSetState(SCE_F_DEFAULT); prevState = SCE_F_DEFAULT; } } } else if (sc.state == SCE_F_OPERATOR2) { if (sc.ch == '.') { sc.ForwardSetState(SCE_F_DEFAULT); } } else if (sc.state == SCE_F_CONTINUATION) { sc.SetState(SCE_F_DEFAULT); } else if (sc.state == SCE_F_LABEL) { if (!IsADigit(sc.ch)) { sc.SetState(SCE_F_DEFAULT); } else { if (isFixFormat && sc.currentPos-posLineStart > 4) sc.SetState(SCE_F_DEFAULT); else if (numNonBlank > 5) sc.SetState(SCE_F_DEFAULT); } } /***************************************/ // Determine if a new state should be entered. if (sc.state == SCE_F_DEFAULT) { if (sc.ch == '!') { if (sc.MatchIgnoreCase("!dec$") || sc.MatchIgnoreCase("!dir$") || sc.MatchIgnoreCase("!ms$") || sc.chNext == '$') { sc.SetState(SCE_F_PREPROCESSOR); } else { sc.SetState(SCE_F_COMMENT); } } else if ((!isFixFormat) && IsADigit(sc.ch) && numNonBlank == 1) { sc.SetState(SCE_F_LABEL); } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_F_NUMBER); } else if ((tolower(sc.ch) == 'b' || tolower(sc.ch) == 'o' || tolower(sc.ch) == 'z') && (sc.chNext == '\"' || sc.chNext == '\'')) { sc.SetState(SCE_F_NUMBER); sc.Forward(); } else if (sc.ch == '.' && isalpha(sc.chNext)) { sc.SetState(SCE_F_OPERATOR2); } else if (IsAWordStart(sc.ch)) { sc.SetState(SCE_F_IDENTIFIER); } else if (sc.ch == '\"') { sc.SetState(SCE_F_STRING2); } else if (sc.ch == '\'') { sc.SetState(SCE_F_STRING1); } else if (isoperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_F_OPERATOR); } } } sc.Complete(); } /***************************************/ // To determine the folding level depending on keywords static int classifyFoldPointFortran(const char* s, const char* prevWord, const char chNextNonBlank) { int lev = 0; if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0) return -1; if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0 || strcmp(s, "blockdata") == 0 || strcmp(s, "select") == 0 || strcmp(s, "do") == 0 || strcmp(s, "enum") ==0 || strcmp(s, "function") == 0 || strcmp(s, "interface") == 0 || strcmp(s, "module") == 0 || strcmp(s, "program") == 0 || strcmp(s, "subroutine") == 0 || strcmp(s, "then") == 0 || (strcmp(s, "type") == 0 && chNextNonBlank != '(') || strcmp(s, "critical") == 0){ if (strcmp(prevWord, "end") == 0) lev = 0; else lev = 1; } else if ((strcmp(s, "end") == 0 && chNextNonBlank != '=') || strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0 || strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0 || strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0 || strcmp(s, "endif") == 0 || strcmp(s, "endforall") == 0 || strcmp(s, "endfunction") == 0 || strcmp(s, "endinterface") == 0 || strcmp(s, "endmodule") == 0 || strcmp(s, "endprogram") == 0 || strcmp(s, "endsubroutine") == 0 || strcmp(s, "endtype") == 0 || strcmp(s, "endwhere") == 0 || strcmp(s, "endcritical") == 0 || (strcmp(s, "procedure") == 0 && strcmp(prevWord, "module") == 0) ) { // Take care of the "module procedure" statement lev = -1; } else if (strcmp(prevWord, "end") == 0 && strcmp(s, "if") == 0){ // end if lev = 0; } else if (strcmp(prevWord, "type") == 0 && strcmp(s, "is") == 0){ // type is lev = -1; } return lev; } // Folding the code static void FoldFortranDoc(unsigned int startPos, int length, int initStyle, Accessor &styler, bool isFixFormat) { // // bool foldComment = styler.GetPropertyInt("fold.comment") != 0; // Do not know how to fold the comment at the moment. // bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; char chNextNonBlank; int styleNext = styler.StyleAt(startPos); int style = initStyle; /***************************************/ int lastStart = 0; char prevWord[32] = ""; char Label[6] = ""; // Variables for do label folding. static int doLabels[100]; static int posLabel=-1; /***************************************/ for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); chNextNonBlank = chNext; unsigned int j=i+1; while(IsABlank(chNextNonBlank) && j<endPos) { j ++ ; chNextNonBlank = styler.SafeGetCharAt(j); } int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); // if (((isFixFormat && stylePrev == SCE_F_CONTINUATION) || stylePrev == SCE_F_DEFAULT || stylePrev == SCE_F_OPERATOR) && (style == SCE_F_WORD || style == SCE_F_LABEL)) { // Store last word and label start point. lastStart = i; } /***************************************/ if (style == SCE_F_WORD) { if(iswordchar(ch) && !iswordchar(chNext)) { char s[32]; unsigned int k; for(k=0; (k<31 ) && (k<i-lastStart+1 ); k++) { s[k] = static_cast<char>(tolower(styler[lastStart+k])); } s[k] = '\0'; // Handle the forall and where statement and structure. if (strcmp(s, "forall") == 0 || strcmp(s, "where") == 0) { if (strcmp(prevWord, "end") != 0) { j = i + 1; char chBrace = '(', chSeek = ')', ch1 = styler.SafeGetCharAt(j); // Find the position of the first ( while (ch1 != chBrace && j<endPos) { j++; ch1 = styler.SafeGetCharAt(j); } char styBrace = styler.StyleAt(j); int depth = 1; char chAtPos; char styAtPos; while (j<endPos) { j++; chAtPos = styler.SafeGetCharAt(j); styAtPos = styler.StyleAt(j); if (styAtPos == styBrace) { if (chAtPos == chBrace) depth++; if (chAtPos == chSeek) depth--; if (depth == 0) break; } } while (j<endPos) { j++; chAtPos = styler.SafeGetCharAt(j); styAtPos = styler.StyleAt(j); if (styAtPos == SCE_F_COMMENT || IsABlank(chAtPos)) continue; if (isFixFormat) { if (!IsALineEnd(chAtPos)) { break; } else { if (lineCurrent < styler.GetLine(styler.Length()-1)) { j = styler.LineStart(lineCurrent+1); if (styler.StyleAt(j+5) == SCE_F_CONTINUATION) { j += 5; continue; } else { levelCurrent++; break; } } } } else { if (chAtPos == '&' && styler.StyleAt(j) == SCE_F_CONTINUATION) { j = GetContinuedPos(j+1, styler); continue; } else if (IsALineEnd(chAtPos)) { levelCurrent ++; break; } else { break; } } } } } else { levelCurrent += classifyFoldPointFortran(s, prevWord, chNextNonBlank); // Store the do Labels into array if (strcmp(s, "do") == 0 && IsADigit(chNextNonBlank)) { unsigned int k = 0; for (i=j; (i<j+5 && i<endPos); i++) { ch = styler.SafeGetCharAt(i); if (IsADigit(ch)) Label[k++] = ch; else break; } Label[k] = '\0'; posLabel ++; doLabels[posLabel] = atoi(Label); } } strcpy(prevWord, s); } } else if (style == SCE_F_LABEL) { if(IsADigit(ch) && !IsADigit(chNext)) { for(j = 0; ( j < 5 ) && ( j < i-lastStart+1 ); j++) { ch = styler.SafeGetCharAt(lastStart + j); if (IsADigit(ch) && styler.StyleAt(lastStart+j) == SCE_F_LABEL) Label[j] = ch; else break; } Label[j] = '\0'; while (doLabels[posLabel] == atoi(Label) && posLabel > -1) { levelCurrent--; posLabel--; } } } if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; strcpy(prevWord, ""); } /***************************************/ if (!isspacechar(ch)) visibleChars++; } /***************************************/ // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } /***************************************/ static const char * const FortranWordLists[] = { "Primary keywords and identifiers", "Intrinsic functions", "Extended and user defined functions", 0, }; /***************************************/ static void ColouriseFortranDocFreeFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, false); } /***************************************/ static void ColouriseFortranDocFixFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, true); } /***************************************/ static void FoldFortranDocFreeFormat(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { FoldFortranDoc(startPos, length, initStyle,styler, false); } /***************************************/ static void FoldFortranDocFixFormat(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { FoldFortranDoc(startPos, length, initStyle,styler, true); } /***************************************/ LexerModule lmFortran(SCLEX_FORTRAN, ColouriseFortranDocFreeFormat, "fortran", FoldFortranDocFreeFormat, FortranWordLists); LexerModule lmF77(SCLEX_F77, ColouriseFortranDocFixFormat, "f77", FoldFortranDocFixFormat, FortranWordLists); |
Added lexers/LexGAP.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
// Scintilla source code edit control /** @file LexGAP.cxx ** Lexer for the GAP language. (The GAP System for Computational Discrete Algebra) ** http://www.gap-system.org **/ // Copyright 2007 by Istvan Szollosi ( szteven <at> gmail <dot> com ) // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsGAPOperator(char ch) { if (isascii(ch) && isalnum(ch)) return false; if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^' || ch == ',' || ch == '!' || ch == '.' || ch == '=' || ch == '<' || ch == '>' || ch == '(' || ch == ')' || ch == ';' || ch == '[' || ch == ']' || ch == '{' || ch == '}' || ch == ':' ) return true; return false; } static void GetRange(unsigned int start, unsigned int end, Accessor &styler, char *s, unsigned int len) { unsigned int i = 0; while ((i < end - start + 1) && (i < len-1)) { s[i] = static_cast<char>(styler[start + i]); i++; } s[i] = '\0'; } static void ColouriseGAPDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords1 = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; // Do not leak onto next line if (initStyle == SCE_GAP_STRINGEOL) initStyle = SCE_GAP_DEFAULT; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { // Prevent SCE_GAP_STRINGEOL from leaking back to previous line if ( sc.atLineStart ) { if (sc.state == SCE_GAP_STRING) sc.SetState(SCE_GAP_STRING); if (sc.state == SCE_GAP_CHAR) sc.SetState(SCE_GAP_CHAR); } // Handle line continuation generically if (sc.ch == '\\' ) { if (sc.chNext == '\n' || sc.chNext == '\r') { sc.Forward(); if (sc.ch == '\r' && sc.chNext == '\n') { sc.Forward(); } continue; } } // Determine if the current state should terminate switch (sc.state) { case SCE_GAP_OPERATOR : sc.SetState(SCE_GAP_DEFAULT); break; case SCE_GAP_NUMBER : if (!IsADigit(sc.ch)) { if (sc.ch == '\\') { if (!sc.atLineEnd) { if (!IsADigit(sc.chNext)) { sc.Forward(); sc.ChangeState(SCE_GAP_IDENTIFIER); } } } else if (isalpha(sc.ch) || sc.ch == '_') { sc.ChangeState(SCE_GAP_IDENTIFIER); } else sc.SetState(SCE_GAP_DEFAULT); } break; case SCE_GAP_IDENTIFIER : if (!(iswordstart(static_cast<char>(sc.ch)) || sc.ch == '$')) { if (sc.ch == '\\') sc.Forward(); else { char s[1000]; sc.GetCurrent(s, sizeof(s)); if (keywords1.InList(s)) { sc.ChangeState(SCE_GAP_KEYWORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_GAP_KEYWORD2); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_GAP_KEYWORD3); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_GAP_KEYWORD4); } sc.SetState(SCE_GAP_DEFAULT); } } break; case SCE_GAP_COMMENT : if (sc.atLineEnd) { sc.SetState(SCE_GAP_DEFAULT); } break; case SCE_GAP_STRING: if (sc.atLineEnd) { sc.ChangeState(SCE_GAP_STRINGEOL); } else if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_GAP_DEFAULT); } break; case SCE_GAP_CHAR: if (sc.atLineEnd) { sc.ChangeState(SCE_GAP_STRINGEOL); } else if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\'') { sc.ForwardSetState(SCE_GAP_DEFAULT); } break; case SCE_GAP_STRINGEOL: if (sc.atLineStart) { sc.SetState(SCE_GAP_DEFAULT); } break; } // Determine if a new state should be entered if (sc.state == SCE_GAP_DEFAULT) { if (IsGAPOperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_GAP_OPERATOR); } else if (IsADigit(sc.ch)) { sc.SetState(SCE_GAP_NUMBER); } else if (isalpha(sc.ch) || sc.ch == '_' || sc.ch == '\\' || sc.ch == '$' || sc.ch == '~') { sc.SetState(SCE_GAP_IDENTIFIER); if (sc.ch == '\\') sc.Forward(); } else if (sc.ch == '#') { sc.SetState(SCE_GAP_COMMENT); } else if (sc.ch == '\"') { sc.SetState(SCE_GAP_STRING); } else if (sc.ch == '\'') { sc.SetState(SCE_GAP_CHAR); } } } sc.Complete(); } static int ClassifyFoldPointGAP(const char* s) { int level = 0; if (strcmp(s, "function") == 0 || strcmp(s, "do") == 0 || strcmp(s, "if") == 0 || strcmp(s, "repeat") == 0 ) { level = 1; } else if (strcmp(s, "end") == 0 || strcmp(s, "od") == 0 || strcmp(s, "fi") == 0 || strcmp(s, "until") == 0 ) { level = -1; } return level; } static void FoldGAPDoc( unsigned int startPos, int length, int initStyle, WordList** , Accessor &styler) { unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; int lastStart = 0; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (stylePrev != SCE_GAP_KEYWORD && style == SCE_GAP_KEYWORD) { // Store last word start point. lastStart = i; } if (stylePrev == SCE_GAP_KEYWORD) { if(iswordchar(ch) && !iswordchar(chNext)) { char s[100]; GetRange(lastStart, i, styler, s, sizeof(s)); levelCurrent += ClassifyFoldPointGAP(s); } } if (atEOL) { int lev = levelPrev; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char * const GAPWordListDesc[] = { "Keywords 1", "Keywords 2", "Keywords 3 (unused)", "Keywords 4 (unused)", 0 }; LexerModule lmGAP( SCLEX_GAP, ColouriseGAPDoc, "gap", FoldGAPDoc, GAPWordListDesc); |
Added lexers/LexGui4Cli.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
// Scintilla source code edit control // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> /* This is the Lexer for Gui4Cli, included in SciLexer.dll - by d. Keletsekis, 2/10/2003 To add to SciLexer.dll: 1. Add the values below to INCLUDE\Scintilla.iface 2. Run the include/HFacer.py script 3. Run the src/lexGen.py script val SCE_GC_DEFAULT=0 val SCE_GC_COMMENTLINE=1 val SCE_GC_COMMENTBLOCK=2 val SCE_GC_GLOBAL=3 val SCE_GC_EVENT=4 val SCE_GC_ATTRIBUTE=5 val SCE_GC_CONTROL=6 val SCE_GC_COMMAND=7 val SCE_GC_STRING=8 val SCE_GC_OPERATOR=9 */ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif #define debug Platform::DebugPrintf static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch =='\\'); } static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.'); } inline bool isGCOperator(int ch) { if (isalnum(ch)) return false; // '.' left out as it is used to make up numbers if (ch == '*' || ch == '/' || ch == '-' || ch == '+' || ch == '(' || ch == ')' || ch == '=' || ch == '%' || ch == '[' || ch == ']' || ch == '<' || ch == '>' || ch == ',' || ch == ';' || ch == ':') return true; return false; } #define isSpace(x) ((x)==' ' || (x)=='\t') #define isNL(x) ((x)=='\n' || (x)=='\r') #define isSpaceOrNL(x) (isSpace(x) || isNL(x)) #define BUFFSIZE 500 #define isFoldPoint(x) ((styler.LevelAt(x) & SC_FOLDLEVELNUMBERMASK) == 1024) static void colorFirstWord(WordList *keywordlists[], Accessor &styler, StyleContext *sc, char *buff, int length, int) { int c = 0; while (sc->More() && isSpaceOrNL(sc->ch)) { sc->Forward(); } styler.ColourTo(sc->currentPos - 1, sc->state); if (!IsAWordChar(sc->ch)) // comment, marker, etc.. return; while (sc->More() && !isSpaceOrNL(sc->ch) && (c < length-1) && !isGCOperator(sc->ch)) { buff[c] = static_cast<char>(sc->ch); ++c; sc->Forward(); } buff[c] = '\0'; char *p = buff; while (*p) // capitalize.. { if (islower(*p)) *p = static_cast<char>(toupper(*p)); ++p; } WordList &kGlobal = *keywordlists[0]; // keyword lists set by the user WordList &kEvent = *keywordlists[1]; WordList &kAttribute = *keywordlists[2]; WordList &kControl = *keywordlists[3]; WordList &kCommand = *keywordlists[4]; int state = 0; // int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK; // debug ("line = %d, level = %d", line, level); if (kGlobal.InList(buff)) state = SCE_GC_GLOBAL; else if (kAttribute.InList(buff)) state = SCE_GC_ATTRIBUTE; else if (kControl.InList(buff)) state = SCE_GC_CONTROL; else if (kCommand.InList(buff)) state = SCE_GC_COMMAND; else if (kEvent.InList(buff)) state = SCE_GC_EVENT; if (state) { sc->ChangeState(state); styler.ColourTo(sc->currentPos - 1, sc->state); sc->ChangeState(SCE_GC_DEFAULT); } else { sc->ChangeState(SCE_GC_DEFAULT); styler.ColourTo(sc->currentPos - 1, sc->state); } } // Main colorizing function called by Scintilla static void ColouriseGui4CliDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { styler.StartAt(startPos); int quotestart = 0, oldstate, currentline = styler.GetLine(startPos); styler.StartSegment(startPos); bool noforward; char buff[BUFFSIZE+1]; // buffer for command name StyleContext sc(startPos, length, initStyle, styler); buff[0] = '\0'; // cbuff = 0; if (sc.state != SCE_GC_COMMENTBLOCK) // colorize 1st word.. colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline); while (sc.More()) { noforward = 0; switch (sc.ch) { case '/': if (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_STRING) break; if (sc.chNext == '/') // line comment { sc.SetState (SCE_GC_COMMENTLINE); sc.Forward(); styler.ColourTo(sc.currentPos, sc.state); } else if (sc.chNext == '*') // block comment { sc.SetState(SCE_GC_COMMENTBLOCK); sc.Forward(); styler.ColourTo(sc.currentPos, sc.state); } else styler.ColourTo(sc.currentPos, sc.state); break; case '*': // end of comment block, or operator.. if (sc.state == SCE_GC_STRING) break; if (sc.state == SCE_GC_COMMENTBLOCK && sc.chNext == '/') { sc.Forward(); styler.ColourTo(sc.currentPos, sc.state); sc.ChangeState (SCE_GC_DEFAULT); } else styler.ColourTo(sc.currentPos, sc.state); break; case '\'': case '\"': // strings.. if (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_COMMENTLINE) break; if (sc.state == SCE_GC_STRING) { if (sc.ch == quotestart) // match same quote char.. { styler.ColourTo(sc.currentPos, sc.state); sc.ChangeState(SCE_GC_DEFAULT); quotestart = 0; } } else { styler.ColourTo(sc.currentPos - 1, sc.state); sc.ChangeState(SCE_GC_STRING); quotestart = sc.ch; } break; case ';': // end of commandline character if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE && sc.state != SCE_GC_STRING) { styler.ColourTo(sc.currentPos - 1, sc.state); styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR); sc.ChangeState(SCE_GC_DEFAULT); sc.Forward(); colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline); noforward = 1; // don't move forward - already positioned at next char.. } break; case '+': case '-': case '=': case '!': // operators.. case '<': case '>': case '&': case '|': case '$': if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE && sc.state != SCE_GC_STRING) { styler.ColourTo(sc.currentPos - 1, sc.state); styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR); sc.ChangeState(SCE_GC_DEFAULT); } break; case '\\': // escape - same as operator, but also mark in strings.. if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE) { oldstate = sc.state; styler.ColourTo(sc.currentPos - 1, sc.state); sc.Forward(); // mark also the next char.. styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR); sc.ChangeState(oldstate); } break; case '\n': case '\r': ++currentline; if (sc.state == SCE_GC_COMMENTLINE) { styler.ColourTo(sc.currentPos, sc.state); sc.ChangeState (SCE_GC_DEFAULT); } else if (sc.state != SCE_GC_COMMENTBLOCK) { colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline); noforward = 1; // don't move forward - already positioned at next char.. } break; // case ' ': case '\t': // default : } if (!noforward) sc.Forward(); } sc.Complete(); } // Main folding function called by Scintilla - (based on props (.ini) files function) static void FoldGui4Cli(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); bool headerPoint = false; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler[i+1]; int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (style == SCE_GC_EVENT || style == SCE_GC_GLOBAL) { headerPoint = true; // fold at events and globals } if (atEOL) { int lev = SC_FOLDLEVELBASE+1; if (headerPoint) lev = SC_FOLDLEVELBASE; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (headerPoint) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) // set level, if not already correct { styler.SetLevel(lineCurrent, lev); } lineCurrent++; // re-initialize our flags visibleChars = 0; headerPoint = false; } if (!(isspacechar(ch))) // || (style == SCE_GC_COMMENTLINE) || (style != SCE_GC_COMMENTBLOCK))) visibleChars++; } int lev = headerPoint ? SC_FOLDLEVELBASE : SC_FOLDLEVELBASE+1; int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, lev | flagsNext); } // I have no idea what these are for.. probably accessible by some message. static const char * const gui4cliWordListDesc[] = { "Globals", "Events", "Attributes", "Control", "Commands", 0 }; // Declare language & pass our function pointers to Scintilla LexerModule lmGui4Cli(SCLEX_GUI4CLI, ColouriseGui4CliDoc, "gui4cli", FoldGui4Cli, gui4cliWordListDesc); #undef debug |
Added lexers/LexHTML.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 |
// Scintilla source code edit control /** @file LexHTML.cxx ** Lexer for HTML. **/ // Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif #define SCE_HA_JS (SCE_HJA_START - SCE_HJ_START) #define SCE_HA_VBS (SCE_HBA_START - SCE_HB_START) #define SCE_HA_PYTHON (SCE_HPA_START - SCE_HP_START) enum script_type { eScriptNone = 0, eScriptJS, eScriptVBS, eScriptPython, eScriptPHP, eScriptXML, eScriptSGML, eScriptSGMLblock, eScriptComment }; enum script_mode { eHtml = 0, eNonHtmlScript, eNonHtmlPreProc, eNonHtmlScriptPreProc }; static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_'); } static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_'); } inline bool IsOperator(int ch) { if (isascii(ch) && isalnum(ch)) return false; // '.' left out as it is used to make up numbers if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || ch == '(' || ch == ')' || ch == '-' || ch == '+' || ch == '=' || ch == '|' || ch == '{' || ch == '}' || ch == '[' || ch == ']' || ch == ':' || ch == ';' || ch == '<' || ch == '>' || ch == ',' || ch == '/' || ch == '?' || ch == '!' || ch == '.' || ch == '~') return true; return false; } static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int end, char *s, size_t len) { unsigned int i = 0; for (; (i < end - start + 1) && (i < len-1); i++) { s[i] = static_cast<char>(MakeLowerCase(styler[start + i])); } s[i] = '\0'; } static const char *GetNextWord(Accessor &styler, unsigned int start, char *s, size_t sLen) { unsigned int i = 0; for (; i < sLen-1; i++) { char ch = static_cast<char>(styler.SafeGetCharAt(start + i)); if ((i == 0) && !IsAWordStart(ch)) break; if ((i > 0) && !IsAWordChar(ch)) break; s[i] = ch; } s[i] = '\0'; return s; } static script_type segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigned int end, script_type prevValue) { char s[100]; GetTextSegment(styler, start, end, s, sizeof(s)); //Platform::DebugPrintf("Scripting indicator [%s]\n", s); if (strstr(s, "src")) // External script return eScriptNone; if (strstr(s, "vbs")) return eScriptVBS; if (strstr(s, "pyth")) return eScriptPython; if (strstr(s, "javas")) return eScriptJS; if (strstr(s, "jscr")) return eScriptJS; if (strstr(s, "php")) return eScriptPHP; if (strstr(s, "xml")) { const char *xml = strstr(s, "xml"); for (const char *t=s; t<xml; t++) { if (!IsASpace(*t)) { return prevValue; } } return eScriptXML; } return prevValue; } static int PrintScriptingIndicatorOffset(Accessor &styler, unsigned int start, unsigned int end) { int iResult = 0; char s[100]; GetTextSegment(styler, start, end, s, sizeof(s)); if (0 == strncmp(s, "php", 3)) { iResult = 3; } return iResult; } static script_type ScriptOfState(int state) { if ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) { return eScriptPython; } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) { return eScriptVBS; } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) { return eScriptJS; } else if ((state >= SCE_HPHP_DEFAULT) && (state <= SCE_HPHP_COMMENTLINE)) { return eScriptPHP; } else if ((state >= SCE_H_SGML_DEFAULT) && (state < SCE_H_SGML_BLOCK_DEFAULT)) { return eScriptSGML; } else if (state == SCE_H_SGML_BLOCK_DEFAULT) { return eScriptSGMLblock; } else { return eScriptNone; } } static int statePrintForState(int state, script_mode inScriptType) { int StateToPrint = state; if (state >= SCE_HJ_START) { if ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) { StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_PYTHON); } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) { StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_VBS); } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) { StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_JS); } } return StateToPrint; } static int stateForPrintState(int StateToPrint) { int state; if ((StateToPrint >= SCE_HPA_START) && (StateToPrint <= SCE_HPA_IDENTIFIER)) { state = StateToPrint - SCE_HA_PYTHON; } else if ((StateToPrint >= SCE_HBA_START) && (StateToPrint <= SCE_HBA_STRINGEOL)) { state = StateToPrint - SCE_HA_VBS; } else if ((StateToPrint >= SCE_HJA_START) && (StateToPrint <= SCE_HJA_REGEX)) { state = StateToPrint - SCE_HA_JS; } else { state = StateToPrint; } return state; } static inline bool IsNumber(unsigned int start, Accessor &styler) { return IsADigit(styler[start]) || (styler[start] == '.') || (styler[start] == '-') || (styler[start] == '#'); } static inline bool isStringState(int state) { bool bResult; switch (state) { case SCE_HJ_DOUBLESTRING: case SCE_HJ_SINGLESTRING: case SCE_HJA_DOUBLESTRING: case SCE_HJA_SINGLESTRING: case SCE_HB_STRING: case SCE_HBA_STRING: case SCE_HP_STRING: case SCE_HP_CHARACTER: case SCE_HP_TRIPLE: case SCE_HP_TRIPLEDOUBLE: case SCE_HPA_STRING: case SCE_HPA_CHARACTER: case SCE_HPA_TRIPLE: case SCE_HPA_TRIPLEDOUBLE: case SCE_HPHP_HSTRING: case SCE_HPHP_SIMPLESTRING: case SCE_HPHP_HSTRING_VARIABLE: case SCE_HPHP_COMPLEX_VARIABLE: bResult = true; break; default : bResult = false; break; } return bResult; } static inline bool stateAllowsTermination(int state) { bool allowTermination = !isStringState(state); if (allowTermination) { switch (state) { case SCE_HB_COMMENTLINE: case SCE_HPHP_COMMENT: case SCE_HP_COMMENTLINE: case SCE_HPA_COMMENTLINE: allowTermination = false; } } return allowTermination; } // not really well done, since it's only comments that should lex the %> and <% static inline bool isCommentASPState(int state) { bool bResult; switch (state) { case SCE_HJ_COMMENT: case SCE_HJ_COMMENTLINE: case SCE_HJ_COMMENTDOC: case SCE_HB_COMMENTLINE: case SCE_HP_COMMENTLINE: case SCE_HPHP_COMMENT: case SCE_HPHP_COMMENTLINE: bResult = true; break; default : bResult = false; break; } return bResult; } static void classifyAttribHTML(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { bool wordIsNumber = IsNumber(start, styler); char chAttr = SCE_H_ATTRIBUTEUNKNOWN; if (wordIsNumber) { chAttr = SCE_H_NUMBER; } else { char s[100]; GetTextSegment(styler, start, end, s, sizeof(s)); if (keywords.InList(s)) chAttr = SCE_H_ATTRIBUTE; } if ((chAttr == SCE_H_ATTRIBUTEUNKNOWN) && !keywords) // No keywords -> all are known chAttr = SCE_H_ATTRIBUTE; styler.ColourTo(end, chAttr); } static int classifyTagHTML(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, bool &tagDontFold, bool caseSensitive, bool isXml, bool allowScripts) { char withSpace[30 + 2] = " "; const char *s = withSpace + 1; // Copy after the '<' unsigned int i = 1; for (unsigned int cPos = start; cPos <= end && i < 30; cPos++) { char ch = styler[cPos]; if ((ch != '<') && (ch != '/')) { withSpace[i++] = caseSensitive ? ch : static_cast<char>(MakeLowerCase(ch)); } } //The following is only a quick hack, to see if this whole thing would work //we first need the tagname with a trailing space... withSpace[i] = ' '; withSpace[i+1] = '\0'; // if the current language is XML, I can fold any tag // if the current language is HTML, I don't want to fold certain tags (input, meta, etc.) //...to find it in the list of no-container-tags tagDontFold = (!isXml) && (NULL != strstr(" area base basefont br col command embed frame hr img input isindex keygen link meta param source track wbr ", withSpace)); //now we can remove the trailing space withSpace[i] = '\0'; // No keywords -> all are known char chAttr = SCE_H_TAGUNKNOWN; if (s[0] == '!') { chAttr = SCE_H_SGML_DEFAULT; } else if (!keywords || keywords.InList(s)) { chAttr = SCE_H_TAG; } styler.ColourTo(end, chAttr); if (chAttr == SCE_H_TAG) { if (allowScripts && 0 == strcmp(s, "script")) { // check to see if this is a self-closing tag by sniffing ahead bool isSelfClose = false; for (unsigned int cPos = end; cPos <= end + 200; cPos++) { char ch = styler.SafeGetCharAt(cPos, '\0'); if (ch == '\0' || ch == '>') break; else if (ch == '/' && styler.SafeGetCharAt(cPos + 1, '\0') == '>') { isSelfClose = true; break; } } // do not enter a script state if the tag self-closed if (!isSelfClose) chAttr = SCE_H_SCRIPT; } else if (!isXml && 0 == strcmp(s, "comment")) { chAttr = SCE_H_COMMENT; } } return chAttr; } static void classifyWordHTJS(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, script_mode inScriptType) { char s[30 + 1]; unsigned int i = 0; for (; i < end - start + 1 && i < 30; i++) { s[i] = styler[start + i]; } s[i] = '\0'; char chAttr = SCE_HJ_WORD; bool wordIsNumber = IsADigit(s[0]) || ((s[0] == '.') && IsADigit(s[1])); if (wordIsNumber) { chAttr = SCE_HJ_NUMBER; } else if (keywords.InList(s)) { chAttr = SCE_HJ_KEYWORD; } styler.ColourTo(end, statePrintForState(chAttr, inScriptType)); } static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, script_mode inScriptType) { char chAttr = SCE_HB_IDENTIFIER; bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.'); if (wordIsNumber) chAttr = SCE_HB_NUMBER; else { char s[100]; GetTextSegment(styler, start, end, s, sizeof(s)); if (keywords.InList(s)) { chAttr = SCE_HB_WORD; if (strcmp(s, "rem") == 0) chAttr = SCE_HB_COMMENTLINE; } } styler.ColourTo(end, statePrintForState(chAttr, inScriptType)); if (chAttr == SCE_HB_COMMENTLINE) return SCE_HB_COMMENTLINE; else return SCE_HB_DEFAULT; } static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord, script_mode inScriptType, bool isMako) { bool wordIsNumber = IsADigit(styler[start]); char s[30 + 1]; unsigned int i = 0; for (; i < end - start + 1 && i < 30; i++) { s[i] = styler[start + i]; } s[i] = '\0'; char chAttr = SCE_HP_IDENTIFIER; if (0 == strcmp(prevWord, "class")) chAttr = SCE_HP_CLASSNAME; else if (0 == strcmp(prevWord, "def")) chAttr = SCE_HP_DEFNAME; else if (wordIsNumber) chAttr = SCE_HP_NUMBER; else if (keywords.InList(s)) chAttr = SCE_HP_WORD; else if (isMako && 0 == strcmp(s, "block")) chAttr = SCE_HP_WORD; styler.ColourTo(end, statePrintForState(chAttr, inScriptType)); strcpy(prevWord, s); } // Update the word colour to default or keyword // Called when in a PHP word static void classifyWordHTPHP(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { char chAttr = SCE_HPHP_DEFAULT; bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.' && start+1 <= end && IsADigit(styler[start+1])); if (wordIsNumber) chAttr = SCE_HPHP_NUMBER; else { char s[100]; GetTextSegment(styler, start, end, s, sizeof(s)); if (keywords.InList(s)) chAttr = SCE_HPHP_WORD; } styler.ColourTo(end, chAttr); } static bool isWordHSGML(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) { char s[30 + 1]; unsigned int i = 0; for (; i < end - start + 1 && i < 30; i++) { s[i] = styler[start + i]; } s[i] = '\0'; return keywords.InList(s); } static bool isWordCdata(unsigned int start, unsigned int end, Accessor &styler) { char s[30 + 1]; unsigned int i = 0; for (; i < end - start + 1 && i < 30; i++) { s[i] = styler[start + i]; } s[i] = '\0'; return (0 == strcmp(s, "[CDATA[")); } // Return the first state to reach when entering a scripting language static int StateForScript(script_type scriptLanguage) { int Result; switch (scriptLanguage) { case eScriptVBS: Result = SCE_HB_START; break; case eScriptPython: Result = SCE_HP_START; break; case eScriptPHP: Result = SCE_HPHP_DEFAULT; break; case eScriptXML: Result = SCE_H_TAGUNKNOWN; break; case eScriptSGML: Result = SCE_H_SGML_DEFAULT; break; case eScriptComment: Result = SCE_H_COMMENT; break; default : Result = SCE_HJ_START; break; } return Result; } static inline bool issgmlwordchar(int ch) { return !isascii(ch) || (isalnum(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#' || ch == '['); } static inline bool IsPhpWordStart(int ch) { return (isascii(ch) && (isalpha(ch) || (ch == '_'))) || (ch >= 0x7f); } static inline bool IsPhpWordChar(int ch) { return IsADigit(ch) || IsPhpWordStart(ch); } static bool InTagState(int state) { return state == SCE_H_TAG || state == SCE_H_TAGUNKNOWN || state == SCE_H_SCRIPT || state == SCE_H_ATTRIBUTE || state == SCE_H_ATTRIBUTEUNKNOWN || state == SCE_H_NUMBER || state == SCE_H_OTHER || state == SCE_H_DOUBLESTRING || state == SCE_H_SINGLESTRING; } static bool IsCommentState(const int state) { return state == SCE_H_COMMENT || state == SCE_H_SGML_COMMENT; } static bool IsScriptCommentState(const int state) { return state == SCE_HJ_COMMENT || state == SCE_HJ_COMMENTLINE || state == SCE_HJA_COMMENT || state == SCE_HJA_COMMENTLINE || state == SCE_HB_COMMENTLINE || state == SCE_HBA_COMMENTLINE; } static bool isLineEnd(int ch) { return ch == '\r' || ch == '\n'; } static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType) { if (strlen(blockType) == 0) { return ((ch == '%') && (chNext == '>')); } else if ((0 == strcmp(blockType, "inherit")) || (0 == strcmp(blockType, "namespace")) || (0 == strcmp(blockType, "include")) || (0 == strcmp(blockType, "page"))) { return ((ch == '/') && (chNext == '>')); } else if (0 == strcmp(blockType, "%")) { if (ch == '/' && isLineEnd(chNext)) return 1; else return isLineEnd(ch); } else if (0 == strcmp(blockType, "{")) { return ch == '}'; } else { return (ch == '>'); } } static bool isDjangoBlockEnd(const int ch, const int chNext, const char *blockType) { if (strlen(blockType) == 0) { return 0; } else if (0 == strcmp(blockType, "%")) { return ((ch == '%') && (chNext == '}')); } else if (0 == strcmp(blockType, "{")) { return ((ch == '}') && (chNext == '}')); } else { return 0; } } static bool isPHPStringState(int state) { return (state == SCE_HPHP_HSTRING) || (state == SCE_HPHP_SIMPLESTRING) || (state == SCE_HPHP_HSTRING_VARIABLE) || (state == SCE_HPHP_COMPLEX_VARIABLE); } static int FindPhpStringDelimiter(char *phpStringDelimiter, const int phpStringDelimiterSize, int i, const int lengthDoc, Accessor &styler, bool &isSimpleString) { int j; const int beginning = i - 1; bool isValidSimpleString = false; while (i < lengthDoc && (styler[i] == ' ' || styler[i] == '\t')) i++; char ch = styler.SafeGetCharAt(i); const char chNext = styler.SafeGetCharAt(i + 1); if (!IsPhpWordStart(ch)) { if (ch == '\'' && IsPhpWordStart(chNext)) { i++; ch = chNext; isSimpleString = true; } else { phpStringDelimiter[0] = '\0'; return beginning; } } phpStringDelimiter[0] = ch; i++; for (j = i; j < lengthDoc && !isLineEnd(styler[j]); j++) { if (!IsPhpWordChar(styler[j])) { if (isSimpleString && (styler[j] == '\'') && isLineEnd(styler.SafeGetCharAt(j + 1))) { isValidSimpleString = true; j++; break; } else { phpStringDelimiter[0] = '\0'; return beginning; } } if (j - i < phpStringDelimiterSize - 2) phpStringDelimiter[j-i+1] = styler[j]; else i++; } if (isSimpleString && !isValidSimpleString) { phpStringDelimiter[0] = '\0'; return beginning; } phpStringDelimiter[j-i+1 - (isSimpleString ? 1 : 0)] = '\0'; return j - 1; } static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler, bool isXml) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; WordList &keywords5 = *keywordlists[4]; WordList &keywords6 = *keywordlists[5]; // SGML (DTD) keywords // Lexer for HTML requires more lexical states (8 bits worth) than most lexers styler.StartAt(startPos, static_cast<char>(STYLE_MAX)); char prevWord[200]; prevWord[0] = '\0'; char phpStringDelimiter[200]; // PHP is not limited in length, we are phpStringDelimiter[0] = '\0'; int StateToPrint = initStyle; int state = stateForPrintState(StateToPrint); char makoBlockType[200]; makoBlockType[0] = '\0'; int makoComment = 0; char djangoBlockType[2]; djangoBlockType[0] = '\0'; // If inside a tag, it may be a script tag, so reread from the start of line starting tag to ensure any language tags are seen if (InTagState(state)) { while ((startPos > 0) && (InTagState(styler.StyleAt(startPos - 1)))) { int backLineStart = styler.LineStart(styler.GetLine(startPos-1)); length += startPos - backLineStart; startPos = backLineStart; } state = SCE_H_DEFAULT; } // String can be heredoc, must find a delimiter first. Reread from beginning of line containing the string, to get the correct lineState if (isPHPStringState(state)) { while (startPos > 0 && (isPHPStringState(state) || !isLineEnd(styler[startPos - 1]))) { startPos--; length++; state = styler.StyleAt(startPos); } if (startPos == 0) state = SCE_H_DEFAULT; } styler.StartAt(startPos, static_cast<char>(STYLE_MAX)); int lineCurrent = styler.GetLine(startPos); int lineState; if (lineCurrent > 0) { lineState = styler.GetLineState(lineCurrent-1); } else { // Default client and ASP scripting language is JavaScript lineState = eScriptJS << 8; // property asp.default.language // Script in ASP code is initially assumed to be in JavaScript. // To change this to VBScript set asp.default.language to 2. Python is 3. lineState |= styler.GetPropertyInt("asp.default.language", eScriptJS) << 4; } script_mode inScriptType = script_mode((lineState >> 0) & 0x03); // 2 bits of scripting mode bool tagOpened = (lineState >> 2) & 0x01; // 1 bit to know if we are in an opened tag bool tagClosing = (lineState >> 3) & 0x01; // 1 bit to know if we are in a closing tag bool tagDontFold = false; //some HTML tags should not be folded script_type aspScript = script_type((lineState >> 4) & 0x0F); // 4 bits of script name script_type clientScript = script_type((lineState >> 8) & 0x0F); // 4 bits of script name int beforePreProc = (lineState >> 12) & 0xFF; // 8 bits of state script_type scriptLanguage = ScriptOfState(state); // If eNonHtmlScript coincides with SCE_H_COMMENT, assume eScriptComment if (inScriptType == eNonHtmlScript && state == SCE_H_COMMENT) { scriptLanguage = eScriptComment; } script_type beforeLanguage = ScriptOfState(beforePreProc); // property fold.html // Folding is turned on or off for HTML and XML files with this option. // The fold option must also be on for folding to occur. const bool foldHTML = styler.GetPropertyInt("fold.html", 0) != 0; const bool fold = foldHTML && styler.GetPropertyInt("fold", 0); // property fold.html.preprocessor // Folding is turned on or off for scripts embedded in HTML files with this option. // The default is on. const bool foldHTMLPreprocessor = foldHTML && styler.GetPropertyInt("fold.html.preprocessor", 1); const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; // property fold.hypertext.comment // Allow folding for comments in scripts embedded in HTML. // The default is off. const bool foldComment = fold && styler.GetPropertyInt("fold.hypertext.comment", 0) != 0; // property fold.hypertext.heredoc // Allow folding for heredocs in scripts embedded in HTML. // The default is off. const bool foldHeredoc = fold && styler.GetPropertyInt("fold.hypertext.heredoc", 0) != 0; // property html.tags.case.sensitive // For XML and HTML, setting this property to 1 will make tags match in a case // sensitive way which is the expected behaviour for XML and XHTML. const bool caseSensitive = styler.GetPropertyInt("html.tags.case.sensitive", 0) != 0; // property lexer.xml.allow.scripts // Set to 0 to disable scripts in XML. const bool allowScripts = styler.GetPropertyInt("lexer.xml.allow.scripts", 1) != 0; // property lexer.html.mako // Set to 1 to enable the mako template language. const bool isMako = styler.GetPropertyInt("lexer.html.mako", 0) != 0; // property lexer.html.django // Set to 1 to enable the django template language. const bool isDjango = styler.GetPropertyInt("lexer.html.django", 0) != 0; const CharacterSet setHTMLWord(CharacterSet::setAlphaNum, ".-_:!#", 0x80, true); const CharacterSet setTagContinue(CharacterSet::setAlphaNum, ".-_:!#[", 0x80, true); const CharacterSet setAttributeContinue(CharacterSet::setAlphaNum, ".-_:!#/", 0x80, true); // TODO: also handle + and - (except if they're part of ++ or --) and return keywords const CharacterSet setOKBeforeJSRE(CharacterSet::setNone, "([{=,:;!%^&*|?~"); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; int visibleChars = 0; int lineStartVisibleChars = 0; int chPrev = ' '; int ch = ' '; int chPrevNonWhite = ' '; // look back to set chPrevNonWhite properly for better regex colouring if (scriptLanguage == eScriptJS && startPos > 0) { int back = startPos; int style = 0; while (--back) { style = styler.StyleAt(back); if (style < SCE_HJ_DEFAULT || style > SCE_HJ_COMMENTDOC) // includes SCE_HJ_COMMENT & SCE_HJ_COMMENTLINE break; } if (style == SCE_HJ_SYMBOLS) { chPrevNonWhite = static_cast<unsigned char>(styler.SafeGetCharAt(back)); } } styler.StartSegment(startPos); const int lengthDoc = startPos + length; for (int i = startPos; i < lengthDoc; i++) { const int chPrev2 = chPrev; chPrev = ch; if (!IsASpace(ch) && state != SCE_HJ_COMMENT && state != SCE_HJ_COMMENTLINE && state != SCE_HJ_COMMENTDOC) chPrevNonWhite = ch; ch = static_cast<unsigned char>(styler[i]); int chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1)); const int chNext2 = static_cast<unsigned char>(styler.SafeGetCharAt(i + 2)); // Handle DBCS codepages if (styler.IsLeadByte(static_cast<char>(ch))) { chPrev = ' '; i += 1; continue; } if ((!IsASpace(ch) || !foldCompact) && fold) visibleChars++; if (!IsASpace(ch)) lineStartVisibleChars++; // decide what is the current state to print (depending of the script tag) StateToPrint = statePrintForState(state, inScriptType); // handle script folding if (fold) { switch (scriptLanguage) { case eScriptJS: case eScriptPHP: //not currently supported case eScriptVBS: if ((state != SCE_HPHP_COMMENT) && (state != SCE_HPHP_COMMENTLINE) && (state != SCE_HJ_COMMENT) && (state != SCE_HJ_COMMENTLINE) && (state != SCE_HJ_COMMENTDOC) && (!isStringState(state))) { //Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle); //if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) { if (ch == '#') { int j = i + 1; while ((j < lengthDoc) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { j++; } if (styler.Match(j, "region") || styler.Match(j, "if")) { levelCurrent++; } else if (styler.Match(j, "end")) { levelCurrent--; } } else if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*'))) { levelCurrent += (((ch == '{') || (ch == '/')) ? 1 : -1); } } else if (((state == SCE_HPHP_COMMENT) || (state == SCE_HJ_COMMENT)) && foldComment && (ch == '*') && (chNext == '/')) { levelCurrent--; } break; case eScriptPython: if (state != SCE_HP_COMMENTLINE && !isMako) { if ((ch == ':') && ((chNext == '\n') || (chNext == '\r' && chNext2 == '\n'))) { levelCurrent++; } else if ((ch == '\n') && !((chNext == '\r') && (chNext2 == '\n')) && (chNext != '\n')) { // check if the number of tabs is lower than the level int Findlevel = (levelCurrent & ~SC_FOLDLEVELBASE) * 8; for (int j = 0; Findlevel > 0; j++) { char chTmp = styler.SafeGetCharAt(i + j + 1); if (chTmp == '\t') { Findlevel -= 8; } else if (chTmp == ' ') { Findlevel--; } else { break; } } if (Findlevel > 0) { levelCurrent -= Findlevel / 8; if (Findlevel % 8) levelCurrent--; } } } break; default: break; } } if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) // Avoid triggering two times on Dos/Win // New line -> record any line state onto /next/ line if (fold) { int lev = levelPrev; if (visibleChars == 0) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; styler.SetLevel(lineCurrent, lev); visibleChars = 0; levelPrev = levelCurrent; } styler.SetLineState(lineCurrent, ((inScriptType & 0x03) << 0) | ((tagOpened & 0x01) << 2) | ((tagClosing & 0x01) << 3) | ((aspScript & 0x0F) << 4) | ((clientScript & 0x0F) << 8) | ((beforePreProc & 0xFF) << 12)); lineCurrent++; lineStartVisibleChars = 0; } // handle start of Mako comment line if (isMako && ch == '#' && chNext == '#') { makoComment = 1; } // handle end of Mako comment line else if (isMako && makoComment && (ch == '\r' || ch == '\n')) { makoComment = 0; styler.ColourTo(i, SCE_HP_COMMENTLINE); state = SCE_HP_DEFAULT; } // Allow falling through to mako handling code if newline is going to end a block if (((ch == '\r' && chNext != '\n') || (ch == '\n')) && (!isMako || (0 != strcmp(makoBlockType, "%")))) { } // generic end of script processing else if ((inScriptType == eNonHtmlScript) && (ch == '<') && (chNext == '/')) { // Check if it's the end of the script tag (or any other HTML tag) switch (state) { // in these cases, you can embed HTML tags (to confirm !!!!!!!!!!!!!!!!!!!!!!) case SCE_H_DOUBLESTRING: case SCE_H_SINGLESTRING: case SCE_HJ_COMMENT: case SCE_HJ_COMMENTDOC: //case SCE_HJ_COMMENTLINE: // removed as this is a common thing done to hide // the end of script marker from some JS interpreters. case SCE_HB_COMMENTLINE: case SCE_HBA_COMMENTLINE: case SCE_HJ_DOUBLESTRING: case SCE_HJ_SINGLESTRING: case SCE_HJ_REGEX: case SCE_HB_STRING: case SCE_HBA_STRING: case SCE_HP_STRING: case SCE_HP_TRIPLE: case SCE_HP_TRIPLEDOUBLE: case SCE_HPHP_HSTRING: case SCE_HPHP_SIMPLESTRING: case SCE_HPHP_COMMENT: case SCE_HPHP_COMMENTLINE: break; default : // check if the closing tag is a script tag if (const char *tag = state == SCE_HJ_COMMENTLINE || isXml ? "script" : state == SCE_H_COMMENT ? "comment" : 0) { int j = i + 2; int chr; do { chr = static_cast<int>(*tag++); } while (chr != 0 && chr == MakeLowerCase(styler.SafeGetCharAt(j++))); if (chr != 0) break; } // closing tag of the script (it's a closing HTML tag anyway) styler.ColourTo(i - 1, StateToPrint); state = SCE_H_TAGUNKNOWN; inScriptType = eHtml; scriptLanguage = eScriptNone; clientScript = eScriptJS; i += 2; visibleChars += 2; tagClosing = true; continue; } } ///////////////////////////////////// // handle the start of PHP pre-processor = Non-HTML else if ((state != SCE_H_ASPAT) && !isPHPStringState(state) && (state != SCE_HPHP_COMMENT) && (state != SCE_HPHP_COMMENTLINE) && (ch == '<') && (chNext == '?') && !IsScriptCommentState(state)) { beforeLanguage = scriptLanguage; scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, isXml ? eScriptXML : eScriptPHP); if ((scriptLanguage != eScriptPHP) && (isStringState(state) || (state==SCE_H_COMMENT))) continue; styler.ColourTo(i - 1, StateToPrint); beforePreProc = state; i++; visibleChars++; i += PrintScriptingIndicatorOffset(styler, styler.GetStartSegment() + 2, i + 6); if (scriptLanguage == eScriptXML) styler.ColourTo(i, SCE_H_XMLSTART); else styler.ColourTo(i, SCE_H_QUESTION); state = StateForScript(scriptLanguage); if (inScriptType == eNonHtmlScript) inScriptType = eNonHtmlScriptPreProc; else inScriptType = eNonHtmlPreProc; // Fold whole script, but not if the XML first tag (all XML-like tags in this case) if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) { levelCurrent++; } // should be better ch = static_cast<unsigned char>(styler.SafeGetCharAt(i)); continue; } // handle the start Mako template Python code else if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') || (lineStartVisibleChars == 1 && ch == '%') || (lineStartVisibleChars == 1 && ch == '/' && chNext == '%') || (ch == '$' && chNext == '{') || (ch == '<' && chNext == '/' && chNext2 == '%'))) { if (ch == '%' || ch == '/') strcpy(makoBlockType, "%"); else if (ch == '$') strcpy(makoBlockType, "{"); else if (chNext == '/') GetNextWord(styler, i+3, makoBlockType, sizeof(makoBlockType)); else GetNextWord(styler, i+2, makoBlockType, sizeof(makoBlockType)); styler.ColourTo(i - 1, StateToPrint); beforePreProc = state; if (inScriptType == eNonHtmlScript) inScriptType = eNonHtmlScriptPreProc; else inScriptType = eNonHtmlPreProc; if (chNext == '/') { i += 2; visibleChars += 2; } else if (ch != '%') { i++; visibleChars++; } state = SCE_HP_START; scriptLanguage = eScriptPython; styler.ColourTo(i, SCE_H_ASP); if (ch != '%' && ch != '$' && ch != '/') { i += static_cast<int>(strlen(makoBlockType)); visibleChars += static_cast<int>(strlen(makoBlockType)); if (keywords4.InList(makoBlockType)) styler.ColourTo(i, SCE_HP_WORD); else styler.ColourTo(i, SCE_H_TAGUNKNOWN); } ch = static_cast<unsigned char>(styler.SafeGetCharAt(i)); continue; } // handle the start/end of Django comment else if (isDjango && state != SCE_H_COMMENT && (ch == '{' && chNext == '#')) { styler.ColourTo(i - 1, StateToPrint); beforePreProc = state; beforeLanguage = scriptLanguage; if (inScriptType == eNonHtmlScript) inScriptType = eNonHtmlScriptPreProc; else inScriptType = eNonHtmlPreProc; i += 1; visibleChars += 1; scriptLanguage = eScriptComment; state = SCE_H_COMMENT; styler.ColourTo(i, SCE_H_ASP); ch = static_cast<unsigned char>(styler.SafeGetCharAt(i)); continue; } else if (isDjango && state == SCE_H_COMMENT && (ch == '#' && chNext == '}')) { styler.ColourTo(i - 1, StateToPrint); i += 1; visibleChars += 1; styler.ColourTo(i, SCE_H_ASP); state = beforePreProc; if (inScriptType == eNonHtmlScriptPreProc) inScriptType = eNonHtmlScript; else inScriptType = eHtml; scriptLanguage = beforeLanguage; continue; } // handle the start Django template code else if (isDjango && scriptLanguage != eScriptPython && (ch == '{' && (chNext == '%' || chNext == '{'))) { if (chNext == '%') strcpy(djangoBlockType, "%"); else strcpy(djangoBlockType, "{"); styler.ColourTo(i - 1, StateToPrint); beforePreProc = state; if (inScriptType == eNonHtmlScript) inScriptType = eNonHtmlScriptPreProc; else inScriptType = eNonHtmlPreProc; i += 1; visibleChars += 1; state = SCE_HP_START; beforeLanguage = scriptLanguage; scriptLanguage = eScriptPython; styler.ColourTo(i, SCE_H_ASP); ch = static_cast<unsigned char>(styler.SafeGetCharAt(i)); continue; } // handle the start of ASP pre-processor = Non-HTML else if (!isMako && !isDjango && !isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) { styler.ColourTo(i - 1, StateToPrint); beforePreProc = state; if (inScriptType == eNonHtmlScript) inScriptType = eNonHtmlScriptPreProc; else inScriptType = eNonHtmlPreProc; if (chNext2 == '@') { i += 2; // place as if it was the second next char treated visibleChars += 2; state = SCE_H_ASPAT; } else if ((chNext2 == '-') && (styler.SafeGetCharAt(i + 3) == '-')) { styler.ColourTo(i + 3, SCE_H_ASP); state = SCE_H_XCCOMMENT; scriptLanguage = eScriptVBS; continue; } else { if (chNext2 == '=') { i += 2; // place as if it was the second next char treated visibleChars += 2; } else { i++; // place as if it was the next char treated visibleChars++; } state = StateForScript(aspScript); } scriptLanguage = eScriptVBS; styler.ColourTo(i, SCE_H_ASP); // fold whole script if (foldHTMLPreprocessor) levelCurrent++; // should be better ch = static_cast<unsigned char>(styler.SafeGetCharAt(i)); continue; } ///////////////////////////////////// // handle the start of SGML language (DTD) else if (((scriptLanguage == eScriptNone) || (scriptLanguage == eScriptXML)) && (chPrev == '<') && (ch == '!') && (StateToPrint != SCE_H_CDATA) && (!IsCommentState(StateToPrint)) && (!IsScriptCommentState(StateToPrint))) { beforePreProc = state; styler.ColourTo(i - 2, StateToPrint); if ((chNext == '-') && (chNext2 == '-')) { state = SCE_H_COMMENT; // wait for a pending command styler.ColourTo(i + 2, SCE_H_COMMENT); i += 2; // follow styling after the -- } else if (isWordCdata(i + 1, i + 7, styler)) { state = SCE_H_CDATA; } else { styler.ColourTo(i, SCE_H_SGML_DEFAULT); // <! is default scriptLanguage = eScriptSGML; state = SCE_H_SGML_COMMAND; // wait for a pending command } // fold whole tag (-- when closing the tag) if (foldHTMLPreprocessor || state == SCE_H_COMMENT || state == SCE_H_CDATA) levelCurrent++; continue; } // handle the end of Mako Python code else if (isMako && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) && (scriptLanguage != eScriptNone) && stateAllowsTermination(state) && isMakoBlockEnd(ch, chNext, makoBlockType)) { if (state == SCE_H_ASPAT) { aspScript = segIsScriptingIndicator(styler, styler.GetStartSegment(), i - 1, aspScript); } if (state == SCE_HP_WORD) { classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako); } else { styler.ColourTo(i - 1, StateToPrint); } if (0 != strcmp(makoBlockType, "%") && (0 != strcmp(makoBlockType, "{")) && ch != '>') { i++; visibleChars++; } else if (0 == strcmp(makoBlockType, "%") && ch == '/') { i++; visibleChars++; } if (0 != strcmp(makoBlockType, "%") || ch == '/') { styler.ColourTo(i, SCE_H_ASP); } state = beforePreProc; if (inScriptType == eNonHtmlScriptPreProc) inScriptType = eNonHtmlScript; else inScriptType = eHtml; scriptLanguage = eScriptNone; continue; } // handle the end of Django template code else if (isDjango && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) && (scriptLanguage != eScriptNone) && stateAllowsTermination(state) && isDjangoBlockEnd(ch, chNext, djangoBlockType)) { if (state == SCE_H_ASPAT) { aspScript = segIsScriptingIndicator(styler, styler.GetStartSegment(), i - 1, aspScript); } if (state == SCE_HP_WORD) { classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako); } else { styler.ColourTo(i - 1, StateToPrint); } i += 1; visibleChars += 1; styler.ColourTo(i, SCE_H_ASP); state = beforePreProc; if (inScriptType == eNonHtmlScriptPreProc) inScriptType = eNonHtmlScript; else inScriptType = eHtml; scriptLanguage = beforeLanguage; continue; } // handle the end of a pre-processor = Non-HTML else if ((!isMako && !isDjango && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) && (((scriptLanguage != eScriptNone) && stateAllowsTermination(state))) && (((ch == '%') || (ch == '?')) && (chNext == '>'))) || ((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) { if (state == SCE_H_ASPAT) { aspScript = segIsScriptingIndicator(styler, styler.GetStartSegment(), i - 1, aspScript); } // Bounce out of any ASP mode switch (state) { case SCE_HJ_WORD: classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler, inScriptType); break; case SCE_HB_WORD: classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType); break; case SCE_HP_WORD: classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako); break; case SCE_HPHP_WORD: classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler); break; case SCE_H_XCCOMMENT: styler.ColourTo(i - 1, state); break; default : styler.ColourTo(i - 1, StateToPrint); break; } if (scriptLanguage != eScriptSGML) { i++; visibleChars++; } if (ch == '%') styler.ColourTo(i, SCE_H_ASP); else if (scriptLanguage == eScriptXML) styler.ColourTo(i, SCE_H_XMLEND); else if (scriptLanguage == eScriptSGML) styler.ColourTo(i, SCE_H_SGML_DEFAULT); else styler.ColourTo(i, SCE_H_QUESTION); state = beforePreProc; if (inScriptType == eNonHtmlScriptPreProc) inScriptType = eNonHtmlScript; else inScriptType = eHtml; // Unfold all scripting languages, except for XML tag if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) { levelCurrent--; } scriptLanguage = beforeLanguage; continue; } ///////////////////////////////////// switch (state) { case SCE_H_DEFAULT: if (ch == '<') { // in HTML, fold on tag open and unfold on tag close tagOpened = true; tagClosing = (chNext == '/'); styler.ColourTo(i - 1, StateToPrint); if (chNext != '!') state = SCE_H_TAGUNKNOWN; } else if (ch == '&') { styler.ColourTo(i - 1, SCE_H_DEFAULT); state = SCE_H_ENTITY; } break; case SCE_H_SGML_DEFAULT: case SCE_H_SGML_BLOCK_DEFAULT: // if (scriptLanguage == eScriptSGMLblock) // StateToPrint = SCE_H_SGML_BLOCK_DEFAULT; if (ch == '\"') { styler.ColourTo(i - 1, StateToPrint); state = SCE_H_SGML_DOUBLESTRING; } else if (ch == '\'') { styler.ColourTo(i - 1, StateToPrint); state = SCE_H_SGML_SIMPLESTRING; } else if ((ch == '-') && (chPrev == '-')) { if (static_cast<int>(styler.GetStartSegment()) <= (i - 2)) { styler.ColourTo(i - 2, StateToPrint); } state = SCE_H_SGML_COMMENT; } else if (isascii(ch) && isalpha(ch) && (chPrev == '%')) { styler.ColourTo(i - 2, StateToPrint); state = SCE_H_SGML_ENTITY; } else if (ch == '#') { styler.ColourTo(i - 1, StateToPrint); state = SCE_H_SGML_SPECIAL; } else if (ch == '[') { styler.ColourTo(i - 1, StateToPrint); scriptLanguage = eScriptSGMLblock; state = SCE_H_SGML_BLOCK_DEFAULT; } else if (ch == ']') { if (scriptLanguage == eScriptSGMLblock) { styler.ColourTo(i, StateToPrint); scriptLanguage = eScriptSGML; } else { styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i, SCE_H_SGML_ERROR); } state = SCE_H_SGML_DEFAULT; } else if (scriptLanguage == eScriptSGMLblock) { if ((ch == '!') && (chPrev == '<')) { styler.ColourTo(i - 2, StateToPrint); styler.ColourTo(i, SCE_H_SGML_DEFAULT); state = SCE_H_SGML_COMMAND; } else if (ch == '>') { styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i, SCE_H_SGML_DEFAULT); } } break; case SCE_H_SGML_COMMAND: if ((ch == '-') && (chPrev == '-')) { styler.ColourTo(i - 2, StateToPrint); state = SCE_H_SGML_COMMENT; } else if (!issgmlwordchar(ch)) { if (isWordHSGML(styler.GetStartSegment(), i - 1, keywords6, styler)) { styler.ColourTo(i - 1, StateToPrint); state = SCE_H_SGML_1ST_PARAM; } else { state = SCE_H_SGML_ERROR; } } break; case SCE_H_SGML_1ST_PARAM: // wait for the beginning of the word if ((ch == '-') && (chPrev == '-')) { if (scriptLanguage == eScriptSGMLblock) { styler.ColourTo(i - 2, SCE_H_SGML_BLOCK_DEFAULT); } else { styler.ColourTo(i - 2, SCE_H_SGML_DEFAULT); } state = SCE_H_SGML_1ST_PARAM_COMMENT; } else if (issgmlwordchar(ch)) { if (scriptLanguage == eScriptSGMLblock) { styler.ColourTo(i - 1, SCE_H_SGML_BLOCK_DEFAULT); } else { styler.ColourTo(i - 1, SCE_H_SGML_DEFAULT); } // find the length of the word int size = 1; while (setHTMLWord.Contains(static_cast<unsigned char>(styler.SafeGetCharAt(i + size)))) size++; styler.ColourTo(i + size - 1, StateToPrint); i += size - 1; visibleChars += size - 1; ch = static_cast<unsigned char>(styler.SafeGetCharAt(i)); if (scriptLanguage == eScriptSGMLblock) { state = SCE_H_SGML_BLOCK_DEFAULT; } else { state = SCE_H_SGML_DEFAULT; } continue; } break; case SCE_H_SGML_ERROR: if ((ch == '-') && (chPrev == '-')) { styler.ColourTo(i - 2, StateToPrint); state = SCE_H_SGML_COMMENT; } case SCE_H_SGML_DOUBLESTRING: if (ch == '\"') { styler.ColourTo(i, StateToPrint); state = SCE_H_SGML_DEFAULT; } break; case SCE_H_SGML_SIMPLESTRING: if (ch == '\'') { styler.ColourTo(i, StateToPrint); state = SCE_H_SGML_DEFAULT; } break; case SCE_H_SGML_COMMENT: if ((ch == '-') && (chPrev == '-')) { styler.ColourTo(i, StateToPrint); state = SCE_H_SGML_DEFAULT; } break; case SCE_H_CDATA: if ((chPrev2 == ']') && (chPrev == ']') && (ch == '>')) { styler.ColourTo(i, StateToPrint); state = SCE_H_DEFAULT; levelCurrent--; } break; case SCE_H_COMMENT: if ((scriptLanguage != eScriptComment) && (chPrev2 == '-') && (chPrev == '-') && (ch == '>')) { styler.ColourTo(i, StateToPrint); state = SCE_H_DEFAULT; levelCurrent--; } break; case SCE_H_SGML_1ST_PARAM_COMMENT: if ((ch == '-') && (chPrev == '-')) { styler.ColourTo(i, SCE_H_SGML_COMMENT); state = SCE_H_SGML_1ST_PARAM; } break; case SCE_H_SGML_SPECIAL: if (!(isascii(ch) && isupper(ch))) { styler.ColourTo(i - 1, StateToPrint); if (isalnum(ch)) { state = SCE_H_SGML_ERROR; } else { state = SCE_H_SGML_DEFAULT; } } break; case SCE_H_SGML_ENTITY: if (ch == ';') { styler.ColourTo(i, StateToPrint); state = SCE_H_SGML_DEFAULT; } else if (!(isascii(ch) && isalnum(ch)) && ch != '-' && ch != '.') { styler.ColourTo(i, SCE_H_SGML_ERROR); state = SCE_H_SGML_DEFAULT; } break; case SCE_H_ENTITY: if (ch == ';') { styler.ColourTo(i, StateToPrint); state = SCE_H_DEFAULT; } if (ch != '#' && !(isascii(ch) && isalnum(ch)) // Should check that '#' follows '&', but it is unlikely anyway... && ch != '.' && ch != '-' && ch != '_' && ch != ':') { // valid in XML if (!isascii(ch)) // Possibly start of a multibyte character so don't allow this byte to be in entity style styler.ColourTo(i-1, SCE_H_TAGUNKNOWN); else styler.ColourTo(i, SCE_H_TAGUNKNOWN); state = SCE_H_DEFAULT; } break; case SCE_H_TAGUNKNOWN: if (!setTagContinue.Contains(ch) && !((ch == '/') && (chPrev == '<'))) { int eClass = classifyTagHTML(styler.GetStartSegment(), i - 1, keywords, styler, tagDontFold, caseSensitive, isXml, allowScripts); if (eClass == SCE_H_SCRIPT || eClass == SCE_H_COMMENT) { if (!tagClosing) { inScriptType = eNonHtmlScript; scriptLanguage = eClass == SCE_H_SCRIPT ? clientScript : eScriptComment; } else { scriptLanguage = eScriptNone; } eClass = SCE_H_TAG; } if (ch == '>') { styler.ColourTo(i, eClass); if (inScriptType == eNonHtmlScript) { state = StateForScript(scriptLanguage); } else { state = SCE_H_DEFAULT; } tagOpened = false; if (!tagDontFold) { if (tagClosing) { levelCurrent--; } else { levelCurrent++; } } tagClosing = false; } else if (ch == '/' && chNext == '>') { if (eClass == SCE_H_TAGUNKNOWN) { styler.ColourTo(i + 1, SCE_H_TAGUNKNOWN); } else { styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i + 1, SCE_H_TAGEND); } i++; ch = chNext; state = SCE_H_DEFAULT; tagOpened = false; } else { if (eClass != SCE_H_TAGUNKNOWN) { if (eClass == SCE_H_SGML_DEFAULT) { state = SCE_H_SGML_DEFAULT; } else { state = SCE_H_OTHER; } } } } break; case SCE_H_ATTRIBUTE: if (!setAttributeContinue.Contains(ch)) { if (inScriptType == eNonHtmlScript) { int scriptLanguagePrev = scriptLanguage; clientScript = segIsScriptingIndicator(styler, styler.GetStartSegment(), i - 1, scriptLanguage); scriptLanguage = clientScript; if ((scriptLanguagePrev != scriptLanguage) && (scriptLanguage == eScriptNone)) inScriptType = eHtml; } classifyAttribHTML(styler.GetStartSegment(), i - 1, keywords, styler); if (ch == '>') { styler.ColourTo(i, SCE_H_TAG); if (inScriptType == eNonHtmlScript) { state = StateForScript(scriptLanguage); } else { state = SCE_H_DEFAULT; } tagOpened = false; if (!tagDontFold) { if (tagClosing) { levelCurrent--; } else { levelCurrent++; } } tagClosing = false; } else if (ch == '=') { styler.ColourTo(i, SCE_H_OTHER); state = SCE_H_VALUE; } else { state = SCE_H_OTHER; } } break; case SCE_H_OTHER: if (ch == '>') { styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i, SCE_H_TAG); if (inScriptType == eNonHtmlScript) { state = StateForScript(scriptLanguage); } else { state = SCE_H_DEFAULT; } tagOpened = false; if (!tagDontFold) { if (tagClosing) { levelCurrent--; } else { levelCurrent++; } } tagClosing = false; } else if (ch == '\"') { styler.ColourTo(i - 1, StateToPrint); state = SCE_H_DOUBLESTRING; } else if (ch == '\'') { styler.ColourTo(i - 1, StateToPrint); state = SCE_H_SINGLESTRING; } else if (ch == '=') { styler.ColourTo(i, StateToPrint); state = SCE_H_VALUE; } else if (ch == '/' && chNext == '>') { styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i + 1, SCE_H_TAGEND); i++; ch = chNext; state = SCE_H_DEFAULT; tagOpened = false; } else if (ch == '?' && chNext == '>') { styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i + 1, SCE_H_XMLEND); i++; ch = chNext; state = SCE_H_DEFAULT; } else if (setHTMLWord.Contains(ch)) { styler.ColourTo(i - 1, StateToPrint); state = SCE_H_ATTRIBUTE; } break; case SCE_H_DOUBLESTRING: if (ch == '\"') { if (inScriptType == eNonHtmlScript) { scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage); } styler.ColourTo(i, SCE_H_DOUBLESTRING); state = SCE_H_OTHER; } break; case SCE_H_SINGLESTRING: if (ch == '\'') { if (inScriptType == eNonHtmlScript) { scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage); } styler.ColourTo(i, SCE_H_SINGLESTRING); state = SCE_H_OTHER; } break; case SCE_H_VALUE: if (!setHTMLWord.Contains(ch)) { if (ch == '\"' && chPrev == '=') { // Should really test for being first character state = SCE_H_DOUBLESTRING; } else if (ch == '\'' && chPrev == '=') { state = SCE_H_SINGLESTRING; } else { if (IsNumber(styler.GetStartSegment(), styler)) { styler.ColourTo(i - 1, SCE_H_NUMBER); } else { styler.ColourTo(i - 1, StateToPrint); } if (ch == '>') { styler.ColourTo(i, SCE_H_TAG); if (inScriptType == eNonHtmlScript) { state = StateForScript(scriptLanguage); } else { state = SCE_H_DEFAULT; } tagOpened = false; if (!tagDontFold) { if (tagClosing) { levelCurrent--; } else { levelCurrent++; } } tagClosing = false; } else { state = SCE_H_OTHER; } } } break; case SCE_HJ_DEFAULT: case SCE_HJ_START: case SCE_HJ_SYMBOLS: if (IsAWordStart(ch)) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_WORD; } else if (ch == '/' && chNext == '*') { styler.ColourTo(i - 1, StateToPrint); if (chNext2 == '*') state = SCE_HJ_COMMENTDOC; else state = SCE_HJ_COMMENT; if (chNext2 == '/') { // Eat the * so it isn't used for the end of the comment i++; } } else if (ch == '/' && chNext == '/') { styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_COMMENTLINE; } else if (ch == '/' && setOKBeforeJSRE.Contains(chPrevNonWhite)) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_REGEX; } else if (ch == '\"') { styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_DOUBLESTRING; } else if (ch == '\'') { styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_SINGLESTRING; } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && styler.SafeGetCharAt(i + 3) == '-') { styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_COMMENTLINE; } else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_COMMENTLINE; i += 2; } else if (IsOperator(ch)) { styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType)); state = SCE_HJ_DEFAULT; } else if ((ch == ' ') || (ch == '\t')) { if (state == SCE_HJ_START) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_DEFAULT; } } break; case SCE_HJ_WORD: if (!IsAWordChar(ch)) { classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler, inScriptType); //styler.ColourTo(i - 1, eHTJSKeyword); state = SCE_HJ_DEFAULT; if (ch == '/' && chNext == '*') { if (chNext2 == '*') state = SCE_HJ_COMMENTDOC; else state = SCE_HJ_COMMENT; } else if (ch == '/' && chNext == '/') { state = SCE_HJ_COMMENTLINE; } else if (ch == '\"') { state = SCE_HJ_DOUBLESTRING; } else if (ch == '\'') { state = SCE_HJ_SINGLESTRING; } else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_COMMENTLINE; i += 2; } else if (IsOperator(ch)) { styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType)); state = SCE_HJ_DEFAULT; } } break; case SCE_HJ_COMMENT: case SCE_HJ_COMMENTDOC: if (ch == '/' && chPrev == '*') { styler.ColourTo(i, StateToPrint); state = SCE_HJ_DEFAULT; ch = ' '; } break; case SCE_HJ_COMMENTLINE: if (ch == '\r' || ch == '\n') { styler.ColourTo(i - 1, statePrintForState(SCE_HJ_COMMENTLINE, inScriptType)); state = SCE_HJ_DEFAULT; ch = ' '; } break; case SCE_HJ_DOUBLESTRING: if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; } } else if (ch == '\"') { styler.ColourTo(i, statePrintForState(SCE_HJ_DOUBLESTRING, inScriptType)); state = SCE_HJ_DEFAULT; } else if ((inScriptType == eNonHtmlScript) && (ch == '-') && (chNext == '-') && (chNext2 == '>')) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_COMMENTLINE; i += 2; } else if (isLineEnd(ch)) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_STRINGEOL; } break; case SCE_HJ_SINGLESTRING: if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; } } else if (ch == '\'') { styler.ColourTo(i, statePrintForState(SCE_HJ_SINGLESTRING, inScriptType)); state = SCE_HJ_DEFAULT; } else if ((inScriptType == eNonHtmlScript) && (ch == '-') && (chNext == '-') && (chNext2 == '>')) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_COMMENTLINE; i += 2; } else if (isLineEnd(ch)) { styler.ColourTo(i - 1, StateToPrint); if (chPrev != '\\' && (chPrev2 != '\\' || chPrev != '\r' || ch != '\n')) { state = SCE_HJ_STRINGEOL; } } break; case SCE_HJ_STRINGEOL: if (!isLineEnd(ch)) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HJ_DEFAULT; } else if (!isLineEnd(chNext)) { styler.ColourTo(i, StateToPrint); state = SCE_HJ_DEFAULT; } break; case SCE_HJ_REGEX: if (ch == '\r' || ch == '\n' || ch == '/') { if (ch == '/') { while (isascii(chNext) && islower(chNext)) { // gobble regex flags i++; ch = chNext; chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1)); } } styler.ColourTo(i, StateToPrint); state = SCE_HJ_DEFAULT; } else if (ch == '\\') { // Gobble up the quoted character if (chNext == '\\' || chNext == '/') { i++; ch = chNext; chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1)); } } break; case SCE_HB_DEFAULT: case SCE_HB_START: if (IsAWordStart(ch)) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_WORD; } else if (ch == '\'') { styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_COMMENTLINE; } else if (ch == '\"') { styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_STRING; } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && styler.SafeGetCharAt(i + 3) == '-') { styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_COMMENTLINE; } else if (IsOperator(ch)) { styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i, statePrintForState(SCE_HB_DEFAULT, inScriptType)); state = SCE_HB_DEFAULT; } else if ((ch == ' ') || (ch == '\t')) { if (state == SCE_HB_START) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_DEFAULT; } } break; case SCE_HB_WORD: if (!IsAWordChar(ch)) { state = classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType); if (state == SCE_HB_DEFAULT) { if (ch == '\"') { state = SCE_HB_STRING; } else if (ch == '\'') { state = SCE_HB_COMMENTLINE; } else if (IsOperator(ch)) { styler.ColourTo(i, statePrintForState(SCE_HB_DEFAULT, inScriptType)); state = SCE_HB_DEFAULT; } } } break; case SCE_HB_STRING: if (ch == '\"') { styler.ColourTo(i, StateToPrint); state = SCE_HB_DEFAULT; } else if (ch == '\r' || ch == '\n') { styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_STRINGEOL; } break; case SCE_HB_COMMENTLINE: if (ch == '\r' || ch == '\n') { styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_DEFAULT; } break; case SCE_HB_STRINGEOL: if (!isLineEnd(ch)) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HB_DEFAULT; } else if (!isLineEnd(chNext)) { styler.ColourTo(i, StateToPrint); state = SCE_HB_DEFAULT; } break; case SCE_HP_DEFAULT: case SCE_HP_START: if (IsAWordStart(ch)) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HP_WORD; } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && styler.SafeGetCharAt(i + 3) == '-') { styler.ColourTo(i - 1, StateToPrint); state = SCE_HP_COMMENTLINE; } else if (ch == '#') { styler.ColourTo(i - 1, StateToPrint); state = SCE_HP_COMMENTLINE; } else if (ch == '\"') { styler.ColourTo(i - 1, StateToPrint); if (chNext == '\"' && chNext2 == '\"') { i += 2; state = SCE_HP_TRIPLEDOUBLE; ch = ' '; chPrev = ' '; chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1)); } else { // state = statePrintForState(SCE_HP_STRING,inScriptType); state = SCE_HP_STRING; } } else if (ch == '\'') { styler.ColourTo(i - 1, StateToPrint); if (chNext == '\'' && chNext2 == '\'') { i += 2; state = SCE_HP_TRIPLE; ch = ' '; chPrev = ' '; chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1)); } else { state = SCE_HP_CHARACTER; } } else if (IsOperator(ch)) { styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType)); } else if ((ch == ' ') || (ch == '\t')) { if (state == SCE_HP_START) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HP_DEFAULT; } } break; case SCE_HP_WORD: if (!IsAWordChar(ch)) { classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako); state = SCE_HP_DEFAULT; if (ch == '#') { state = SCE_HP_COMMENTLINE; } else if (ch == '\"') { if (chNext == '\"' && chNext2 == '\"') { i += 2; state = SCE_HP_TRIPLEDOUBLE; ch = ' '; chPrev = ' '; chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1)); } else { state = SCE_HP_STRING; } } else if (ch == '\'') { if (chNext == '\'' && chNext2 == '\'') { i += 2; state = SCE_HP_TRIPLE; ch = ' '; chPrev = ' '; chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1)); } else { state = SCE_HP_CHARACTER; } } else if (IsOperator(ch)) { styler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType)); } } break; case SCE_HP_COMMENTLINE: if (ch == '\r' || ch == '\n') { styler.ColourTo(i - 1, StateToPrint); state = SCE_HP_DEFAULT; } break; case SCE_HP_STRING: if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; ch = chNext; chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1)); } } else if (ch == '\"') { styler.ColourTo(i, StateToPrint); state = SCE_HP_DEFAULT; } break; case SCE_HP_CHARACTER: if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; ch = chNext; chNext = static_cast<unsigned char>(styler.SafeGetCharAt(i + 1)); } } else if (ch == '\'') { styler.ColourTo(i, StateToPrint); state = SCE_HP_DEFAULT; } break; case SCE_HP_TRIPLE: if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') { styler.ColourTo(i, StateToPrint); state = SCE_HP_DEFAULT; } break; case SCE_HP_TRIPLEDOUBLE: if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') { styler.ColourTo(i, StateToPrint); state = SCE_HP_DEFAULT; } break; ///////////// start - PHP state handling case SCE_HPHP_WORD: if (!IsAWordChar(ch)) { classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler); if (ch == '/' && chNext == '*') { i++; state = SCE_HPHP_COMMENT; } else if (ch == '/' && chNext == '/') { i++; state = SCE_HPHP_COMMENTLINE; } else if (ch == '#') { state = SCE_HPHP_COMMENTLINE; } else if (ch == '\"') { state = SCE_HPHP_HSTRING; strcpy(phpStringDelimiter, "\""); } else if (styler.Match(i, "<<<")) { bool isSimpleString = false; i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString); if (strlen(phpStringDelimiter)) { state = (isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING); if (foldHeredoc) levelCurrent++; } } else if (ch == '\'') { state = SCE_HPHP_SIMPLESTRING; strcpy(phpStringDelimiter, "\'"); } else if (ch == '$' && IsPhpWordStart(chNext)) { state = SCE_HPHP_VARIABLE; } else if (IsOperator(ch)) { state = SCE_HPHP_OPERATOR; } else { state = SCE_HPHP_DEFAULT; } } break; case SCE_HPHP_NUMBER: // recognize bases 8,10 or 16 integers OR floating-point numbers if (!IsADigit(ch) && strchr(".xXabcdefABCDEF", ch) == NULL && ((ch != '-' && ch != '+') || (chPrev != 'e' && chPrev != 'E'))) { styler.ColourTo(i - 1, SCE_HPHP_NUMBER); if (IsOperator(ch)) state = SCE_HPHP_OPERATOR; else state = SCE_HPHP_DEFAULT; } break; case SCE_HPHP_VARIABLE: if (!IsPhpWordChar(chNext)) { styler.ColourTo(i, SCE_HPHP_VARIABLE); state = SCE_HPHP_DEFAULT; } break; case SCE_HPHP_COMMENT: if (ch == '/' && chPrev == '*') { styler.ColourTo(i, StateToPrint); state = SCE_HPHP_DEFAULT; } break; case SCE_HPHP_COMMENTLINE: if (ch == '\r' || ch == '\n') { styler.ColourTo(i - 1, StateToPrint); state = SCE_HPHP_DEFAULT; } break; case SCE_HPHP_HSTRING: if (ch == '\\' && (phpStringDelimiter[0] == '\"' || chNext == '$' || chNext == '{')) { // skip the next char i++; } else if (((ch == '{' && chNext == '$') || (ch == '$' && chNext == '{')) && IsPhpWordStart(chNext2)) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HPHP_COMPLEX_VARIABLE; } else if (ch == '$' && IsPhpWordStart(chNext)) { styler.ColourTo(i - 1, StateToPrint); state = SCE_HPHP_HSTRING_VARIABLE; } else if (styler.Match(i, phpStringDelimiter)) { if (phpStringDelimiter[0] == '\"') { styler.ColourTo(i, StateToPrint); state = SCE_HPHP_DEFAULT; } else if (isLineEnd(chPrev)) { const int psdLength = static_cast<int>(strlen(phpStringDelimiter)); const char chAfterPsd = styler.SafeGetCharAt(i + psdLength); const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1); if (isLineEnd(chAfterPsd) || (chAfterPsd == ';' && isLineEnd(chAfterPsd2))) { i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1; styler.ColourTo(i, StateToPrint); state = SCE_HPHP_DEFAULT; if (foldHeredoc) levelCurrent--; } } } break; case SCE_HPHP_SIMPLESTRING: if (phpStringDelimiter[0] == '\'') { if (ch == '\\') { // skip the next char i++; } else if (ch == '\'') { styler.ColourTo(i, StateToPrint); state = SCE_HPHP_DEFAULT; } } else if (isLineEnd(chPrev) && styler.Match(i, phpStringDelimiter)) { const int psdLength = static_cast<int>(strlen(phpStringDelimiter)); const char chAfterPsd = styler.SafeGetCharAt(i + psdLength); const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1); if (isLineEnd(chAfterPsd) || (chAfterPsd == ';' && isLineEnd(chAfterPsd2))) { i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1; styler.ColourTo(i, StateToPrint); state = SCE_HPHP_DEFAULT; if (foldHeredoc) levelCurrent--; } } break; case SCE_HPHP_HSTRING_VARIABLE: if (!IsPhpWordChar(chNext)) { styler.ColourTo(i, StateToPrint); state = SCE_HPHP_HSTRING; } break; case SCE_HPHP_COMPLEX_VARIABLE: if (ch == '}') { styler.ColourTo(i, StateToPrint); state = SCE_HPHP_HSTRING; } break; case SCE_HPHP_OPERATOR: case SCE_HPHP_DEFAULT: styler.ColourTo(i - 1, StateToPrint); if (IsADigit(ch) || (ch == '.' && IsADigit(chNext))) { state = SCE_HPHP_NUMBER; } else if (IsAWordStart(ch)) { state = SCE_HPHP_WORD; } else if (ch == '/' && chNext == '*') { i++; state = SCE_HPHP_COMMENT; } else if (ch == '/' && chNext == '/') { i++; state = SCE_HPHP_COMMENTLINE; } else if (ch == '#') { state = SCE_HPHP_COMMENTLINE; } else if (ch == '\"') { state = SCE_HPHP_HSTRING; strcpy(phpStringDelimiter, "\""); } else if (styler.Match(i, "<<<")) { bool isSimpleString = false; i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString); if (strlen(phpStringDelimiter)) { state = (isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING); if (foldHeredoc) levelCurrent++; } } else if (ch == '\'') { state = SCE_HPHP_SIMPLESTRING; strcpy(phpStringDelimiter, "\'"); } else if (ch == '$' && IsPhpWordStart(chNext)) { state = SCE_HPHP_VARIABLE; } else if (IsOperator(ch)) { state = SCE_HPHP_OPERATOR; } else if ((state == SCE_HPHP_OPERATOR) && (IsASpace(ch))) { state = SCE_HPHP_DEFAULT; } break; ///////////// end - PHP state handling } // Some of the above terminated their lexeme but since the same character starts // the same class again, only reenter if non empty segment. bool nonEmptySegment = i >= static_cast<int>(styler.GetStartSegment()); if (state == SCE_HB_DEFAULT) { // One of the above succeeded if ((ch == '\"') && (nonEmptySegment)) { state = SCE_HB_STRING; } else if (ch == '\'') { state = SCE_HB_COMMENTLINE; } else if (IsAWordStart(ch)) { state = SCE_HB_WORD; } else if (IsOperator(ch)) { styler.ColourTo(i, SCE_HB_DEFAULT); } } else if (state == SCE_HBA_DEFAULT) { // One of the above succeeded if ((ch == '\"') && (nonEmptySegment)) { state = SCE_HBA_STRING; } else if (ch == '\'') { state = SCE_HBA_COMMENTLINE; } else if (IsAWordStart(ch)) { state = SCE_HBA_WORD; } else if (IsOperator(ch)) { styler.ColourTo(i, SCE_HBA_DEFAULT); } } else if (state == SCE_HJ_DEFAULT) { // One of the above succeeded if (ch == '/' && chNext == '*') { if (styler.SafeGetCharAt(i + 2) == '*') state = SCE_HJ_COMMENTDOC; else state = SCE_HJ_COMMENT; } else if (ch == '/' && chNext == '/') { state = SCE_HJ_COMMENTLINE; } else if ((ch == '\"') && (nonEmptySegment)) { state = SCE_HJ_DOUBLESTRING; } else if ((ch == '\'') && (nonEmptySegment)) { state = SCE_HJ_SINGLESTRING; } else if (IsAWordStart(ch)) { state = SCE_HJ_WORD; } else if (IsOperator(ch)) { styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType)); } } } switch (state) { case SCE_HJ_WORD: classifyWordHTJS(styler.GetStartSegment(), lengthDoc - 1, keywords2, styler, inScriptType); break; case SCE_HB_WORD: classifyWordHTVB(styler.GetStartSegment(), lengthDoc - 1, keywords3, styler, inScriptType); break; case SCE_HP_WORD: classifyWordHTPy(styler.GetStartSegment(), lengthDoc - 1, keywords4, styler, prevWord, inScriptType, isMako); break; case SCE_HPHP_WORD: classifyWordHTPHP(styler.GetStartSegment(), lengthDoc - 1, keywords5, styler); break; default: StateToPrint = statePrintForState(state, inScriptType); if (static_cast<int>(styler.GetStartSegment()) < lengthDoc) styler.ColourTo(lengthDoc - 1, StateToPrint); break; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later if (fold) { int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } } static void ColouriseXMLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { // Passing in true because we're lexing XML ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists, styler, true); } static void ColouriseHTMLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { // Passing in false because we're notlexing XML ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists, styler, false); } static void ColourisePHPScriptDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { if (startPos == 0) initStyle = SCE_HPHP_DEFAULT; ColouriseHTMLDoc(startPos, length, initStyle, keywordlists, styler); } static const char * const htmlWordListDesc[] = { "HTML elements and attributes", "JavaScript keywords", "VBScript keywords", "Python keywords", "PHP keywords", "SGML and DTD keywords", 0, }; static const char * const phpscriptWordListDesc[] = { "", //Unused "", //Unused "", //Unused "", //Unused "PHP keywords", "", //Unused 0, }; LexerModule lmHTML(SCLEX_HTML, ColouriseHTMLDoc, "hypertext", 0, htmlWordListDesc, 8); LexerModule lmXML(SCLEX_XML, ColouriseXMLDoc, "xml", 0, htmlWordListDesc, 8); LexerModule lmPHPSCRIPT(SCLEX_PHPSCRIPT, ColourisePHPScriptDoc, "phpscript", 0, phpscriptWordListDesc, 8); |
Added lexers/LexHaskell.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
/****************************************************************** * LexHaskell.cxx * * A haskell lexer for the scintilla code control. * Some stuff "lended" from LexPython.cxx and LexCPP.cxx. * External lexer stuff inspired from the caml external lexer. * * Written by Tobias Engvall - tumm at dtek dot chalmers dot se * * Several bug fixes by Krasimir Angelov - kr.angelov at gmail.com * * TODO: * * Implement a folder :) * * Nice Character-lexing (stuff inside '\''), LexPython has * this. * * *****************************************************************/ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "PropSetSimple.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif #ifdef BUILD_AS_EXTERNAL_LEXER #include "ExternalLexer.h" #include "WindowAccessor.h" #define BUILD_EXTERNAL_LEXER 0 #endif #define HA_MODE_DEFAULT 0 #define HA_MODE_IMPORT1 1 #define HA_MODE_IMPORT2 2 #define HA_MODE_IMPORT3 3 #define HA_MODE_MODULE 4 #define HA_MODE_FFI 5 #define HA_MODE_TYPE 6 static inline bool IsNewline(const int ch) { return (ch == '\n' || ch == '\r'); } static inline bool IsWhitespace(const int ch) { return ( ch == ' ' || ch == '\t' || IsNewline(ch) ); } static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_'); } static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\''); } static void ColorizeHaskellDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &ffi = *keywordlists[1]; StyleContext sc(startPos, length, initStyle, styler); int lineCurrent = styler.GetLine(startPos); int state = lineCurrent ? styler.GetLineState(lineCurrent-1) : HA_MODE_DEFAULT; int mode = state & 0xF; int xmode = state >> 4; while (sc.More()) { // Check for state end // Operator if (sc.state == SCE_HA_OPERATOR) { if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) { sc.Forward(); } else { styler.ColourTo(sc.currentPos - 1, sc.state); sc.ChangeState(SCE_HA_DEFAULT); } } // String else if (sc.state == SCE_HA_STRING) { if (sc.ch == '\"') { sc.Forward(); styler.ColourTo(sc.currentPos-1, sc.state); sc.ChangeState(SCE_HA_DEFAULT); } else if (sc.ch == '\\') { sc.Forward(2); } else if (sc.atLineEnd) { styler.ColourTo(sc.currentPos-1, sc.state); sc.ChangeState(SCE_HA_DEFAULT); } else { sc.Forward(); } } // Char else if (sc.state == SCE_HA_CHARACTER) { if (sc.ch == '\'') { sc.Forward(); styler.ColourTo(sc.currentPos-1, sc.state); sc.ChangeState(SCE_HA_DEFAULT); } else if (sc.ch == '\\') { sc.Forward(2); } else if (sc.atLineEnd) { styler.ColourTo(sc.currentPos-1, sc.state); sc.ChangeState(SCE_HA_DEFAULT); } else { sc.Forward(); } } // Number else if (sc.state == SCE_HA_NUMBER) { if (IsADigit(sc.ch, xmode)) { sc.Forward(); } else if ((xmode == 10) && (sc.ch == 'e' || sc.ch == 'E') && (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-')) { sc.Forward(); if (sc.ch == '+' || sc.ch == '-') sc.Forward(); } else { styler.ColourTo(sc.currentPos - 1, sc.state); sc.ChangeState(SCE_HA_DEFAULT); } } // Identifier else if (sc.state == SCE_HA_IDENTIFIER) { if (IsAWordChar(sc.ch)) { sc.Forward(); } else { char s[100]; sc.GetCurrent(s, sizeof(s)); int style = sc.state; int new_mode = 0; if (keywords.InList(s)) { style = SCE_HA_KEYWORD; } else if (isupper(s[0])) { if (mode >= HA_MODE_IMPORT1 && mode <= HA_MODE_IMPORT3) { style = SCE_HA_MODULE; new_mode = HA_MODE_IMPORT2; } else if (mode == HA_MODE_MODULE) style = SCE_HA_MODULE; else style = SCE_HA_CAPITAL; } else if (mode == HA_MODE_IMPORT1 && strcmp(s,"qualified") == 0) { style = SCE_HA_KEYWORD; new_mode = HA_MODE_IMPORT1; } else if (mode == HA_MODE_IMPORT2) { if (strcmp(s,"as") == 0) { style = SCE_HA_KEYWORD; new_mode = HA_MODE_IMPORT3; } else if (strcmp(s,"hiding") == 0) { style = SCE_HA_KEYWORD; } } else if (mode == HA_MODE_FFI) { if (ffi.InList(s)) { style = SCE_HA_KEYWORD; new_mode = HA_MODE_FFI; } } else if (mode == HA_MODE_TYPE) { if (strcmp(s,"family") == 0) style = SCE_HA_KEYWORD; } styler.ColourTo(sc.currentPos - 1, style); if (strcmp(s,"import") == 0 && mode != HA_MODE_FFI) new_mode = HA_MODE_IMPORT1; else if (strcmp(s,"module") == 0) new_mode = HA_MODE_MODULE; else if (strcmp(s,"foreign") == 0) new_mode = HA_MODE_FFI; else if (strcmp(s,"type") == 0) new_mode = HA_MODE_TYPE; sc.ChangeState(SCE_HA_DEFAULT); mode = new_mode; } } // Comments // Oneliner else if (sc.state == SCE_HA_COMMENTLINE) { if (sc.atLineEnd) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.ChangeState(SCE_HA_DEFAULT); } else { sc.Forward(); } } // Nested else if (sc.state == SCE_HA_COMMENTBLOCK) { if (sc.Match("{-")) { sc.Forward(2); xmode++; } else if (sc.Match("-}")) { sc.Forward(2); xmode--; if (xmode == 0) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.ChangeState(SCE_HA_DEFAULT); } } else { if (sc.atLineEnd) { // Remember the line state for future incremental lexing styler.SetLineState(lineCurrent, (xmode << 4) | mode); lineCurrent++; } sc.Forward(); } } // New state? if (sc.state == SCE_HA_DEFAULT) { // Digit if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)) || (sc.ch == '-' && IsADigit(sc.chNext))) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.ChangeState(SCE_HA_NUMBER); if (sc.ch == '0' && (sc.chNext == 'X' || sc.chNext == 'x')) { // Match anything starting with "0x" or "0X", too sc.Forward(2); xmode = 16; } else if (sc.ch == '0' && (sc.chNext == 'O' || sc.chNext == 'o')) { // Match anything starting with "0x" or "0X", too sc.Forward(2); xmode = 8; } else { sc.Forward(); xmode = 10; } mode = HA_MODE_DEFAULT; } // Comment line else if (sc.Match("--")) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.Forward(2); sc.ChangeState(SCE_HA_COMMENTLINE); // Comment block } else if (sc.Match("{-")) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.Forward(2); sc.ChangeState(SCE_HA_COMMENTBLOCK); xmode = 1; } // String else if (sc.Match('\"')) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.Forward(); sc.ChangeState(SCE_HA_STRING); } // Character else if (sc.Match('\'')) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.Forward(); sc.ChangeState(SCE_HA_CHARACTER); } else if (sc.ch == '(' || sc.ch == ')' || sc.ch == '{' || sc.ch == '}' || sc.ch == '[' || sc.ch == ']') { styler.ColourTo(sc.currentPos - 1, sc.state); sc.Forward(); styler.ColourTo(sc.currentPos - 1, SCE_HA_OPERATOR); mode = HA_MODE_DEFAULT; } // Operator else if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.Forward(); sc.ChangeState(SCE_HA_OPERATOR); mode = HA_MODE_DEFAULT; } // Keyword else if (IsAWordStart(sc.ch)) { styler.ColourTo(sc.currentPos - 1, sc.state); sc.Forward(); sc.ChangeState(SCE_HA_IDENTIFIER); } else { if (sc.atLineEnd) { // Remember the line state for future incremental lexing styler.SetLineState(lineCurrent, (xmode << 4) | mode); lineCurrent++; } sc.Forward(); } } } sc.Complete(); } // External stuff - used for dynamic-loading, not implemented in wxStyledTextCtrl yet. // Inspired by the caml external lexer - Credits to Robert Roessler - http://www.rftp.com #ifdef BUILD_EXTERNAL_LEXER static const char* LexerName = "haskell"; void EXT_LEXER_DECL Lex(unsigned int lexer, unsigned int startPos, int length, int initStyle, char *words[], WindowID window, char *props) { PropSetSimple ps; ps.SetMultiple(props); WindowAccessor wa(window, ps); int nWL = 0; for (; words[nWL]; nWL++) ; WordList** wl = new WordList* [nWL + 1]; int i = 0; for (; i<nWL; i++) { wl[i] = new WordList(); wl[i]->Set(words[i]); } wl[i] = 0; ColorizeHaskellDoc(startPos, length, initStyle, wl, wa); wa.Flush(); for (i=nWL-1;i>=0;i--) delete wl[i]; delete [] wl; } void EXT_LEXER_DECL Fold (unsigned int lexer, unsigned int startPos, int length, int initStyle, char *words[], WindowID window, char *props) { } int EXT_LEXER_DECL GetLexerCount() { return 1; } void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength) { if (buflength > 0) { buflength--; int n = strlen(LexerName); if (n > buflength) n = buflength; memcpy(name, LexerName, n), name[n] = '\0'; } } #endif LexerModule lmHaskell(SCLEX_HASKELL, ColorizeHaskellDoc, "haskell"); |
Added lexers/LexInno.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
// Scintilla source code edit control /** @file LexInno.cxx ** Lexer for Inno Setup scripts. **/ // Written by Friedrich Vedder <fvedd@t-online.de>, using code from LexOthers.cxx. // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) { int state = SCE_INNO_DEFAULT; char chPrev; char ch = 0; char chNext = styler[startPos]; int lengthDoc = startPos + length; char *buffer = new char[length]; int bufferCount = 0; bool isBOL, isEOL, isWS, isBOLWS = 0; bool isCStyleComment = false; WordList §ionKeywords = *keywordLists[0]; WordList &standardKeywords = *keywordLists[1]; WordList ¶meterKeywords = *keywordLists[2]; WordList &preprocessorKeywords = *keywordLists[3]; WordList &pascalKeywords = *keywordLists[4]; WordList &userKeywords = *keywordLists[5]; int curLine = styler.GetLine(startPos); int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0; bool isCode = (curLineState == 1); // Go through all provided text segment // using the hand-written state machine shown below styler.StartAt(startPos); styler.StartSegment(startPos); for (int i = startPos; i < lengthDoc; i++) { chPrev = ch; ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if (styler.IsLeadByte(ch)) { chNext = styler.SafeGetCharAt(i + 2); i++; continue; } isBOL = (chPrev == 0) || (chPrev == '\n') || (chPrev == '\r' && ch != '\n'); isBOLWS = (isBOL) ? 1 : (isBOLWS && (chPrev == ' ' || chPrev == '\t')); isEOL = (ch == '\n' || ch == '\r'); isWS = (ch == ' ' || ch == '\t'); if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { // Remember the line state for future incremental lexing curLine = styler.GetLine(i); styler.SetLineState(curLine, (isCode ? 1 : 0)); } switch(state) { case SCE_INNO_DEFAULT: if (!isCode && ch == ';' && isBOLWS) { // Start of a comment state = SCE_INNO_COMMENT; } else if (ch == '[' && isBOLWS) { // Start of a section name bufferCount = 0; state = SCE_INNO_SECTION; } else if (ch == '#' && isBOLWS) { // Start of a preprocessor directive state = SCE_INNO_PREPROC; } else if (!isCode && ch == '{' && chNext != '{' && chPrev != '{') { // Start of an inline expansion state = SCE_INNO_INLINE_EXPANSION; } else if (isCode && (ch == '{' || (ch == '(' && chNext == '*'))) { // Start of a Pascal comment state = SCE_INNO_COMMENT_PASCAL; isCStyleComment = false; } else if (isCode && ch == '/' && chNext == '/') { // Apparently, C-style comments are legal, too state = SCE_INNO_COMMENT_PASCAL; isCStyleComment = true; } else if (ch == '"') { // Start of a double-quote string state = SCE_INNO_STRING_DOUBLE; } else if (ch == '\'') { // Start of a single-quote string state = SCE_INNO_STRING_SINGLE; } else if (isascii(ch) && (isalpha(ch) || (ch == '_'))) { // Start of an identifier bufferCount = 0; buffer[bufferCount++] = static_cast<char>(tolower(ch)); state = SCE_INNO_IDENTIFIER; } else { // Style it the default style styler.ColourTo(i,SCE_INNO_DEFAULT); } break; case SCE_INNO_COMMENT: if (isEOL) { state = SCE_INNO_DEFAULT; styler.ColourTo(i,SCE_INNO_COMMENT); } break; case SCE_INNO_IDENTIFIER: if (isascii(ch) && (isalnum(ch) || (ch == '_'))) { buffer[bufferCount++] = static_cast<char>(tolower(ch)); } else { state = SCE_INNO_DEFAULT; buffer[bufferCount] = '\0'; // Check if the buffer contains a keyword if (!isCode && standardKeywords.InList(buffer)) { styler.ColourTo(i-1,SCE_INNO_KEYWORD); } else if (!isCode && parameterKeywords.InList(buffer)) { styler.ColourTo(i-1,SCE_INNO_PARAMETER); } else if (isCode && pascalKeywords.InList(buffer)) { styler.ColourTo(i-1,SCE_INNO_KEYWORD_PASCAL); } else if (!isCode && userKeywords.InList(buffer)) { styler.ColourTo(i-1,SCE_INNO_KEYWORD_USER); } else { styler.ColourTo(i-1,SCE_INNO_DEFAULT); } // Push back the faulty character chNext = styler[i--]; ch = chPrev; } break; case SCE_INNO_SECTION: if (ch == ']') { state = SCE_INNO_DEFAULT; buffer[bufferCount] = '\0'; // Check if the buffer contains a section name if (sectionKeywords.InList(buffer)) { styler.ColourTo(i,SCE_INNO_SECTION); isCode = !CompareCaseInsensitive(buffer, "code"); } else { styler.ColourTo(i,SCE_INNO_DEFAULT); } } else if (isascii(ch) && (isalnum(ch) || (ch == '_'))) { buffer[bufferCount++] = static_cast<char>(tolower(ch)); } else { state = SCE_INNO_DEFAULT; styler.ColourTo(i,SCE_INNO_DEFAULT); } break; case SCE_INNO_PREPROC: if (isWS || isEOL) { if (isascii(chPrev) && isalpha(chPrev)) { state = SCE_INNO_DEFAULT; buffer[bufferCount] = '\0'; // Check if the buffer contains a preprocessor directive if (preprocessorKeywords.InList(buffer)) { styler.ColourTo(i-1,SCE_INNO_PREPROC); } else { styler.ColourTo(i-1,SCE_INNO_DEFAULT); } // Push back the faulty character chNext = styler[i--]; ch = chPrev; } } else if (isascii(ch) && isalpha(ch)) { if (chPrev == '#' || chPrev == ' ' || chPrev == '\t') bufferCount = 0; buffer[bufferCount++] = static_cast<char>(tolower(ch)); } break; case SCE_INNO_STRING_DOUBLE: if (ch == '"' || isEOL) { state = SCE_INNO_DEFAULT; styler.ColourTo(i,SCE_INNO_STRING_DOUBLE); } break; case SCE_INNO_STRING_SINGLE: if (ch == '\'' || isEOL) { state = SCE_INNO_DEFAULT; styler.ColourTo(i,SCE_INNO_STRING_SINGLE); } break; case SCE_INNO_INLINE_EXPANSION: if (ch == '}') { state = SCE_INNO_DEFAULT; styler.ColourTo(i,SCE_INNO_INLINE_EXPANSION); } else if (isEOL) { state = SCE_INNO_DEFAULT; styler.ColourTo(i,SCE_INNO_DEFAULT); } break; case SCE_INNO_COMMENT_PASCAL: if (isCStyleComment) { if (isEOL) { state = SCE_INNO_DEFAULT; styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL); } } else { if (ch == '}' || (ch == ')' && chPrev == '*')) { state = SCE_INNO_DEFAULT; styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL); } else if (isEOL) { state = SCE_INNO_DEFAULT; styler.ColourTo(i,SCE_INNO_DEFAULT); } } break; } } delete []buffer; } static const char * const innoWordListDesc[] = { "Sections", "Keywords", "Parameters", "Preprocessor directives", "Pascal keywords", "User defined keywords", 0 }; static void FoldInnoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { unsigned int endPos = startPos + length; char chNext = styler[startPos]; int lineCurrent = styler.GetLine(startPos); bool sectionFlag = false; int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) : SC_FOLDLEVELBASE; int level; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler[i+1]; bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); int style = styler.StyleAt(i); if (style == SCE_INNO_SECTION) sectionFlag = true; if (atEOL || i == endPos - 1) { if (sectionFlag) { level = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG; if (level == levelPrev) styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG); } else { level = levelPrev & SC_FOLDLEVELNUMBERMASK; if (levelPrev & SC_FOLDLEVELHEADERFLAG) level++; } styler.SetLevel(lineCurrent, level); levelPrev = level; lineCurrent++; sectionFlag = false; } } } LexerModule lmInno(SCLEX_INNOSETUP, ColouriseInnoDoc, "inno", FoldInnoDoc, innoWordListDesc); |
Added lexers/LexKix.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
// Scintilla source code edit control /** @file LexKix.cxx ** Lexer for KIX-Scripts. **/ // Copyright 2004 by Manfred Becker <manfred@becker-trdf.de> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // Extended to accept accented characters static inline bool IsAWordChar(int ch) { return ch >= 0x80 || isalnum(ch) || ch == '_'; } static inline bool IsOperator(const int ch) { return (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '&' || ch == '|' || ch == '<' || ch == '>' || ch == '='); } static void ColouriseKixDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; // WordList &keywords4 = *keywordlists[3]; styler.StartAt(startPos); StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.state == SCE_KIX_COMMENT) { if (sc.atLineEnd) { sc.SetState(SCE_KIX_DEFAULT); } } else if (sc.state == SCE_KIX_STRING1) { // This is a doubles quotes string if (sc.ch == '\"') { sc.ForwardSetState(SCE_KIX_DEFAULT); } } else if (sc.state == SCE_KIX_STRING2) { // This is a single quote string if (sc.ch == '\'') { sc.ForwardSetState(SCE_KIX_DEFAULT); } } else if (sc.state == SCE_KIX_NUMBER) { if (!IsADigit(sc.ch)) { sc.SetState(SCE_KIX_DEFAULT); } } else if (sc.state == SCE_KIX_VAR) { if (!IsAWordChar(sc.ch)) { sc.SetState(SCE_KIX_DEFAULT); } } else if (sc.state == SCE_KIX_MACRO) { if (!IsAWordChar(sc.ch) && !IsADigit(sc.ch)) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (!keywords3.InList(&s[1])) { sc.ChangeState(SCE_KIX_DEFAULT); } sc.SetState(SCE_KIX_DEFAULT); } } else if (sc.state == SCE_KIX_OPERATOR) { if (!IsOperator(sc.ch)) { sc.SetState(SCE_KIX_DEFAULT); } } else if (sc.state == SCE_KIX_IDENTIFIER) { if (!IsAWordChar(sc.ch)) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (keywords.InList(s)) { sc.ChangeState(SCE_KIX_KEYWORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_KIX_FUNCTIONS); } sc.SetState(SCE_KIX_DEFAULT); } } // Determine if a new state should be entered. if (sc.state == SCE_KIX_DEFAULT) { if (sc.ch == ';') { sc.SetState(SCE_KIX_COMMENT); } else if (sc.ch == '\"') { sc.SetState(SCE_KIX_STRING1); } else if (sc.ch == '\'') { sc.SetState(SCE_KIX_STRING2); } else if (sc.ch == '$') { sc.SetState(SCE_KIX_VAR); } else if (sc.ch == '@') { sc.SetState(SCE_KIX_MACRO); } else if (IsADigit(sc.ch) || ((sc.ch == '.' || sc.ch == '&') && IsADigit(sc.chNext))) { sc.SetState(SCE_KIX_NUMBER); } else if (IsOperator(sc.ch)) { sc.SetState(SCE_KIX_OPERATOR); } else if (IsAWordChar(sc.ch)) { sc.SetState(SCE_KIX_IDENTIFIER); } } } sc.Complete(); } LexerModule lmKix(SCLEX_KIX, ColouriseKixDoc, "kix"); |
Added lexers/LexLaTeX.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 |
// Scintilla source code edit control /** @file LexLaTeX.cxx ** Lexer for LaTeX2e. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. // Modified by G. HU in 2013. Added folding, syntax highting inside math environments, and changed some minor behaviors. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include <vector> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "PropSetSimple.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #include "LexerBase.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif using namespace std; struct latexFoldSave { latexFoldSave() : structLev(0) { for (int i = 0; i < 8; ++i) openBegins[i] = 0; } latexFoldSave(const latexFoldSave &save) : structLev(save.structLev) { for (int i = 0; i < 8; ++i) openBegins[i] = save.openBegins[i]; } int openBegins[8]; int structLev; }; class LexerLaTeX : public LexerBase { private: vector<int> modes; void setMode(int line, int mode) { if (line >= static_cast<int>(modes.size())) modes.resize(line + 1, 0); modes[line] = mode; } int getMode(int line) { if (line >= 0 && line < static_cast<int>(modes.size())) return modes[line]; return 0; } void truncModes(int numLines) { if (static_cast<int>(modes.size()) > numLines * 2 + 256) modes.resize(numLines + 128); } vector<latexFoldSave> saves; void setSave(int line, const latexFoldSave &save) { if (line >= static_cast<int>(saves.size())) saves.resize(line + 1); saves[line] = save; } void getSave(int line, latexFoldSave &save) { if (line >= 0 && line < static_cast<int>(saves.size())) save = saves[line]; else { save.structLev = 0; for (int i = 0; i < 8; ++i) save.openBegins[i] = 0; } } void truncSaves(int numLines) { if (static_cast<int>(saves.size()) > numLines * 2 + 256) saves.resize(numLines + 128); } public: static ILexer *LexerFactoryLaTeX() { return new LexerLaTeX(); } void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess); void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess); }; static bool latexIsSpecial(int ch) { return (ch == '#') || (ch == '$') || (ch == '%') || (ch == '&') || (ch == '_') || (ch == '{') || (ch == '}') || (ch == ' '); } static bool latexIsBlank(int ch) { return (ch == ' ') || (ch == '\t'); } static bool latexIsBlankAndNL(int ch) { return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n'); } static bool latexIsLetter(int ch) { return isascii(ch) && isalpha(ch); } static bool latexIsTagValid(int &i, int l, Accessor &styler) { while (i < l) { if (styler.SafeGetCharAt(i) == '{') { while (i < l) { i++; if (styler.SafeGetCharAt(i) == '}') { return true; } else if (!latexIsLetter(styler.SafeGetCharAt(i)) && styler.SafeGetCharAt(i)!='*') { return false; } } } else if (!latexIsBlank(styler.SafeGetCharAt(i))) { return false; } i++; } return false; } static bool latexNextNotBlankIs(int i, Accessor &styler, char needle) { char ch; while (i < styler.Length()) { ch = styler.SafeGetCharAt(i); if (!latexIsBlankAndNL(ch) && ch != '*') { if (ch == needle) return true; else return false; } i++; } return false; } static bool latexLastWordIs(int start, Accessor &styler, const char *needle) { unsigned int i = 0; unsigned int l = static_cast<unsigned int>(strlen(needle)); int ini = start-l+1; char s[32]; while (i < l && i < 31) { s[i] = styler.SafeGetCharAt(ini + i); i++; } s[i] = '\0'; return (strcmp(s, needle) == 0); } static bool latexLastWordIsMathEnv(int pos, Accessor &styler) { int i, j; char s[32]; const char *mathEnvs[] = { "align", "alignat", "flalign", "gather", "multiline", "displaymath", "eqnarray", "equation" }; if (styler.SafeGetCharAt(pos) != '}') return false; for (i = pos - 1; i >= 0; --i) { if (styler.SafeGetCharAt(i) == '{') break; if (pos - i >= 20) return false; } if (i < 0 || i == pos - 1) return false; ++i; for (j = 0; i + j < pos; ++j) s[j] = styler.SafeGetCharAt(i + j); s[j] = '\0'; if (j == 0) return false; if (s[j - 1] == '*') s[--j] = '\0'; for (i = 0; i < static_cast<int>(sizeof(mathEnvs) / sizeof(const char *)); ++i) if (strcmp(s, mathEnvs[i]) == 0) return true; return false; } static inline void latexStateReset(int &mode, int &state) { switch (mode) { case 1: state = SCE_L_MATH; break; case 2: state = SCE_L_MATH2; break; default: state = SCE_L_DEFAULT; break; } } // There are cases not handled correctly, like $abcd\textrm{what is $x+y$}z+w$. // But I think it's already good enough. void SCI_METHOD LexerLaTeX::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { // startPos is assumed to be the first character of a line Accessor styler(pAccess, &props); styler.StartAt(startPos); int mode = getMode(styler.GetLine(startPos) - 1); int state = initStyle; if (state == SCE_L_ERROR || state == SCE_L_SHORTCMD || state == SCE_L_SPECIAL) // should not happen latexStateReset(mode, state); char chNext = styler.SafeGetCharAt(startPos); char chVerbatimDelim = '\0'; styler.StartSegment(startPos); int lengthDoc = startPos + length; for (int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if (styler.IsLeadByte(ch)) { i++; chNext = styler.SafeGetCharAt(i + 1); continue; } if (ch == '\r' || ch == '\n') setMode(styler.GetLine(i), mode); switch (state) { case SCE_L_DEFAULT : switch (ch) { case '\\' : styler.ColourTo(i - 1, state); if (latexIsLetter(chNext)) { state = SCE_L_COMMAND; } else if (latexIsSpecial(chNext)) { styler.ColourTo(i + 1, SCE_L_SPECIAL); i++; chNext = styler.SafeGetCharAt(i + 1); } else if (chNext == '\r' || chNext == '\n') { styler.ColourTo(i, SCE_L_ERROR); } else { styler.ColourTo(i + 1, SCE_L_SHORTCMD); if (chNext == '(') { mode = 1; state = SCE_L_MATH; } else if (chNext == '[') { mode = 2; state = SCE_L_MATH2; } i++; chNext = styler.SafeGetCharAt(i + 1); } break; case '$' : styler.ColourTo(i - 1, state); if (chNext == '$') { styler.ColourTo(i + 1, SCE_L_SHORTCMD); mode = 2; state = SCE_L_MATH2; i++; chNext = styler.SafeGetCharAt(i + 1); } else { styler.ColourTo(i, SCE_L_SHORTCMD); mode = 1; state = SCE_L_MATH; } break; case '%' : styler.ColourTo(i - 1, state); state = SCE_L_COMMENT; break; } break; // These 3 will never be reached. case SCE_L_ERROR: case SCE_L_SPECIAL: case SCE_L_SHORTCMD: break; case SCE_L_COMMAND : if (!latexIsLetter(chNext)) { styler.ColourTo(i, state); if (latexNextNotBlankIs(i + 1, styler, '[' )) { state = SCE_L_CMDOPT; } else if (latexLastWordIs(i, styler, "\\begin")) { state = SCE_L_TAG; } else if (latexLastWordIs(i, styler, "\\end")) { state = SCE_L_TAG2; } else if (latexLastWordIs(i, styler, "\\verb") && chNext != '*' && chNext != ' ') { chVerbatimDelim = chNext; state = SCE_L_VERBATIM; } else { latexStateReset(mode, state); } } break; case SCE_L_CMDOPT : if (ch == ']') { styler.ColourTo(i, state); latexStateReset(mode, state); } break; case SCE_L_TAG : if (latexIsTagValid(i, lengthDoc, styler)) { styler.ColourTo(i, state); latexStateReset(mode, state); if (latexLastWordIs(i, styler, "{verbatim}")) { state = SCE_L_VERBATIM; } else if (latexLastWordIs(i, styler, "{comment}")) { state = SCE_L_COMMENT2; } else if (latexLastWordIs(i, styler, "{math}") && mode == 0) { mode = 1; state = SCE_L_MATH; } else if (latexLastWordIsMathEnv(i, styler) && mode == 0) { mode = 2; state = SCE_L_MATH2; } } else { styler.ColourTo(i, SCE_L_ERROR); latexStateReset(mode, state); ch = styler.SafeGetCharAt(i); if (ch == '\r' || ch == '\n') setMode(styler.GetLine(i), mode); } chNext = styler.SafeGetCharAt(i+1); break; case SCE_L_TAG2 : if (latexIsTagValid(i, lengthDoc, styler)) { styler.ColourTo(i, state); latexStateReset(mode, state); } else { styler.ColourTo(i, SCE_L_ERROR); latexStateReset(mode, state); ch = styler.SafeGetCharAt(i); if (ch == '\r' || ch == '\n') setMode(styler.GetLine(i), mode); } chNext = styler.SafeGetCharAt(i+1); break; case SCE_L_MATH : switch (ch) { case '\\' : styler.ColourTo(i - 1, state); if (latexIsLetter(chNext)) { int match = i + 3; if (latexLastWordIs(match, styler, "\\end")) { match++; if (latexIsTagValid(match, lengthDoc, styler)) { if (latexLastWordIs(match, styler, "{math}")) mode = 0; } } state = SCE_L_COMMAND; } else if (latexIsSpecial(chNext)) { styler.ColourTo(i + 1, SCE_L_SPECIAL); i++; chNext = styler.SafeGetCharAt(i + 1); } else if (chNext == '\r' || chNext == '\n') { styler.ColourTo(i, SCE_L_ERROR); } else { if (chNext == ')') { mode = 0; state = SCE_L_DEFAULT; } styler.ColourTo(i + 1, SCE_L_SHORTCMD); i++; chNext = styler.SafeGetCharAt(i + 1); } break; case '$' : styler.ColourTo(i - 1, state); styler.ColourTo(i, SCE_L_SHORTCMD); mode = 0; state = SCE_L_DEFAULT; break; case '%' : styler.ColourTo(i - 1, state); state = SCE_L_COMMENT; break; } break; case SCE_L_MATH2 : switch (ch) { case '\\' : styler.ColourTo(i - 1, state); if (latexIsLetter(chNext)) { int match = i + 3; if (latexLastWordIs(match, styler, "\\end")) { match++; if (latexIsTagValid(match, lengthDoc, styler)) { if (latexLastWordIsMathEnv(match, styler)) mode = 0; } } state = SCE_L_COMMAND; } else if (latexIsSpecial(chNext)) { styler.ColourTo(i + 1, SCE_L_SPECIAL); i++; chNext = styler.SafeGetCharAt(i + 1); } else if (chNext == '\r' || chNext == '\n') { styler.ColourTo(i, SCE_L_ERROR); } else { if (chNext == ']') { mode = 0; state = SCE_L_DEFAULT; } styler.ColourTo(i + 1, SCE_L_SHORTCMD); i++; chNext = styler.SafeGetCharAt(i + 1); } break; case '$' : styler.ColourTo(i - 1, state); if (chNext == '$') { styler.ColourTo(i + 1, SCE_L_SHORTCMD); i++; chNext = styler.SafeGetCharAt(i + 1); mode = 0; state = SCE_L_DEFAULT; } else { // This may not be an error, e.g. \begin{equation}\text{$a$}\end{equation} styler.ColourTo(i, SCE_L_SHORTCMD); } break; case '%' : styler.ColourTo(i - 1, state); state = SCE_L_COMMENT; break; } break; case SCE_L_COMMENT : if (ch == '\r' || ch == '\n') { styler.ColourTo(i - 1, state); latexStateReset(mode, state); } break; case SCE_L_COMMENT2 : if (ch == '\\') { int match = i + 3; if (latexLastWordIs(match, styler, "\\end")) { match++; if (latexIsTagValid(match, lengthDoc, styler)) { if (latexLastWordIs(match, styler, "{comment}")) { styler.ColourTo(i - 1, state); state = SCE_L_COMMAND; } } } } break; case SCE_L_VERBATIM : if (ch == '\\') { int match = i + 3; if (latexLastWordIs(match, styler, "\\end")) { match++; if (latexIsTagValid(match, lengthDoc, styler)) { if (latexLastWordIs(match, styler, "{verbatim}")) { styler.ColourTo(i - 1, state); state = SCE_L_COMMAND; } } } } else if (chNext == chVerbatimDelim) { styler.ColourTo(i + 1, state); latexStateReset(mode, state); chVerbatimDelim = '\0'; i++; chNext = styler.SafeGetCharAt(i + 1); } else if (chVerbatimDelim != '\0' && (ch == '\n' || ch == '\r')) { styler.ColourTo(i, SCE_L_ERROR); latexStateReset(mode, state); chVerbatimDelim = '\0'; } break; } } if (lengthDoc == styler.Length()) truncModes(styler.GetLine(lengthDoc - 1)); styler.ColourTo(lengthDoc - 1, state); styler.Flush(); } static int latexFoldSaveToInt(const latexFoldSave &save) { int sum = 0; for (int i = 0; i <= save.structLev; ++i) sum += save.openBegins[i]; return ((sum + save.structLev + SC_FOLDLEVELBASE) & SC_FOLDLEVELNUMBERMASK); } // Change folding state while processing a line // Return the level before the first relevant command void SCI_METHOD LexerLaTeX::Fold(unsigned int startPos, int length, int, IDocument *pAccess) { const char *structWords[7] = {"part", "chapter", "section", "subsection", "subsubsection", "paragraph", "subparagraph"}; Accessor styler(pAccess, &props); unsigned int endPos = startPos + length; int curLine = styler.GetLine(startPos); latexFoldSave save; getSave(curLine - 1, save); do { char ch, buf[16]; int i, j, lev = -1; bool needFold = false; for (i = static_cast<int>(startPos); i < static_cast<int>(endPos); ++i) { ch = styler.SafeGetCharAt(i); if (ch == '\r' || ch == '\n') break; if (ch != '\\' || styler.StyleAt(i) != SCE_L_COMMAND) continue; for (j = 0; j < 15 && i + 1 < static_cast<int>(endPos); ++j, ++i) { buf[j] = styler.SafeGetCharAt(i + 1); if (!latexIsLetter(buf[j])) break; } buf[j] = '\0'; if (strcmp(buf, "begin") == 0) { if (lev < 0) lev = latexFoldSaveToInt(save); ++save.openBegins[save.structLev]; needFold = true; } else if (strcmp(buf, "end") == 0) { while (save.structLev > 0 && save.openBegins[save.structLev] == 0) --save.structLev; if (lev < 0) lev = latexFoldSaveToInt(save); if (save.openBegins[save.structLev] > 0) --save.openBegins[save.structLev]; } else { for (j = 0; j < 7; ++j) if (strcmp(buf, structWords[j]) == 0) break; if (j >= 7) continue; save.structLev = j; // level before the command for (j = save.structLev + 1; j < 8; ++j) { save.openBegins[save.structLev] += save.openBegins[j]; save.openBegins[j] = 0; } if (lev < 0) lev = latexFoldSaveToInt(save); ++save.structLev; // level after the command needFold = true; } } if (lev < 0) lev = latexFoldSaveToInt(save); if (needFold) lev |= SC_FOLDLEVELHEADERFLAG; styler.SetLevel(curLine, lev); setSave(curLine, save); ++curLine; startPos = styler.LineStart(curLine); if (static_cast<int>(startPos) == styler.Length()) { lev = latexFoldSaveToInt(save); styler.SetLevel(curLine, lev); setSave(curLine, save); truncSaves(curLine); } } while (startPos < endPos); styler.Flush(); } static const char *const emptyWordListDesc[] = { 0 }; LexerModule lmLatex(SCLEX_LATEX, LexerLaTeX::LexerFactoryLaTeX, "latex", emptyWordListDesc); |
Added lexers/LexLisp.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
// Scintilla source code edit control /** @file LexLisp.cxx ** Lexer for Lisp. ** Written by Alexey Yutkin. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif #define SCE_LISP_CHARACTER 29 #define SCE_LISP_MACRO 30 #define SCE_LISP_MACRO_DISPATCH 31 static inline bool isLispoperator(char ch) { if (isascii(ch) && isalnum(ch)) return false; if (ch == '\'' || ch == '`' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '{' || ch == '}') return true; return false; } static inline bool isLispwordstart(char ch) { return isascii(ch) && ch != ';' && !isspacechar(ch) && !isLispoperator(ch) && ch != '\n' && ch != '\r' && ch != '\"'; } static void classifyWordLisp(unsigned int start, unsigned int end, WordList &keywords, WordList &keywords_kw, Accessor &styler) { assert(end >= start); char s[100]; unsigned int i; bool digit_flag = true; for (i = 0; (i < end - start + 1) && (i < 99); i++) { s[i] = styler[start + i]; s[i + 1] = '\0'; if (!isdigit(s[i]) && (s[i] != '.')) digit_flag = false; } char chAttr = SCE_LISP_IDENTIFIER; if(digit_flag) chAttr = SCE_LISP_NUMBER; else { if (keywords.InList(s)) { chAttr = SCE_LISP_KEYWORD; } else if (keywords_kw.InList(s)) { chAttr = SCE_LISP_KEYWORD_KW; } else if ((s[0] == '*' && s[i-1] == '*') || (s[0] == '+' && s[i-1] == '+')) { chAttr = SCE_LISP_SPECIAL; } } styler.ColourTo(end, chAttr); return; } static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords_kw = *keywordlists[1]; styler.StartAt(startPos); int state = initStyle, radix = -1; char chNext = styler[startPos]; unsigned int lengthDoc = startPos + length; styler.StartSegment(startPos); for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (styler.IsLeadByte(ch)) { chNext = styler.SafeGetCharAt(i + 2); i += 1; continue; } if (state == SCE_LISP_DEFAULT) { if (ch == '#') { styler.ColourTo(i - 1, state); radix = -1; state = SCE_LISP_MACRO_DISPATCH; } else if (ch == ':' && isLispwordstart(chNext)) { styler.ColourTo(i - 1, state); state = SCE_LISP_SYMBOL; } else if (isLispwordstart(ch)) { styler.ColourTo(i - 1, state); state = SCE_LISP_IDENTIFIER; } else if (ch == ';') { styler.ColourTo(i - 1, state); state = SCE_LISP_COMMENT; } else if (isLispoperator(ch) || ch=='\'') { styler.ColourTo(i - 1, state); styler.ColourTo(i, SCE_LISP_OPERATOR); if (ch=='\'' && isLispwordstart(chNext)) { state = SCE_LISP_SYMBOL; } } else if (ch == '\"') { styler.ColourTo(i - 1, state); state = SCE_LISP_STRING; } } else if (state == SCE_LISP_IDENTIFIER || state == SCE_LISP_SYMBOL) { if (!isLispwordstart(ch)) { if (state == SCE_LISP_IDENTIFIER) { classifyWordLisp(styler.GetStartSegment(), i - 1, keywords, keywords_kw, styler); } else { styler.ColourTo(i - 1, state); } state = SCE_LISP_DEFAULT; } /*else*/ if (isLispoperator(ch) || ch=='\'') { styler.ColourTo(i - 1, state); styler.ColourTo(i, SCE_LISP_OPERATOR); if (ch=='\'' && isLispwordstart(chNext)) { state = SCE_LISP_SYMBOL; } } } else if (state == SCE_LISP_MACRO_DISPATCH) { if (!(isascii(ch) && isdigit(ch))) { if (ch != 'r' && ch != 'R' && (i - styler.GetStartSegment()) > 1) { state = SCE_LISP_DEFAULT; } else { switch (ch) { case '|': state = SCE_LISP_MULTI_COMMENT; break; case 'o': case 'O': radix = 8; state = SCE_LISP_MACRO; break; case 'x': case 'X': radix = 16; state = SCE_LISP_MACRO; break; case 'b': case 'B': radix = 2; state = SCE_LISP_MACRO; break; case '\\': state = SCE_LISP_CHARACTER; break; case ':': case '-': case '+': state = SCE_LISP_MACRO; break; case '\'': if (isLispwordstart(chNext)) { state = SCE_LISP_SPECIAL; } else { styler.ColourTo(i - 1, SCE_LISP_DEFAULT); styler.ColourTo(i, SCE_LISP_OPERATOR); state = SCE_LISP_DEFAULT; } break; default: if (isLispoperator(ch)) { styler.ColourTo(i - 1, SCE_LISP_DEFAULT); styler.ColourTo(i, SCE_LISP_OPERATOR); } state = SCE_LISP_DEFAULT; break; } } } } else if (state == SCE_LISP_MACRO) { if (isLispwordstart(ch) && (radix == -1 || IsADigit(ch, radix))) { state = SCE_LISP_SPECIAL; } else { state = SCE_LISP_DEFAULT; } } else if (state == SCE_LISP_CHARACTER) { if (isLispoperator(ch)) { styler.ColourTo(i, SCE_LISP_SPECIAL); state = SCE_LISP_DEFAULT; } else if (isLispwordstart(ch)) { styler.ColourTo(i, SCE_LISP_SPECIAL); state = SCE_LISP_SPECIAL; } else { state = SCE_LISP_DEFAULT; } } else if (state == SCE_LISP_SPECIAL) { if (!isLispwordstart(ch) || (radix != -1 && !IsADigit(ch, radix))) { styler.ColourTo(i - 1, state); state = SCE_LISP_DEFAULT; } if (isLispoperator(ch) || ch=='\'') { styler.ColourTo(i - 1, state); styler.ColourTo(i, SCE_LISP_OPERATOR); if (ch=='\'' && isLispwordstart(chNext)) { state = SCE_LISP_SYMBOL; } } } else { if (state == SCE_LISP_COMMENT) { if (atEOL) { styler.ColourTo(i - 1, state); state = SCE_LISP_DEFAULT; } } else if (state == SCE_LISP_MULTI_COMMENT) { if (ch == '|' && chNext == '#') { i++; chNext = styler.SafeGetCharAt(i + 1); styler.ColourTo(i, state); state = SCE_LISP_DEFAULT; } } else if (state == SCE_LISP_STRING) { if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; chNext = styler.SafeGetCharAt(i + 1); } } else if (ch == '\"') { styler.ColourTo(i, state); state = SCE_LISP_DEFAULT; } } } } styler.ColourTo(lengthDoc - 1, state); } static void FoldLispDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[], Accessor &styler) { unsigned int lengthDoc = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (style == SCE_LISP_OPERATOR) { if (ch == '(' || ch == '[' || ch == '{') { levelCurrent++; } else if (ch == ')' || ch == ']' || ch == '}') { levelCurrent--; } } if (atEOL) { int lev = levelPrev; if (visibleChars == 0) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char * const lispWordListDesc[] = { "Functions and special operators", "Keywords", 0 }; LexerModule lmLISP(SCLEX_LISP, ColouriseLispDoc, "lisp", FoldLispDoc, lispWordListDesc); |
Added lexers/LexLout.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
// Scintilla source code edit control /** @file LexLout.cxx ** Lexer for the Basser Lout (>= version 3) typesetting language **/ // Copyright 2003 by Kein-Hong Man <mkh@pl.jaring.my> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalpha(ch) || ch == '@' || ch == '_'); } static inline bool IsAnOther(const int ch) { return (ch < 0x80) && (ch == '{' || ch == '}' || ch == '!' || ch == '$' || ch == '%' || ch == '&' || ch == '\'' || ch == '(' || ch == ')' || ch == '*' || ch == '+' || ch == ',' || ch == '-' || ch == '.' || ch == '/' || ch == ':' || ch == ';' || ch == '<' || ch == '=' || ch == '>' || ch == '?' || ch == '[' || ch == ']' || ch == '^' || ch == '`' || ch == '|' || ch == '~'); } static void ColouriseLoutDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; int visibleChars = 0; int firstWordInLine = 0; int leadingAtSign = 0; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.atLineStart && (sc.state == SCE_LOUT_STRING)) { // Prevent SCE_LOUT_STRINGEOL from leaking back to previous line sc.SetState(SCE_LOUT_STRING); } // Determine if the current state should terminate. if (sc.state == SCE_LOUT_COMMENT) { if (sc.atLineEnd) { sc.SetState(SCE_LOUT_DEFAULT); visibleChars = 0; } } else if (sc.state == SCE_LOUT_NUMBER) { if (!IsADigit(sc.ch) && sc.ch != '.') { sc.SetState(SCE_LOUT_DEFAULT); } } else if (sc.state == SCE_LOUT_STRING) { if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_LOUT_DEFAULT); } else if (sc.atLineEnd) { sc.ChangeState(SCE_LOUT_STRINGEOL); sc.ForwardSetState(SCE_LOUT_DEFAULT); visibleChars = 0; } } else if (sc.state == SCE_LOUT_IDENTIFIER) { if (!IsAWordChar(sc.ch)) { char s[100]; sc.GetCurrent(s, sizeof(s)); if (leadingAtSign) { if (keywords.InList(s)) { sc.ChangeState(SCE_LOUT_WORD); } else { sc.ChangeState(SCE_LOUT_WORD4); } } else if (firstWordInLine && keywords3.InList(s)) { sc.ChangeState(SCE_LOUT_WORD3); } sc.SetState(SCE_LOUT_DEFAULT); } } else if (sc.state == SCE_LOUT_OPERATOR) { if (!IsAnOther(sc.ch)) { char s[100]; sc.GetCurrent(s, sizeof(s)); if (keywords2.InList(s)) { sc.ChangeState(SCE_LOUT_WORD2); } sc.SetState(SCE_LOUT_DEFAULT); } } // Determine if a new state should be entered. if (sc.state == SCE_LOUT_DEFAULT) { if (sc.ch == '#') { sc.SetState(SCE_LOUT_COMMENT); } else if (sc.ch == '\"') { sc.SetState(SCE_LOUT_STRING); } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_LOUT_NUMBER); } else if (IsAWordChar(sc.ch)) { firstWordInLine = (visibleChars == 0); leadingAtSign = (sc.ch == '@'); sc.SetState(SCE_LOUT_IDENTIFIER); } else if (IsAnOther(sc.ch)) { sc.SetState(SCE_LOUT_OPERATOR); } } if (sc.atLineEnd) { // Reset states to begining of colourise so no surprises // if different sets of lines lexed. visibleChars = 0; } if (!IsASpace(sc.ch)) { visibleChars++; } } sc.Complete(); } static void FoldLoutDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; int styleNext = styler.StyleAt(startPos); char s[10]; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (style == SCE_LOUT_WORD) { if (ch == '@') { for (unsigned int j = 0; j < 8; j++) { if (!IsAWordChar(styler[i + j])) { break; } s[j] = styler[i + j]; s[j + 1] = '\0'; } if (strcmp(s, "@Begin") == 0) { levelCurrent++; } else if (strcmp(s, "@End") == 0) { levelCurrent--; } } } else if (style == SCE_LOUT_OPERATOR) { if (ch == '{') { levelCurrent++; } else if (ch == '}') { levelCurrent--; } } if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) { lev |= SC_FOLDLEVELWHITEFLAG; } if ((levelCurrent > levelPrev) && (visibleChars > 0)) { lev |= SC_FOLDLEVELHEADERFLAG; } if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char * const loutWordLists[] = { "Predefined identifiers", "Predefined delimiters", "Predefined keywords", 0, }; LexerModule lmLout(SCLEX_LOUT, ColouriseLoutDoc, "lout", FoldLoutDoc, loutWordLists); |
Added lexers/LexLua.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 |
// Scintilla source code edit control /** @file LexLua.cxx ** Lexer for Lua language. ** ** Written by Paul Winwood. ** Folder by Alexey Yutkin. ** Modified by Marcos E. Wurzius & Philippe Lhoste **/ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // Test for [=[ ... ]=] delimiters, returns 0 if it's only a [ or ], // return 1 for [[ or ]], returns >=2 for [=[ or ]=] and so on. // The maximum number of '=' characters allowed is 254. static int LongDelimCheck(StyleContext &sc) { int sep = 1; while (sc.GetRelative(sep) == '=' && sep < 0xFF) sep++; if (sc.GetRelative(sep) == sc.ch) return sep; return 0; } static void ColouriseLuaDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; WordList &keywords5 = *keywordlists[4]; WordList &keywords6 = *keywordlists[5]; WordList &keywords7 = *keywordlists[6]; WordList &keywords8 = *keywordlists[7]; // Accepts accented characters CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true); // Not exactly following number definition (several dots are seen as OK, etc.) // but probably enough in most cases. [pP] is for hex floats. CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefpABCDEFP"); CharacterSet setExponent(CharacterSet::setNone, "eEpP"); CharacterSet setLuaOperator(CharacterSet::setNone, "*/-+()={}~[];<>,.^%:#"); CharacterSet setEscapeSkip(CharacterSet::setNone, "\"'\\"); int currentLine = styler.GetLine(startPos); // Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level, // if we are inside such a string. Block comment was introduced in Lua 5.0, // blocks with separators [=[ ... ]=] in Lua 5.1. // Continuation of a string (\z whitespace escaping) is controlled by stringWs. int nestLevel = 0; int sepCount = 0; int stringWs = 0; if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT || initStyle == SCE_LUA_STRING || initStyle == SCE_LUA_CHARACTER) { int lineState = styler.GetLineState(currentLine - 1); nestLevel = lineState >> 9; sepCount = lineState & 0xFF; stringWs = lineState & 0x100; } // Do not leak onto next line if (initStyle == SCE_LUA_STRINGEOL || initStyle == SCE_LUA_COMMENTLINE || initStyle == SCE_LUA_PREPROCESSOR) { initStyle = SCE_LUA_DEFAULT; } StyleContext sc(startPos, length, initStyle, styler); if (startPos == 0 && sc.ch == '#') { // shbang line: # is a comment only if first char of the script sc.SetState(SCE_LUA_COMMENTLINE); } for (; sc.More(); sc.Forward()) { if (sc.atLineEnd) { // Update the line state, so it can be seen by next line currentLine = styler.GetLine(sc.currentPos); switch (sc.state) { case SCE_LUA_LITERALSTRING: case SCE_LUA_COMMENT: case SCE_LUA_STRING: case SCE_LUA_CHARACTER: // Inside a literal string, block comment or string, we set the line state styler.SetLineState(currentLine, (nestLevel << 9) | stringWs | sepCount); break; default: // Reset the line state styler.SetLineState(currentLine, 0); break; } } if (sc.atLineStart && (sc.state == SCE_LUA_STRING)) { // Prevent SCE_LUA_STRINGEOL from leaking back to previous line sc.SetState(SCE_LUA_STRING); } // Handle string line continuation if ((sc.state == SCE_LUA_STRING || sc.state == SCE_LUA_CHARACTER) && sc.ch == '\\') { if (sc.chNext == '\n' || sc.chNext == '\r') { sc.Forward(); if (sc.ch == '\r' && sc.chNext == '\n') { sc.Forward(); } continue; } } // Determine if the current state should terminate. if (sc.state == SCE_LUA_OPERATOR) { if (sc.ch == ':' && sc.chPrev == ':') { // :: <label> :: forward scan sc.Forward(); int ln = 0, maxln = startPos + length - sc.currentPos; int c; while (ln < maxln) { // determine line extent c = sc.GetRelative(ln); if (c == '\r' || c == '\n') break; ln++; } maxln = ln; ln = 0; while (ln < maxln) { // skip over spaces/tabs if (!IsASpaceOrTab(sc.GetRelative(ln))) break; ln++; } int ws1 = ln; if (setWordStart.Contains(sc.GetRelative(ln))) { int i = 0; char s[100]; while (ln < maxln) { // get potential label c = sc.GetRelative(ln); if (!setWord.Contains(c)) break; if (i < 90) s[i++] = c; ln++; } s[i] = '\0'; int lbl = ln; if (!keywords.InList(s)) { while (ln < maxln) { // skip over spaces/tabs if (!IsASpaceOrTab(sc.GetRelative(ln))) break; ln++; } int ws2 = ln - lbl; if (sc.GetRelative(ln) == ':' && sc.GetRelative(ln + 1) == ':') { // final :: found, complete valid label construct sc.ChangeState(SCE_LUA_LABEL); if (ws1) { sc.SetState(SCE_LUA_DEFAULT); sc.Forward(ws1); } sc.SetState(SCE_LUA_LABEL); sc.Forward(lbl - ws1); if (ws2) { sc.SetState(SCE_LUA_DEFAULT); sc.Forward(ws2); } sc.SetState(SCE_LUA_LABEL); sc.Forward(2); } } } } sc.SetState(SCE_LUA_DEFAULT); } else if (sc.state == SCE_LUA_NUMBER) { // We stop the number definition on non-numerical non-dot non-eEpP non-sign non-hexdigit char if (!setNumber.Contains(sc.ch)) { sc.SetState(SCE_LUA_DEFAULT); } else if (sc.ch == '-' || sc.ch == '+') { if (!setExponent.Contains(sc.chPrev)) sc.SetState(SCE_LUA_DEFAULT); } } else if (sc.state == SCE_LUA_IDENTIFIER) { if (!(setWord.Contains(sc.ch) || sc.ch == '.') || sc.Match('.', '.')) { char s[100]; sc.GetCurrent(s, sizeof(s)); if (keywords.InList(s)) { sc.ChangeState(SCE_LUA_WORD); if (strcmp(s, "goto") == 0) { // goto <label> forward scan sc.SetState(SCE_LUA_DEFAULT); while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) sc.Forward(); if (setWordStart.Contains(sc.ch)) { sc.SetState(SCE_LUA_LABEL); sc.Forward(); while (setWord.Contains(sc.ch)) sc.Forward(); sc.GetCurrent(s, sizeof(s)); if (keywords.InList(s)) sc.ChangeState(SCE_LUA_WORD); } sc.SetState(SCE_LUA_DEFAULT); } } else if (keywords2.InList(s)) { sc.ChangeState(SCE_LUA_WORD2); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_LUA_WORD3); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_LUA_WORD4); } else if (keywords5.InList(s)) { sc.ChangeState(SCE_LUA_WORD5); } else if (keywords6.InList(s)) { sc.ChangeState(SCE_LUA_WORD6); } else if (keywords7.InList(s)) { sc.ChangeState(SCE_LUA_WORD7); } else if (keywords8.InList(s)) { sc.ChangeState(SCE_LUA_WORD8); } sc.SetState(SCE_LUA_DEFAULT); } } else if (sc.state == SCE_LUA_COMMENTLINE || sc.state == SCE_LUA_PREPROCESSOR) { if (sc.atLineEnd) { sc.ForwardSetState(SCE_LUA_DEFAULT); } } else if (sc.state == SCE_LUA_STRING) { if (stringWs) { if (!IsASpace(sc.ch)) stringWs = 0; } if (sc.ch == '\\') { if (setEscapeSkip.Contains(sc.chNext)) { sc.Forward(); } else if (sc.chNext == 'z') { sc.Forward(); stringWs = 0x100; } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_LUA_DEFAULT); } else if (stringWs == 0 && sc.atLineEnd) { sc.ChangeState(SCE_LUA_STRINGEOL); sc.ForwardSetState(SCE_LUA_DEFAULT); } } else if (sc.state == SCE_LUA_CHARACTER) { if (stringWs) { if (!IsASpace(sc.ch)) stringWs = 0; } if (sc.ch == '\\') { if (setEscapeSkip.Contains(sc.chNext)) { sc.Forward(); } else if (sc.chNext == 'z') { sc.Forward(); stringWs = 0x100; } } else if (sc.ch == '\'') { sc.ForwardSetState(SCE_LUA_DEFAULT); } else if (stringWs == 0 && sc.atLineEnd) { sc.ChangeState(SCE_LUA_STRINGEOL); sc.ForwardSetState(SCE_LUA_DEFAULT); } } else if (sc.state == SCE_LUA_LITERALSTRING || sc.state == SCE_LUA_COMMENT) { if (sc.ch == '[') { int sep = LongDelimCheck(sc); if (sep == 1 && sepCount == 1) { // [[-only allowed to nest nestLevel++; sc.Forward(); } } else if (sc.ch == ']') { int sep = LongDelimCheck(sc); if (sep == 1 && sepCount == 1) { // un-nest with ]]-only nestLevel--; sc.Forward(); if (nestLevel == 0) { sc.ForwardSetState(SCE_LUA_DEFAULT); } } else if (sep > 1 && sep == sepCount) { // ]=]-style delim sc.Forward(sep); sc.ForwardSetState(SCE_LUA_DEFAULT); } } } // Determine if a new state should be entered. if (sc.state == SCE_LUA_DEFAULT) { if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_LUA_NUMBER); if (sc.ch == '0' && toupper(sc.chNext) == 'X') { sc.Forward(); } } else if (setWordStart.Contains(sc.ch)) { sc.SetState(SCE_LUA_IDENTIFIER); } else if (sc.ch == '\"') { sc.SetState(SCE_LUA_STRING); stringWs = 0; } else if (sc.ch == '\'') { sc.SetState(SCE_LUA_CHARACTER); stringWs = 0; } else if (sc.ch == '[') { sepCount = LongDelimCheck(sc); if (sepCount == 0) { sc.SetState(SCE_LUA_OPERATOR); } else { nestLevel = 1; sc.SetState(SCE_LUA_LITERALSTRING); sc.Forward(sepCount); } } else if (sc.Match('-', '-')) { sc.SetState(SCE_LUA_COMMENTLINE); if (sc.Match("--[")) { sc.Forward(2); sepCount = LongDelimCheck(sc); if (sepCount > 0) { nestLevel = 1; sc.ChangeState(SCE_LUA_COMMENT); sc.Forward(sepCount); } } else { sc.Forward(); } } else if (sc.atLineStart && sc.Match('$')) { sc.SetState(SCE_LUA_PREPROCESSOR); // Obsolete since Lua 4.0, but still in old code } else if (setLuaOperator.Contains(sc.ch)) { sc.SetState(SCE_LUA_OPERATOR); } } } if (setWord.Contains(sc.chPrev) || sc.chPrev == '.') { char s[100]; sc.GetCurrent(s, sizeof(s)); if (keywords.InList(s)) { sc.ChangeState(SCE_LUA_WORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_LUA_WORD2); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_LUA_WORD3); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_LUA_WORD4); } else if (keywords5.InList(s)) { sc.ChangeState(SCE_LUA_WORD5); } else if (keywords6.InList(s)) { sc.ChangeState(SCE_LUA_WORD6); } else if (keywords7.InList(s)) { sc.ChangeState(SCE_LUA_WORD7); } else if (keywords8.InList(s)) { sc.ChangeState(SCE_LUA_WORD8); } } sc.Complete(); } static void FoldLuaDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[], Accessor &styler) { unsigned int lengthDoc = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; int styleNext = styler.StyleAt(startPos); for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (style == SCE_LUA_WORD) { if (ch == 'i' || ch == 'd' || ch == 'f' || ch == 'e' || ch == 'r' || ch == 'u') { char s[10] = ""; for (unsigned int j = 0; j < 8; j++) { if (!iswordchar(styler[i + j])) { break; } s[j] = styler[i + j]; s[j + 1] = '\0'; } if ((strcmp(s, "if") == 0) || (strcmp(s, "do") == 0) || (strcmp(s, "function") == 0) || (strcmp(s, "repeat") == 0)) { levelCurrent++; } if ((strcmp(s, "end") == 0) || (strcmp(s, "elseif") == 0) || (strcmp(s, "until") == 0)) { levelCurrent--; } } } else if (style == SCE_LUA_OPERATOR) { if (ch == '{' || ch == '(') { levelCurrent++; } else if (ch == '}' || ch == ')') { levelCurrent--; } } else if (style == SCE_LUA_LITERALSTRING || style == SCE_LUA_COMMENT) { if (ch == '[') { levelCurrent++; } else if (ch == ']') { levelCurrent--; } } if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) { lev |= SC_FOLDLEVELWHITEFLAG; } if ((levelCurrent > levelPrev) && (visibleChars > 0)) { lev |= SC_FOLDLEVELHEADERFLAG; } if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) { visibleChars++; } } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char * const luaWordListDesc[] = { "Keywords", "Basic functions", "String, (table) & math functions", "(coroutines), I/O & system facilities", "user1", "user2", "user3", "user4", 0 }; LexerModule lmLua(SCLEX_LUA, ColouriseLuaDoc, "lua", FoldLuaDoc, luaWordListDesc); |
Added lexers/LexMMIXAL.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
// Scintilla source code edit control /** @file LexMMIXAL.cxx ** Lexer for MMIX Assembler Language. ** Written by Christoph Hsler <christoph.hoesler@student.uni-tuebingen.de> ** For information about MMIX visit http://www-cs-faculty.stanford.edu/~knuth/mmix.html **/ // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == ':' || ch == '_'); } inline bool isMMIXALOperator(char ch) { if (isascii(ch) && isalnum(ch)) return false; if (ch == '+' || ch == '-' || ch == '|' || ch == '^' || ch == '*' || ch == '/' || ch == '%' || ch == '<' || ch == '>' || ch == '&' || ch == '~' || ch == '$' || ch == ',' || ch == '(' || ch == ')' || ch == '[' || ch == ']') return true; return false; } static void ColouriseMMIXALDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &opcodes = *keywordlists[0]; WordList &special_register = *keywordlists[1]; WordList &predef_symbols = *keywordlists[2]; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { // No EOL continuation if (sc.atLineStart) { if (sc.ch == '@' && sc.chNext == 'i') { sc.SetState(SCE_MMIXAL_INCLUDE); } else { sc.SetState(SCE_MMIXAL_LEADWS); } } // Check if first non whitespace character in line is alphanumeric if (sc.state == SCE_MMIXAL_LEADWS && !isspace(sc.ch)) { // LEADWS if(!IsAWordChar(sc.ch)) { sc.SetState(SCE_MMIXAL_COMMENT); } else { if(sc.atLineStart) { sc.SetState(SCE_MMIXAL_LABEL); } else { sc.SetState(SCE_MMIXAL_OPCODE_PRE); } } } // Determine if the current state should terminate. if (sc.state == SCE_MMIXAL_OPERATOR) { // OPERATOR sc.SetState(SCE_MMIXAL_OPERANDS); } else if (sc.state == SCE_MMIXAL_NUMBER) { // NUMBER if (!isdigit(sc.ch)) { if (IsAWordChar(sc.ch)) { char s[100]; sc.GetCurrent(s, sizeof(s)); sc.ChangeState(SCE_MMIXAL_REF); sc.SetState(SCE_MMIXAL_REF); } else { sc.SetState(SCE_MMIXAL_OPERANDS); } } } else if (sc.state == SCE_MMIXAL_LABEL) { // LABEL if (!IsAWordChar(sc.ch) ) { sc.SetState(SCE_MMIXAL_OPCODE_PRE); } } else if (sc.state == SCE_MMIXAL_REF) { // REF if (!IsAWordChar(sc.ch) ) { char s[100]; sc.GetCurrent(s, sizeof(s)); if (*s == ':') { // ignore base prefix for match for (size_t i = 0; i != sizeof(s); ++i) { *(s+i) = *(s+i+1); } } if (special_register.InList(s)) { sc.ChangeState(SCE_MMIXAL_REGISTER); } else if (predef_symbols.InList(s)) { sc.ChangeState(SCE_MMIXAL_SYMBOL); } sc.SetState(SCE_MMIXAL_OPERANDS); } } else if (sc.state == SCE_MMIXAL_OPCODE_PRE) { // OPCODE_PRE if (!isspace(sc.ch)) { sc.SetState(SCE_MMIXAL_OPCODE); } } else if (sc.state == SCE_MMIXAL_OPCODE) { // OPCODE if (!IsAWordChar(sc.ch) ) { char s[100]; sc.GetCurrent(s, sizeof(s)); if (opcodes.InList(s)) { sc.ChangeState(SCE_MMIXAL_OPCODE_VALID); } else { sc.ChangeState(SCE_MMIXAL_OPCODE_UNKNOWN); } sc.SetState(SCE_MMIXAL_OPCODE_POST); } } else if (sc.state == SCE_MMIXAL_STRING) { // STRING if (sc.ch == '\"') { sc.ForwardSetState(SCE_MMIXAL_OPERANDS); } else if (sc.atLineEnd) { sc.ForwardSetState(SCE_MMIXAL_OPERANDS); } } else if (sc.state == SCE_MMIXAL_CHAR) { // CHAR if (sc.ch == '\'') { sc.ForwardSetState(SCE_MMIXAL_OPERANDS); } else if (sc.atLineEnd) { sc.ForwardSetState(SCE_MMIXAL_OPERANDS); } } else if (sc.state == SCE_MMIXAL_REGISTER) { // REGISTER if (!isdigit(sc.ch)) { sc.SetState(SCE_MMIXAL_OPERANDS); } } else if (sc.state == SCE_MMIXAL_HEX) { // HEX if (!isxdigit(sc.ch)) { sc.SetState(SCE_MMIXAL_OPERANDS); } } // Determine if a new state should be entered. if (sc.state == SCE_MMIXAL_OPCODE_POST || // OPCODE_POST sc.state == SCE_MMIXAL_OPERANDS) { // OPERANDS if (sc.state == SCE_MMIXAL_OPERANDS && isspace(sc.ch)) { if (!sc.atLineEnd) { sc.SetState(SCE_MMIXAL_COMMENT); } } else if (isdigit(sc.ch)) { sc.SetState(SCE_MMIXAL_NUMBER); } else if (IsAWordChar(sc.ch) || sc.Match('@')) { sc.SetState(SCE_MMIXAL_REF); } else if (sc.Match('\"')) { sc.SetState(SCE_MMIXAL_STRING); } else if (sc.Match('\'')) { sc.SetState(SCE_MMIXAL_CHAR); } else if (sc.Match('$')) { sc.SetState(SCE_MMIXAL_REGISTER); } else if (sc.Match('#')) { sc.SetState(SCE_MMIXAL_HEX); } else if (isMMIXALOperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_MMIXAL_OPERATOR); } } } sc.Complete(); } static const char * const MMIXALWordListDesc[] = { "Operation Codes", "Special Register", "Predefined Symbols", 0 }; LexerModule lmMMIXAL(SCLEX_MMIXAL, ColouriseMMIXALDoc, "mmixal", 0, MMIXALWordListDesc); |
Added lexers/LexMPT.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
// Scintilla source code edit control /** @file LexMPT.cxx ** Lexer for MPT specific files. Based on LexOthers.cxx ** LOT = the text log file created by the MPT application while running a test program ** Other MPT specific files to be added later. **/ // Copyright 2003 by Marius Gheorghe <mgheorghe@cabletest.com> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include <string> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static int GetLotLineState(std::string &line) { if (line.length()) { // Most of the time the first non-blank character in line determines that line's type // Now finds the first non-blank character unsigned i; // Declares counter here to make it persistent after the for loop for (i = 0; i < line.length(); ++i) { if (!(isascii(line[i]) && isspace(line[i]))) break; } // Checks if it was a blank line if (i == line.length()) return SCE_LOT_DEFAULT; switch (line[i]) { case '*': // Fail measurement return SCE_LOT_FAIL; case '+': // Header case '|': // Header return SCE_LOT_HEADER; case ':': // Set test limits return SCE_LOT_SET; case '-': // Section break return SCE_LOT_BREAK; default: // Any other line // Checks for message at the end of lot file if (line.find("PASSED") != std::string::npos) { return SCE_LOT_PASS; } else if (line.find("FAILED") != std::string::npos) { return SCE_LOT_FAIL; } else if (line.find("ABORTED") != std::string::npos) { return SCE_LOT_ABORT; } else { return i ? SCE_LOT_PASS : SCE_LOT_DEFAULT; } } } else { return SCE_LOT_DEFAULT; } } static void ColourizeLotDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { styler.StartAt(startPos); styler.StartSegment(startPos); bool atLineStart = true;// Arms the 'at line start' flag char chNext = styler.SafeGetCharAt(startPos); std::string line(""); line.reserve(256); // Lot lines are less than 256 chars long most of the time. This should avoid reallocations // Styles LOT document unsigned int i; // Declared here because it's used after the for loop for (i = startPos; i < startPos + length; ++i) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); line += ch; atLineStart = false; // LOT files are only used on the Win32 platform, thus EOL == CR+LF // Searches for the end of line if (ch == '\r' && chNext == '\n') { line += chNext; // Gets the '\n' ++i; // Advances past the '\n' chNext = styler.SafeGetCharAt(i + 1); // Gets character of next line styler.ColourTo(i, GetLotLineState(line)); line = ""; atLineStart = true; // Arms flag for next line } } // Last line may not have a line ending if (!atLineStart) { styler.ColourTo(i - 1, GetLotLineState(line)); } } // Folds an MPT LOT file: the blocks that can be folded are: // sections (headed by a set line) // passes (contiguous pass results within a section) // fails (contiguous fail results within a section) static void FoldLotDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { bool foldCompact = styler.GetPropertyInt("fold.compact", 0) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); char chNext = styler.SafeGetCharAt(startPos); int style = SCE_LOT_DEFAULT; int styleNext = styler.StyleAt(startPos); int lev = SC_FOLDLEVELBASE; // Gets style of previous line if not at the beginning of the document if (startPos > 1) style = styler.StyleAt(startPos - 2); for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if (ch == '\r' && chNext == '\n') { // TO DO: // Should really get the state of the previous line from the styler int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 2); switch (style) { /* case SCE_LOT_SET: lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG; break; */ case SCE_LOT_FAIL: /* if (stylePrev != SCE_LOT_FAIL) lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG; else lev = SC_FOLDLEVELBASE + 1; */ lev = SC_FOLDLEVELBASE; break; default: if (lineCurrent == 0 || stylePrev == SCE_LOT_FAIL) lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG; else lev = SC_FOLDLEVELBASE + 1; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; break; } if (lev != styler.LevelAt(lineCurrent)) styler.SetLevel(lineCurrent, lev); lineCurrent++; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, lev | flagsNext); } static const char * const emptyWordListDesc[] = { 0 }; LexerModule lmLot(SCLEX_LOT, ColourizeLotDoc, "lot", FoldLotDoc, emptyWordListDesc); |
Added lexers/LexMSSQL.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 |
// Scintilla source code edit control /** @file LexMSSQL.cxx ** Lexer for MSSQL. **/ // By Filip Yaghob <fyaghob@gmail.com> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif #define KW_MSSQL_STATEMENTS 0 #define KW_MSSQL_DATA_TYPES 1 #define KW_MSSQL_SYSTEM_TABLES 2 #define KW_MSSQL_GLOBAL_VARIABLES 3 #define KW_MSSQL_FUNCTIONS 4 #define KW_MSSQL_STORED_PROCEDURES 5 #define KW_MSSQL_OPERATORS 6 static bool isMSSQLOperator(char ch) { if (isascii(ch) && isalnum(ch)) return false; // '.' left out as it is used to make up numbers if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || ch == '-' || ch == '+' || ch == '=' || ch == '|' || ch == '<' || ch == '>' || ch == '/' || ch == '!' || ch == '~' || ch == '(' || ch == ')' || ch == ',') return true; return false; } static char classifyWordSQL(unsigned int start, unsigned int end, WordList *keywordlists[], Accessor &styler, unsigned int actualState, unsigned int prevState) { char s[256]; bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.'); WordList &kwStatements = *keywordlists[KW_MSSQL_STATEMENTS]; WordList &kwDataTypes = *keywordlists[KW_MSSQL_DATA_TYPES]; WordList &kwSystemTables = *keywordlists[KW_MSSQL_SYSTEM_TABLES]; WordList &kwGlobalVariables = *keywordlists[KW_MSSQL_GLOBAL_VARIABLES]; WordList &kwFunctions = *keywordlists[KW_MSSQL_FUNCTIONS]; WordList &kwStoredProcedures = *keywordlists[KW_MSSQL_STORED_PROCEDURES]; WordList &kwOperators = *keywordlists[KW_MSSQL_OPERATORS]; for (unsigned int i = 0; i < end - start + 1 && i < 128; i++) { s[i] = static_cast<char>(tolower(styler[start + i])); s[i + 1] = '\0'; } char chAttr = SCE_MSSQL_IDENTIFIER; if (actualState == SCE_MSSQL_GLOBAL_VARIABLE) { if (kwGlobalVariables.InList(&s[2])) chAttr = SCE_MSSQL_GLOBAL_VARIABLE; } else if (wordIsNumber) { chAttr = SCE_MSSQL_NUMBER; } else if (prevState == SCE_MSSQL_DEFAULT_PREF_DATATYPE) { // Look first in datatypes if (kwDataTypes.InList(s)) chAttr = SCE_MSSQL_DATATYPE; else if (kwOperators.InList(s)) chAttr = SCE_MSSQL_OPERATOR; else if (kwStatements.InList(s)) chAttr = SCE_MSSQL_STATEMENT; else if (kwSystemTables.InList(s)) chAttr = SCE_MSSQL_SYSTABLE; else if (kwFunctions.InList(s)) chAttr = SCE_MSSQL_FUNCTION; else if (kwStoredProcedures.InList(s)) chAttr = SCE_MSSQL_STORED_PROCEDURE; } else { if (kwOperators.InList(s)) chAttr = SCE_MSSQL_OPERATOR; else if (kwStatements.InList(s)) chAttr = SCE_MSSQL_STATEMENT; else if (kwSystemTables.InList(s)) chAttr = SCE_MSSQL_SYSTABLE; else if (kwFunctions.InList(s)) chAttr = SCE_MSSQL_FUNCTION; else if (kwStoredProcedures.InList(s)) chAttr = SCE_MSSQL_STORED_PROCEDURE; else if (kwDataTypes.InList(s)) chAttr = SCE_MSSQL_DATATYPE; } styler.ColourTo(end, chAttr); return chAttr; } static void ColouriseMSSQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { styler.StartAt(startPos); bool fold = styler.GetPropertyInt("fold") != 0; int lineCurrent = styler.GetLine(startPos); int spaceFlags = 0; int state = initStyle; int prevState = initStyle; char chPrev = ' '; char chNext = styler[startPos]; styler.StartSegment(startPos); unsigned int lengthDoc = startPos + length; for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags); int lev = indentCurrent; if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { // Only non whitespace lines can be headers int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags); if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) { lev |= SC_FOLDLEVELHEADERFLAG; } } if (fold) { styler.SetLevel(lineCurrent, lev); } } if (styler.IsLeadByte(ch)) { chNext = styler.SafeGetCharAt(i + 2); chPrev = ' '; i += 1; continue; } // When the last char isn't part of the state (have to deal with it too)... if ( (state == SCE_MSSQL_IDENTIFIER) || (state == SCE_MSSQL_STORED_PROCEDURE) || (state == SCE_MSSQL_DATATYPE) || //~ (state == SCE_MSSQL_COLUMN_NAME) || (state == SCE_MSSQL_FUNCTION) || //~ (state == SCE_MSSQL_GLOBAL_VARIABLE) || (state == SCE_MSSQL_VARIABLE)) { if (!iswordchar(ch)) { int stateTmp; if ((state == SCE_MSSQL_VARIABLE) || (state == SCE_MSSQL_COLUMN_NAME)) { styler.ColourTo(i - 1, state); stateTmp = state; } else stateTmp = classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState); prevState = state; if (stateTmp == SCE_MSSQL_IDENTIFIER || stateTmp == SCE_MSSQL_VARIABLE) state = SCE_MSSQL_DEFAULT_PREF_DATATYPE; else state = SCE_MSSQL_DEFAULT; } } else if (state == SCE_MSSQL_LINE_COMMENT) { if (ch == '\r' || ch == '\n') { styler.ColourTo(i - 1, state); prevState = state; state = SCE_MSSQL_DEFAULT; } } else if (state == SCE_MSSQL_GLOBAL_VARIABLE) { if ((ch != '@') && !iswordchar(ch)) { classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState); prevState = state; state = SCE_MSSQL_DEFAULT; } } // If is the default or one of the above succeeded if (state == SCE_MSSQL_DEFAULT || state == SCE_MSSQL_DEFAULT_PREF_DATATYPE) { if (iswordstart(ch)) { styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT); prevState = state; state = SCE_MSSQL_IDENTIFIER; } else if (ch == '/' && chNext == '*') { styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT); prevState = state; state = SCE_MSSQL_COMMENT; } else if (ch == '-' && chNext == '-') { styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT); prevState = state; state = SCE_MSSQL_LINE_COMMENT; } else if (ch == '\'') { styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT); prevState = state; state = SCE_MSSQL_STRING; } else if (ch == '"') { styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT); prevState = state; state = SCE_MSSQL_COLUMN_NAME; } else if (ch == '[') { styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT); prevState = state; state = SCE_MSSQL_COLUMN_NAME_2; } else if (isMSSQLOperator(ch)) { styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT); styler.ColourTo(i, SCE_MSSQL_OPERATOR); //~ style = SCE_MSSQL_DEFAULT; prevState = state; state = SCE_MSSQL_DEFAULT; } else if (ch == '@') { styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT); prevState = state; if (chNext == '@') { state = SCE_MSSQL_GLOBAL_VARIABLE; // i += 2; } else state = SCE_MSSQL_VARIABLE; } // When the last char is part of the state... } else if (state == SCE_MSSQL_COMMENT) { if (ch == '/' && chPrev == '*') { if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_MSSQL_COMMENT) && (styler.GetStartSegment() == startPos)))) { styler.ColourTo(i, state); //~ state = SCE_MSSQL_COMMENT; prevState = state; state = SCE_MSSQL_DEFAULT; } } } else if (state == SCE_MSSQL_STRING) { if (ch == '\'') { if ( chNext == '\'' ) { i++; ch = chNext; chNext = styler.SafeGetCharAt(i + 1); } else { styler.ColourTo(i, state); prevState = state; state = SCE_MSSQL_DEFAULT; //i++; } //ch = chNext; //chNext = styler.SafeGetCharAt(i + 1); } } else if (state == SCE_MSSQL_COLUMN_NAME) { if (ch == '"') { if (chNext == '"') { i++; ch = chNext; chNext = styler.SafeGetCharAt(i + 1); } else { styler.ColourTo(i, state); prevState = state; state = SCE_MSSQL_DEFAULT_PREF_DATATYPE; //i++; } } } else if (state == SCE_MSSQL_COLUMN_NAME_2) { if (ch == ']') { styler.ColourTo(i, state); prevState = state; state = SCE_MSSQL_DEFAULT_PREF_DATATYPE; //i++; } } chPrev = ch; } styler.ColourTo(lengthDoc - 1, state); } static void FoldMSSQLDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; bool inComment = (styler.StyleAt(startPos-1) == SCE_MSSQL_COMMENT); char s[10]; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int style = styler.StyleAt(i); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); // Comment folding if (foldComment) { if (!inComment && (style == SCE_MSSQL_COMMENT)) levelCurrent++; else if (inComment && (style != SCE_MSSQL_COMMENT)) levelCurrent--; inComment = (style == SCE_MSSQL_COMMENT); } if (style == SCE_MSSQL_STATEMENT) { // Folding between begin or case and end if (ch == 'b' || ch == 'B' || ch == 'c' || ch == 'C' || ch == 'e' || ch == 'E') { for (unsigned int j = 0; j < 5; j++) { if (!iswordchar(styler[i + j])) { break; } s[j] = static_cast<char>(tolower(styler[i + j])); s[j + 1] = '\0'; } if ((strcmp(s, "begin") == 0) || (strcmp(s, "case") == 0)) { levelCurrent++; } if (strcmp(s, "end") == 0) { levelCurrent--; } } } if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char * const sqlWordListDesc[] = { "Statements", "Data Types", "System tables", "Global variables", "Functions", "System Stored Procedures", "Operators", 0, }; LexerModule lmMSSQL(SCLEX_MSSQL, ColouriseMSSQLDoc, "mssql", FoldMSSQLDoc, sqlWordListDesc); |
Added lexers/LexMagik.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 |
// Scintilla source code edit control /** * @file LexMagik.cxx * Lexer for GE(r) Smallworld(tm) MagikSF */ // Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif /** * Is it a core character (C isalpha(), exclamation and question mark) * * \param ch The character * \return True if ch is a character, False otherwise */ static inline bool IsAlphaCore(int ch) { return (isalpha(ch) || ch == '!' || ch == '?'); } /** * Is it a character (IsAlphaCore() and underscore) * * \param ch The character * \return True if ch is a character, False otherwise */ static inline bool IsAlpha(int ch) { return (IsAlphaCore(ch) || ch == '_'); } /** * Is it a symbolic character (IsAlpha() and colon) * * \param ch The character * \return True if ch is a character, False otherwise */ static inline bool IsAlphaSym(int ch) { return (IsAlpha(ch) || ch == ':'); } /** * Is it a numerical character (IsAlpha() and 0 - 9) * * \param ch The character * \return True if ch is a character, False otherwise */ static inline bool IsAlNum(int ch) { return ((ch >= '0' && ch <= '9') || IsAlpha(ch)); } /** * Is it a symbolic numerical character (IsAlNum() and colon) * * \param ch The character * \return True if ch is a character, False otherwise */ static inline bool IsAlNumSym(int ch) { return (IsAlNum(ch) || ch == ':'); } /** * The lexer function * * \param startPos Where to start scanning * \param length Where to scan to * \param initStyle The style at the initial point, not used in this folder * \param keywordslists The keywordslists, currently, number 5 is used * \param styler The styler */ static void ColouriseMagikDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { styler.StartAt(startPos); WordList &keywords = *keywordlists[0]; WordList &pragmatics = *keywordlists[1]; WordList &containers = *keywordlists[2]; WordList &flow = *keywordlists[3]; WordList &characters = *keywordlists[4]; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { repeat: if(sc.ch == '#') { if (sc.chNext == '#') sc.SetState(SCE_MAGIK_HYPER_COMMENT); else sc.SetState(SCE_MAGIK_COMMENT); for(; sc.More() && !(sc.atLineEnd); sc.Forward()); sc.SetState(SCE_MAGIK_DEFAULT); goto repeat; } if(sc.ch == '"') { sc.SetState(SCE_MAGIK_STRING); if(sc.More()) { sc.Forward(); for(; sc.More() && sc.ch != '"'; sc.Forward()); } sc.ForwardSetState(SCE_MAGIK_DEFAULT); goto repeat; } // The default state if(sc.state == SCE_MAGIK_DEFAULT) { // A certain keyword has been detected if (sc.ch == '_' && ( sc.currentPos == 0 || !IsAlNum(sc.chPrev))) { char keyword[50]; memset(keyword, '\0', 50); for( int scanPosition = 0; scanPosition < 50; scanPosition++) { char keywordChar = static_cast<char>( tolower(styler.SafeGetCharAt( scanPosition + static_cast<int>(sc.currentPos+1), ' '))); if(IsAlpha(keywordChar)) { keyword[scanPosition] = keywordChar; } else { break; } } // It is a pragma if(pragmatics.InList(keyword)) { sc.SetState(SCE_MAGIK_PRAGMA); } // it is a normal keyword like _local, _self, etc. else if(keywords.InList(keyword)) { sc.SetState(SCE_MAGIK_KEYWORD); } // It is a container keyword, such as _method, _proc, etc. else if(containers.InList(keyword)) { sc.SetState(SCE_MAGIK_CONTAINER); } // It is a flow keyword, such as _for, _if, _try, etc. else if(flow.InList(keyword)) { sc.SetState(SCE_MAGIK_FLOW); } // Interpret as unknown keyword else { sc.SetState(SCE_MAGIK_UNKNOWN_KEYWORD); } } // Symbolic expression else if(sc.ch == ':' && !IsAlNum(sc.chPrev)) { sc.SetState(SCE_MAGIK_SYMBOL); bool firstTrip = true; for(sc.Forward(); sc.More(); sc.Forward()) { if(firstTrip && IsAlphaSym(sc.ch)); else if(!firstTrip && IsAlNumSym(sc.ch)); else if(sc.ch == '|') { for(sc.Forward(); sc.More() && sc.ch != '|'; sc.Forward()); } else break; firstTrip = false; } sc.SetState(SCE_MAGIK_DEFAULT); goto repeat; } // Identifier (label) expression else if(sc.ch == '@') { sc.SetState(SCE_MAGIK_IDENTIFIER); bool firstTrip = true; for(sc.Forward(); sc.More(); sc.Forward()) { if(firstTrip && IsAlphaCore(sc.ch)) { firstTrip = false; } else if(!firstTrip && IsAlpha(sc.ch)); else break; } sc.SetState(SCE_MAGIK_DEFAULT); goto repeat; } // Start of a character else if(sc.ch == '%') { sc.SetState(SCE_MAGIK_CHARACTER); sc.Forward(); char keyword[50]; memset(keyword, '\0', 50); for( int scanPosition = 0; scanPosition < 50; scanPosition++) { char keywordChar = static_cast<char>( tolower(styler.SafeGetCharAt( scanPosition + static_cast<int>(sc.currentPos), ' '))); if(IsAlpha(keywordChar)) { keyword[scanPosition] = keywordChar; } else { break; } } if(characters.InList(keyword)) { sc.Forward(static_cast<int>(strlen(keyword))); } else { sc.Forward(); } sc.SetState(SCE_MAGIK_DEFAULT); goto repeat; } // Operators else if( sc.ch == '>' || sc.ch == '<' || sc.ch == '.' || sc.ch == ',' || sc.ch == '+' || sc.ch == '-' || sc.ch == '/' || sc.ch == '*' || sc.ch == '~' || sc.ch == '$' || sc.ch == '=') { sc.SetState(SCE_MAGIK_OPERATOR); } // Braces else if(sc.ch == '(' || sc.ch == ')') { sc.SetState(SCE_MAGIK_BRACE_BLOCK); } // Brackets else if(sc.ch == '{' || sc.ch == '}') { sc.SetState(SCE_MAGIK_BRACKET_BLOCK); } // Square Brackets else if(sc.ch == '[' || sc.ch == ']') { sc.SetState(SCE_MAGIK_SQBRACKET_BLOCK); } } // It is an operator else if( sc.state == SCE_MAGIK_OPERATOR || sc.state == SCE_MAGIK_BRACE_BLOCK || sc.state == SCE_MAGIK_BRACKET_BLOCK || sc.state == SCE_MAGIK_SQBRACKET_BLOCK) { sc.SetState(SCE_MAGIK_DEFAULT); goto repeat; } // It is the pragma state else if(sc.state == SCE_MAGIK_PRAGMA) { if(!IsAlpha(sc.ch)) { sc.SetState(SCE_MAGIK_DEFAULT); goto repeat; } } // It is the keyword state else if( sc.state == SCE_MAGIK_KEYWORD || sc.state == SCE_MAGIK_CONTAINER || sc.state == SCE_MAGIK_FLOW || sc.state == SCE_MAGIK_UNKNOWN_KEYWORD) { if(!IsAlpha(sc.ch)) { sc.SetState(SCE_MAGIK_DEFAULT); goto repeat; } } } sc.Complete(); } /** * The word list description */ static const char * const magikWordListDesc[] = { "Accessors (local, global, self, super, thisthread)", "Pragmatic (pragma, private)", "Containers (method, block, proc)", "Flow (if, then, elif, else)", "Characters (space, tab, newline, return)", "Fold Containers (method, proc, block, if, loop)", 0}; /** * This function detects keywords which are able to have a body. Note that it * uses the Fold Containers word description, not the containers description. It * only works when the style at that particular position is set on Containers * or Flow (number 3 or 4). * * \param keywordslist The list of keywords that are scanned, they should only * contain the start keywords, not the end keywords * \param The actual keyword * \return 1 if it is a folding start-keyword, -1 if it is a folding end-keyword * 0 otherwise */ static inline int IsFoldingContainer(WordList &keywordslist, char * keyword) { if( strlen(keyword) > 3 && keyword[0] == 'e' && keyword[1] == 'n' && keyword[2] == 'd') { if (keywordslist.InList(keyword + 3)) { return -1; } } else { if(keywordslist.InList(keyword)) { return 1; } } return 0; } /** * The folding function * * \param startPos Where to start scanning * \param length Where to scan to * \param keywordslists The keywordslists, currently, number 5 is used * \param styler The styler */ static void FoldMagikDoc(unsigned int startPos, int length, int, WordList *keywordslists[], Accessor &styler) { bool compact = styler.GetPropertyInt("fold.compact") != 0; WordList &foldingElements = *keywordslists[5]; int endPos = startPos + length; int line = styler.GetLine(startPos); int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK; int flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK; for( int currentPos = startPos; currentPos < endPos; currentPos++) { char currentState = styler.StyleAt(currentPos); char c = styler.SafeGetCharAt(currentPos, ' '); int prevLine = styler.GetLine(currentPos - 1); line = styler.GetLine(currentPos); // Default situation if(prevLine < line) { styler.SetLevel(line, (level|flags) & ~SC_FOLDLEVELHEADERFLAG); flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK; } if( ( currentState == SCE_MAGIK_CONTAINER || currentState == SCE_MAGIK_FLOW ) && c == '_') { char keyword[50]; memset(keyword, '\0', 50); for( int scanPosition = 0; scanPosition < 50; scanPosition++) { char keywordChar = static_cast<char>( tolower(styler.SafeGetCharAt( scanPosition + currentPos + 1, ' '))); if(IsAlpha(keywordChar)) { keyword[scanPosition] = keywordChar; } else { break; } } if(IsFoldingContainer(foldingElements, keyword) > 0) { styler.SetLevel( line, styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG); level++; } else if(IsFoldingContainer(foldingElements, keyword) < 0) { styler.SetLevel(line, styler.LevelAt(line)); level--; } } if( compact && ( currentState == SCE_MAGIK_BRACE_BLOCK || currentState == SCE_MAGIK_BRACKET_BLOCK || currentState == SCE_MAGIK_SQBRACKET_BLOCK)) { if(c == '{' || c == '[' || c == '(') { styler.SetLevel( line, styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG); level++; } else if(c == '}' || c == ']' || c == ')') { styler.SetLevel(line, styler.LevelAt(line)); level--; } } } } /** * Injecting the module */ LexerModule lmMagikSF( SCLEX_MAGIK, ColouriseMagikDoc, "magiksf", FoldMagikDoc, magikWordListDesc); |
Added lexers/LexMarkdown.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 |
/****************************************************************** * LexMarkdown.cxx * * A simple Markdown lexer for scintilla. * * Includes highlighting for some extra features from the * Pandoc implementation; strikeout, using '#.' as a default * ordered list item marker, and delimited code blocks. * * Limitations: * * Standard indented code blocks are not highlighted at all, * as it would conflict with other indentation schemes. Use * delimited code blocks for blanket highlighting of an * entire code block. Embedded HTML is not highlighted either. * Blanket HTML highlighting has issues, because some Markdown * implementations allow Markdown markup inside of the HTML. Also, * there is a following blank line issue that can't be ignored, * explained in the next paragraph. Embedded HTML and code * blocks would be better supported with language specific * highlighting. * * The highlighting aims to accurately reflect correct syntax, * but a few restrictions are relaxed. Delimited code blocks are * highlighted, even if the line following the code block is not blank. * Requiring a blank line after a block, breaks the highlighting * in certain cases, because of the way Scintilla ends up calling * the lexer. * * Written by Jon Strait - jstrait@moonloop.net * * The License.txt file describes the conditions under which this * software may be distributed. * *****************************************************************/ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsNewline(const int ch) { return (ch == '\n' || ch == '\r'); } // True if can follow ch down to the end with possibly trailing whitespace static bool FollowToLineEnd(const int ch, const int state, const unsigned int endPos, StyleContext &sc) { unsigned int i = 0; while (sc.GetRelative(++i) == ch) ; // Skip over whitespace while (IsASpaceOrTab(sc.GetRelative(i)) && sc.currentPos + i < endPos) ++i; if (IsNewline(sc.GetRelative(i)) || sc.currentPos + i == endPos) { sc.Forward(i); sc.ChangeState(state); sc.SetState(SCE_MARKDOWN_LINE_BEGIN); return true; } else return false; } // Set the state on text section from current to length characters, // then set the rest until the newline to default, except for any characters matching token static void SetStateAndZoom(const int state, const int length, const int token, StyleContext &sc) { sc.SetState(state); sc.Forward(length); sc.SetState(SCE_MARKDOWN_DEFAULT); sc.Forward(); bool started = false; while (sc.More() && !IsNewline(sc.ch)) { if (sc.ch == token && !started) { sc.SetState(state); started = true; } else if (sc.ch != token) { sc.SetState(SCE_MARKDOWN_DEFAULT); started = false; } sc.Forward(); } sc.SetState(SCE_MARKDOWN_LINE_BEGIN); } // Does the previous line have more than spaces and tabs? static bool HasPrevLineContent(StyleContext &sc) { int i = 0; // Go back to the previous newline while ((--i + (int)sc.currentPos) >= 0 && !IsNewline(sc.GetRelative(i))) ; while ((--i + (int)sc.currentPos) >= 0) { if (IsNewline(sc.GetRelative(i))) break; if (!IsASpaceOrTab(sc.GetRelative(i))) return true; } return false; } static bool AtTermStart(StyleContext &sc) { return sc.currentPos == 0 || isspacechar(sc.chPrev); } static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) { int c, count = 1; unsigned int i = 0; while (++i) { c = sc.GetRelative(i); if (c == sc.ch) ++count; // hit a terminating character else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) { // Are we a valid HRULE if ((IsNewline(c) || sc.currentPos + i == endPos) && count >= 3 && !HasPrevLineContent(sc)) { sc.SetState(SCE_MARKDOWN_HRULE); sc.Forward(i); sc.SetState(SCE_MARKDOWN_LINE_BEGIN); return true; } else { sc.SetState(SCE_MARKDOWN_DEFAULT); return false; } } } return false; } static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle, WordList **, Accessor &styler) { unsigned int endPos = startPos + length; int precharCount = 0; // Don't advance on a new loop iteration and retry at the same position. // Useful in the corner case of having to start at the beginning file position // in the default state. bool freezeCursor = false; StyleContext sc(startPos, length, initStyle, styler); while (sc.More()) { // Skip past escaped characters if (sc.ch == '\\') { sc.Forward(); continue; } // A blockquotes resets the line semantics if (sc.state == SCE_MARKDOWN_BLOCKQUOTE) sc.SetState(SCE_MARKDOWN_LINE_BEGIN); // Conditional state-based actions if (sc.state == SCE_MARKDOWN_CODE2) { if (sc.Match("``") && sc.GetRelative(-2) != ' ') { sc.Forward(2); sc.SetState(SCE_MARKDOWN_DEFAULT); } } else if (sc.state == SCE_MARKDOWN_CODE) { if (sc.ch == '`' && sc.chPrev != ' ') sc.ForwardSetState(SCE_MARKDOWN_DEFAULT); } /* De-activated because it gets in the way of other valid indentation * schemes, for example multiple paragraphs inside a list item. // Code block else if (sc.state == SCE_MARKDOWN_CODEBK) { bool d = true; if (IsNewline(sc.ch)) { if (sc.chNext != '\t') { for (int c = 1; c < 5; ++c) { if (sc.GetRelative(c) != ' ') d = false; } } } else if (sc.atLineStart) { if (sc.ch != '\t' ) { for (int i = 0; i < 4; ++i) { if (sc.GetRelative(i) != ' ') d = false; } } } if (!d) sc.SetState(SCE_MARKDOWN_LINE_BEGIN); } */ // Strong else if (sc.state == SCE_MARKDOWN_STRONG1) { if (sc.Match("**") && sc.chPrev != ' ') { sc.Forward(2); sc.SetState(SCE_MARKDOWN_DEFAULT); } } else if (sc.state == SCE_MARKDOWN_STRONG2) { if (sc.Match("__") && sc.chPrev != ' ') { sc.Forward(2); sc.SetState(SCE_MARKDOWN_DEFAULT); } } // Emphasis else if (sc.state == SCE_MARKDOWN_EM1) { if (sc.ch == '*' && sc.chPrev != ' ') sc.ForwardSetState(SCE_MARKDOWN_DEFAULT); } else if (sc.state == SCE_MARKDOWN_EM2) { if (sc.ch == '_' && sc.chPrev != ' ') sc.ForwardSetState(SCE_MARKDOWN_DEFAULT); } else if (sc.state == SCE_MARKDOWN_CODEBK) { if (sc.atLineStart && sc.Match("~~~")) { int i = 1; while (!IsNewline(sc.GetRelative(i)) && sc.currentPos + i < endPos) i++; sc.Forward(i); sc.SetState(SCE_MARKDOWN_DEFAULT); } } else if (sc.state == SCE_MARKDOWN_STRIKEOUT) { if (sc.Match("~~") && sc.chPrev != ' ') { sc.Forward(2); sc.SetState(SCE_MARKDOWN_DEFAULT); } } else if (sc.state == SCE_MARKDOWN_LINE_BEGIN) { // Header if (sc.Match("######")) SetStateAndZoom(SCE_MARKDOWN_HEADER6, 6, '#', sc); else if (sc.Match("#####")) SetStateAndZoom(SCE_MARKDOWN_HEADER5, 5, '#', sc); else if (sc.Match("####")) SetStateAndZoom(SCE_MARKDOWN_HEADER4, 4, '#', sc); else if (sc.Match("###")) SetStateAndZoom(SCE_MARKDOWN_HEADER3, 3, '#', sc); else if (sc.Match("##")) SetStateAndZoom(SCE_MARKDOWN_HEADER2, 2, '#', sc); else if (sc.Match("#")) { // Catch the special case of an unordered list if (sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) { precharCount = 0; sc.SetState(SCE_MARKDOWN_PRECHAR); } else SetStateAndZoom(SCE_MARKDOWN_HEADER1, 1, '#', sc); } // Code block else if (sc.Match("~~~")) { if (!HasPrevLineContent(sc)) sc.SetState(SCE_MARKDOWN_CODEBK); else sc.SetState(SCE_MARKDOWN_DEFAULT); } else if (sc.ch == '=') { if (HasPrevLineContent(sc) && FollowToLineEnd('=', SCE_MARKDOWN_HEADER1, endPos, sc)) ; else sc.SetState(SCE_MARKDOWN_DEFAULT); } else if (sc.ch == '-') { if (HasPrevLineContent(sc) && FollowToLineEnd('-', SCE_MARKDOWN_HEADER2, endPos, sc)) ; else { precharCount = 0; sc.SetState(SCE_MARKDOWN_PRECHAR); } } else if (IsNewline(sc.ch)) sc.SetState(SCE_MARKDOWN_LINE_BEGIN); else { precharCount = 0; sc.SetState(SCE_MARKDOWN_PRECHAR); } } // The header lasts until the newline else if (sc.state == SCE_MARKDOWN_HEADER1 || sc.state == SCE_MARKDOWN_HEADER2 || sc.state == SCE_MARKDOWN_HEADER3 || sc.state == SCE_MARKDOWN_HEADER4 || sc.state == SCE_MARKDOWN_HEADER5 || sc.state == SCE_MARKDOWN_HEADER6) { if (IsNewline(sc.ch)) sc.SetState(SCE_MARKDOWN_LINE_BEGIN); } // New state only within the initial whitespace if (sc.state == SCE_MARKDOWN_PRECHAR) { // Blockquote if (sc.ch == '>' && precharCount < 5) sc.SetState(SCE_MARKDOWN_BLOCKQUOTE); /* // Begin of code block else if (!HasPrevLineContent(sc) && (sc.chPrev == '\t' || precharCount >= 4)) sc.SetState(SCE_MARKDOWN_CODEBK); */ // HRule - Total of three or more hyphens, asterisks, or underscores // on a line by themselves else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '_') && IsValidHrule(endPos, sc)) ; // Unordered list else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '+') && IsASpaceOrTab(sc.chNext)) { sc.SetState(SCE_MARKDOWN_ULIST_ITEM); sc.ForwardSetState(SCE_MARKDOWN_DEFAULT); } // Ordered list else if (IsADigit(sc.ch)) { int digitCount = 0; while (IsADigit(sc.GetRelative(++digitCount))) ; if (sc.GetRelative(digitCount) == '.' && IsASpaceOrTab(sc.GetRelative(digitCount + 1))) { sc.SetState(SCE_MARKDOWN_OLIST_ITEM); sc.Forward(digitCount + 1); sc.SetState(SCE_MARKDOWN_DEFAULT); } } // Alternate Ordered list else if (sc.ch == '#' && sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) { sc.SetState(SCE_MARKDOWN_OLIST_ITEM); sc.Forward(2); sc.SetState(SCE_MARKDOWN_DEFAULT); } else if (sc.ch != ' ' || precharCount > 2) sc.SetState(SCE_MARKDOWN_DEFAULT); else ++precharCount; } // New state anywhere in doc if (sc.state == SCE_MARKDOWN_DEFAULT) { if (sc.atLineStart && sc.ch == '#') { sc.SetState(SCE_MARKDOWN_LINE_BEGIN); freezeCursor = true; } // Links and Images if (sc.Match("![") || sc.ch == '[') { int i = 0, j = 0, k = 0; int len = endPos - sc.currentPos; while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\')) ; if (sc.GetRelative(i) == ']') { j = i; if (sc.GetRelative(++i) == '(') { while (i < len && (sc.GetRelative(++i) != ')' || sc.GetRelative(i - 1) == '\\')) ; if (sc.GetRelative(i) == ')') k = i; } else if (sc.GetRelative(i) == '[' || sc.GetRelative(++i) == '[') { while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\')) ; if (sc.GetRelative(i) == ']') k = i; } } // At least a link text if (j) { sc.SetState(SCE_MARKDOWN_LINK); sc.Forward(j); // Also has a URL or reference portion if (k) sc.Forward(k - j); sc.ForwardSetState(SCE_MARKDOWN_DEFAULT); } } // Code - also a special case for alternate inside spacing if (sc.Match("``") && sc.GetRelative(3) != ' ' && AtTermStart(sc)) { sc.SetState(SCE_MARKDOWN_CODE2); sc.Forward(); } else if (sc.ch == '`' && sc.chNext != ' ' && AtTermStart(sc)) { sc.SetState(SCE_MARKDOWN_CODE); } // Strong else if (sc.Match("**") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) { sc.SetState(SCE_MARKDOWN_STRONG1); sc.Forward(); } else if (sc.Match("__") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) { sc.SetState(SCE_MARKDOWN_STRONG2); sc.Forward(); } // Emphasis else if (sc.ch == '*' && sc.chNext != ' ' && AtTermStart(sc)) { sc.SetState(SCE_MARKDOWN_EM1); } else if (sc.ch == '_' && sc.chNext != ' ' && AtTermStart(sc)) { sc.SetState(SCE_MARKDOWN_EM2); } // Strikeout else if (sc.Match("~~") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) { sc.SetState(SCE_MARKDOWN_STRIKEOUT); sc.Forward(); } // Beginning of line else if (IsNewline(sc.ch)) { sc.SetState(SCE_MARKDOWN_LINE_BEGIN); } } // Advance if not holding back the cursor for this iteration. if (!freezeCursor) sc.Forward(); freezeCursor = false; } sc.Complete(); } LexerModule lmMarkdown(SCLEX_MARKDOWN, ColorizeMarkdownDoc, "markdown"); |
Added lexers/LexMatlab.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
// Scintilla source code edit control /** @file LexMatlab.cxx ** Lexer for Matlab. ** Written by Jos Fonseca ** ** Changes by Christoph Dalitz 2003/12/04: ** - added support for Octave ** - Strings can now be included both in single or double quotes **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static bool IsMatlabCommentChar(int c) { return (c == '%') ; } static bool IsOctaveCommentChar(int c) { return (c == '%' || c == '#') ; } static bool IsMatlabComment(Accessor &styler, int pos, int len) { return len > 0 && IsMatlabCommentChar(styler[pos]) ; } static bool IsOctaveComment(Accessor &styler, int pos, int len) { return len > 0 && IsOctaveCommentChar(styler[pos]) ; } static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_'); } static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_'); } static void ColouriseMatlabOctaveDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler, bool (*IsCommentChar)(int)) { WordList &keywords = *keywordlists[0]; styler.StartAt(startPos); bool transpose = false; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.state == SCE_MATLAB_OPERATOR) { if (sc.chPrev == '.') { if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') { sc.ForwardSetState(SCE_MATLAB_DEFAULT); transpose = false; } else if (sc.ch == '\'') { sc.ForwardSetState(SCE_MATLAB_DEFAULT); transpose = true; } else { sc.SetState(SCE_MATLAB_DEFAULT); } } else { sc.SetState(SCE_MATLAB_DEFAULT); } } else if (sc.state == SCE_MATLAB_KEYWORD) { if (!isalnum(sc.ch) && sc.ch != '_') { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (keywords.InList(s)) { sc.SetState(SCE_MATLAB_DEFAULT); transpose = false; } else { sc.ChangeState(SCE_MATLAB_IDENTIFIER); sc.SetState(SCE_MATLAB_DEFAULT); transpose = true; } } } else if (sc.state == SCE_MATLAB_NUMBER) { if (!isdigit(sc.ch) && sc.ch != '.' && !(sc.ch == 'e' || sc.ch == 'E') && !((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E'))) { sc.SetState(SCE_MATLAB_DEFAULT); transpose = true; } } else if (sc.state == SCE_MATLAB_STRING) { if (sc.ch == '\'') { if (sc.chNext == '\'') { sc.Forward(); } else { sc.ForwardSetState(SCE_MATLAB_DEFAULT); } } } else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) { if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_MATLAB_DEFAULT); } } else if (sc.state == SCE_MATLAB_COMMENT || sc.state == SCE_MATLAB_COMMAND) { if (sc.atLineEnd) { sc.SetState(SCE_MATLAB_DEFAULT); transpose = false; } } if (sc.state == SCE_MATLAB_DEFAULT) { if (IsCommentChar(sc.ch)) { sc.SetState(SCE_MATLAB_COMMENT); } else if (sc.ch == '!' && sc.chNext != '=' ) { sc.SetState(SCE_MATLAB_COMMAND); } else if (sc.ch == '\'') { if (transpose) { sc.SetState(SCE_MATLAB_OPERATOR); } else { sc.SetState(SCE_MATLAB_STRING); } } else if (sc.ch == '"') { sc.SetState(SCE_MATLAB_DOUBLEQUOTESTRING); } else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) { sc.SetState(SCE_MATLAB_NUMBER); } else if (isalpha(sc.ch)) { sc.SetState(SCE_MATLAB_KEYWORD); } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '\\') { if (sc.ch == ')' || sc.ch == ']') { transpose = true; } else { transpose = false; } sc.SetState(SCE_MATLAB_OPERATOR); } else { transpose = false; } } } sc.Complete(); } static void ColouriseMatlabDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar); } static void ColouriseOctaveDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar); } static void FoldMatlabOctaveDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler, bool (*IsComment)(Accessor&, int, int)) { int endPos = startPos + length; // Backtrack to previous line in case need to fix its fold status int lineCurrent = styler.GetLine(startPos); if (startPos > 0) { if (lineCurrent > 0) { lineCurrent--; startPos = styler.LineStart(lineCurrent); } } int spaceFlags = 0; int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsComment); char chNext = styler[startPos]; for (int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) { int lev = indentCurrent; int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsComment); if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { // Only non whitespace lines can be headers if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) { lev |= SC_FOLDLEVELHEADERFLAG; } else if (indentNext & SC_FOLDLEVELWHITEFLAG) { // Line after is blank so check the next - maybe should continue further? int spaceFlags2 = 0; int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsComment); if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) { lev |= SC_FOLDLEVELHEADERFLAG; } } } indentCurrent = indentNext; styler.SetLevel(lineCurrent, lev); lineCurrent++; } } } static void FoldMatlabDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabComment); } static void FoldOctaveDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveComment); } static const char * const matlabWordListDesc[] = { "Keywords", 0 }; static const char * const octaveWordListDesc[] = { "Keywords", 0 }; LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc); LexerModule lmOctave(SCLEX_OCTAVE, ColouriseOctaveDoc, "octave", FoldOctaveDoc, octaveWordListDesc); |
Added lexers/LexMetapost.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 |
// Scintilla source code edit control // File: LexMetapost.cxx - general context conformant metapost coloring scheme // Author: Hans Hagen - PRAGMA ADE - Hasselt NL - www.pragma-ade.com // Version: September 28, 2003 // Modified by instanton: July 10, 2007 // Folding based on keywordlists[] // Copyright: 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. // This lexer is derived from the one written for the texwork environment (1999++) which in // turn is inspired on texedit (1991++) which finds its roots in wdt (1986). #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // val SCE_METAPOST_DEFAULT = 0 // val SCE_METAPOST_SPECIAL = 1 // val SCE_METAPOST_GROUP = 2 // val SCE_METAPOST_SYMBOL = 3 // val SCE_METAPOST_COMMAND = 4 // val SCE_METAPOST_TEXT = 5 // Definitions in SciTEGlobal.properties: // // Metapost Highlighting // // # Default // style.metapost.0=fore:#7F7F00 // # Special // style.metapost.1=fore:#007F7F // # Group // style.metapost.2=fore:#880000 // # Symbol // style.metapost.3=fore:#7F7F00 // # Command // style.metapost.4=fore:#008800 // # Text // style.metapost.5=fore:#000000 // lexer.tex.comment.process=0 // Auxiliary functions: static inline bool endOfLine(Accessor &styler, unsigned int i) { return (styler[i] == '\n') || ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')) ; } static inline bool isMETAPOSTcomment(int ch) { return (ch == '%') ; } static inline bool isMETAPOSTone(int ch) { return (ch == '[') || (ch == ']') || (ch == '(') || (ch == ')') || (ch == ':') || (ch == '=') || (ch == '<') || (ch == '>') || (ch == '{') || (ch == '}') || (ch == '\'') || (ch == '\"') ; } static inline bool isMETAPOSTtwo(int ch) { return (ch == ';') || (ch == '$') || (ch == '@') || (ch == '#'); } static inline bool isMETAPOSTthree(int ch) { return (ch == '.') || (ch == '-') || (ch == '+') || (ch == '/') || (ch == '*') || (ch == ',') || (ch == '|') || (ch == '`') || (ch == '!') || (ch == '?') || (ch == '^') || (ch == '&') || (ch == '%') ; } static inline bool isMETAPOSTidentifier(int ch) { return ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) || (ch == '_') ; } static inline bool isMETAPOSTnumber(int ch) { return (ch >= '0') && (ch <= '9') ; } static inline bool isMETAPOSTstring(int ch) { return (ch == '\"') ; } static inline bool isMETAPOSTcolon(int ch) { return (ch == ':') ; } static inline bool isMETAPOSTequal(int ch) { return (ch == '=') ; } static int CheckMETAPOSTInterface( unsigned int startPos, int length, Accessor &styler, int defaultInterface) { char lineBuffer[1024] ; unsigned int linePos = 0 ; // some day we can make something lexer.metapost.mapping=(none,0)(metapost,1)(mp,1)(metafun,2)... if (styler.SafeGetCharAt(0) == '%') { for (unsigned int i = 0; i < startPos + length; i++) { lineBuffer[linePos++] = styler.SafeGetCharAt(i) ; if (endOfLine(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { lineBuffer[linePos] = '\0'; if (strstr(lineBuffer, "interface=none")) { return 0 ; } else if (strstr(lineBuffer, "interface=metapost") || strstr(lineBuffer, "interface=mp")) { return 1 ; } else if (strstr(lineBuffer, "interface=metafun")) { return 2 ; } else if (styler.SafeGetCharAt(1) == 'D' && strstr(lineBuffer, "%D \\module")) { // better would be to limit the search to just one line return 2 ; } else { return defaultInterface ; } } } } return defaultInterface ; } static void ColouriseMETAPOSTDoc( unsigned int startPos, int length, int, WordList *keywordlists[], Accessor &styler) { styler.StartAt(startPos) ; styler.StartSegment(startPos) ; bool processComment = styler.GetPropertyInt("lexer.metapost.comment.process", 0) == 1 ; int defaultInterface = styler.GetPropertyInt("lexer.metapost.interface.default", 1) ; int currentInterface = CheckMETAPOSTInterface(startPos,length,styler,defaultInterface) ; // 0 no keyword highlighting // 1 metapost keyword hightlighting // 2+ metafun keyword hightlighting int extraInterface = 0 ; if (currentInterface != 0) { extraInterface = currentInterface ; } WordList &keywords = *keywordlists[0] ; WordList &keywords2 = *keywordlists[extraInterface-1] ; StyleContext sc(startPos, length, SCE_METAPOST_TEXT, styler) ; char key[100] ; bool inTeX = false ; bool inComment = false ; bool inString = false ; bool inClause = false ; bool going = sc.More() ; // needed because of a fuzzy end of file state for (; going; sc.Forward()) { if (! sc.More()) { going = false ; } // we need to go one behind the end of text if (inClause) { sc.SetState(SCE_METAPOST_TEXT) ; inClause = false ; } if (inComment) { if (sc.atLineEnd) { sc.SetState(SCE_METAPOST_TEXT) ; inTeX = false ; inComment = false ; inClause = false ; inString = false ; // not correct but we want to stimulate one-lines } } else if (inString) { if (isMETAPOSTstring(sc.ch)) { sc.SetState(SCE_METAPOST_SPECIAL) ; sc.ForwardSetState(SCE_METAPOST_TEXT) ; inString = false ; } else if (sc.atLineEnd) { sc.SetState(SCE_METAPOST_TEXT) ; inTeX = false ; inComment = false ; inClause = false ; inString = false ; // not correct but we want to stimulate one-lines } } else { if ((! isMETAPOSTidentifier(sc.ch)) && (sc.LengthCurrent() > 0)) { if (sc.state == SCE_METAPOST_COMMAND) { sc.GetCurrent(key, sizeof(key)) ; if ((strcmp(key,"btex") == 0) || (strcmp(key,"verbatimtex") == 0)) { sc.ChangeState(SCE_METAPOST_GROUP) ; inTeX = true ; } else if (inTeX) { if (strcmp(key,"etex") == 0) { sc.ChangeState(SCE_METAPOST_GROUP) ; inTeX = false ; } else { sc.ChangeState(SCE_METAPOST_TEXT) ; } } else { if (keywords && keywords.InList(key)) { sc.ChangeState(SCE_METAPOST_COMMAND) ; } else if (keywords2 && keywords2.InList(key)) { sc.ChangeState(SCE_METAPOST_EXTRA) ; } else { sc.ChangeState(SCE_METAPOST_TEXT) ; } } } } if (isMETAPOSTcomment(sc.ch)) { if (! inTeX) { sc.SetState(SCE_METAPOST_SYMBOL) ; sc.ForwardSetState(SCE_METAPOST_DEFAULT) ; inComment = ! processComment ; } else { sc.SetState(SCE_METAPOST_TEXT) ; } } else if (isMETAPOSTstring(sc.ch)) { if (! inTeX) { sc.SetState(SCE_METAPOST_SPECIAL) ; if (! isMETAPOSTstring(sc.chNext)) { sc.ForwardSetState(SCE_METAPOST_TEXT) ; } inString = true ; } else { sc.SetState(SCE_METAPOST_TEXT) ; } } else if (isMETAPOSTcolon(sc.ch)) { if (! inTeX) { if (! isMETAPOSTequal(sc.chNext)) { sc.SetState(SCE_METAPOST_COMMAND) ; inClause = true ; } else { sc.SetState(SCE_METAPOST_SPECIAL) ; } } else { sc.SetState(SCE_METAPOST_TEXT) ; } } else if (isMETAPOSTone(sc.ch)) { if (! inTeX) { sc.SetState(SCE_METAPOST_SPECIAL) ; } else { sc.SetState(SCE_METAPOST_TEXT) ; } } else if (isMETAPOSTtwo(sc.ch)) { if (! inTeX) { sc.SetState(SCE_METAPOST_GROUP) ; } else { sc.SetState(SCE_METAPOST_TEXT) ; } } else if (isMETAPOSTthree(sc.ch)) { if (! inTeX) { sc.SetState(SCE_METAPOST_SYMBOL) ; } else { sc.SetState(SCE_METAPOST_TEXT) ; } } else if (isMETAPOSTidentifier(sc.ch)) { if (sc.state != SCE_METAPOST_COMMAND) { sc.SetState(SCE_METAPOST_TEXT) ; sc.ChangeState(SCE_METAPOST_COMMAND) ; } } else if (isMETAPOSTnumber(sc.ch)) { // rather redundant since for the moment we don't handle numbers sc.SetState(SCE_METAPOST_TEXT) ; } else if (sc.atLineEnd) { sc.SetState(SCE_METAPOST_TEXT) ; inTeX = false ; inComment = false ; inClause = false ; inString = false ; } else { sc.SetState(SCE_METAPOST_TEXT) ; } } } sc.Complete(); } // Hooks info the system: static const char * const metapostWordListDesc[] = { "MetaPost", "MetaFun", 0 } ; static int classifyFoldPointMetapost(const char* s,WordList *keywordlists[]) { WordList& keywordsStart=*keywordlists[3]; WordList& keywordsStop1=*keywordlists[4]; if (keywordsStart.InList(s)) {return 1;} else if (keywordsStop1.InList(s)) {return -1;} return 0; } static int ParseMetapostWord(unsigned int pos, Accessor &styler, char *word) { int length=0; char ch=styler.SafeGetCharAt(pos); *word=0; while(isMETAPOSTidentifier(ch) && isalpha(ch) && length<100){ word[length]=ch; length++; ch=styler.SafeGetCharAt(pos+length); } word[length]=0; return length; } static void FoldMetapostDoc(unsigned int startPos, int length, int, WordList *keywordlists[], Accessor &styler) { bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos+length; int visibleChars=0; int lineCurrent=styler.GetLine(startPos); int levelPrev=styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent=levelPrev; char chNext=styler[startPos]; char buffer[100]=""; for (unsigned int i=startPos; i < endPos; i++) { char ch=chNext; chNext=styler.SafeGetCharAt(i+1); char chPrev=styler.SafeGetCharAt(i-1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if(i==0 || chPrev == '\r' || chPrev=='\n'|| chPrev==' '|| chPrev=='(' || chPrev=='$') { ParseMetapostWord(i, styler, buffer); levelCurrent += classifyFoldPointMetapost(buffer,keywordlists); } if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } LexerModule lmMETAPOST(SCLEX_METAPOST, ColouriseMETAPOSTDoc, "metapost", FoldMetapostDoc, metapostWordListDesc); |
Added lexers/LexModula.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 |
// -*- coding: utf-8 -*- // Scintilla source code edit control /** * @file LexModula.cxx * @author Dariusz "DKnoto" Knociński * @date 2011/02/03 * @brief Lexer for Modula-2/3 documents. */ // The License.txt file describes the conditions under which this software may // be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "PropSetSimple.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif #ifdef DEBUG_LEX_MODULA #define DEBUG_STATE( p, c )\ fprintf( stderr, "Unknown state: currentPos = %d, char = '%c'\n", p, c ); #else #define DEBUG_STATE( p, c ) #endif static inline bool IsDigitOfBase( unsigned ch, unsigned base ) { if( ch < '0' || ch > 'f' ) return false; if( base <= 10 ) { if( ch >= ( '0' + base ) ) return false; } else { if( ch > '9' ) { unsigned nb = base - 10; if( ( ch < 'A' ) || ( ch >= ( 'A' + nb ) ) ) { if( ( ch < 'a' ) || ( ch >= ( 'a' + nb ) ) ) { return false; } } } } return true; } static inline unsigned IsOperator( StyleContext & sc, WordList & op ) { int i; char s[3]; s[0] = sc.ch; s[1] = sc.chNext; s[2] = 0; for( i = 0; i < op.len; i++ ) { if( ( strlen( op.words[i] ) == 2 ) && ( s[0] == op.words[i][0] && s[1] == op.words[i][1] ) ) { return 2; } } s[1] = 0; for( i = 0; i < op.len; i++ ) { if( ( strlen( op.words[i] ) == 1 ) && ( s[0] == op.words[i][0] ) ) { return 1; } } return 0; } static inline bool IsEOL( Accessor &styler, unsigned curPos ) { unsigned ch = styler.SafeGetCharAt( curPos ); if( ( ch == '\r' && styler.SafeGetCharAt( curPos + 1 ) == '\n' ) || ( ch == '\n' ) ) { return true; } return false; } static inline bool checkStatement( Accessor &styler, int &curPos, const char *stt, bool spaceAfter = true ) { int len = static_cast<int>(strlen( stt )); int i; for( i = 0; i < len; i++ ) { if( styler.SafeGetCharAt( curPos + i ) != stt[i] ) { return false; } } if( spaceAfter ) { if( ! isspace( styler.SafeGetCharAt( curPos + i ) ) ) { return false; } } curPos += ( len - 1 ); return true; } static inline bool checkEndSemicolon( Accessor &styler, int &curPos, int endPos ) { const char *stt = "END"; int len = static_cast<int>(strlen( stt )); int i; for( i = 0; i < len; i++ ) { if( styler.SafeGetCharAt( curPos + i ) != stt[i] ) { return false; } } while( isspace( styler.SafeGetCharAt( curPos + i ) ) ) { i++; if( ( curPos + i ) >= endPos ) return false; } if( styler.SafeGetCharAt( curPos + i ) != ';' ) { return false; } curPos += ( i - 1 ); return true; } static inline bool checkKeyIdentOper( Accessor &styler, int &curPos, int endPos, const char *stt, const char etk ) { int newPos = curPos; if( ! checkStatement( styler, newPos, stt ) ) return false; newPos++; if( newPos >= endPos ) return false; if( ! isspace( styler.SafeGetCharAt( newPos ) ) ) return false; newPos++; if( newPos >= endPos ) return false; while( isspace( styler.SafeGetCharAt( newPos ) ) ) { newPos++; if( newPos >= endPos ) return false; } if( ! isalpha( styler.SafeGetCharAt( newPos ) ) ) return false; newPos++; if( newPos >= endPos ) return false; char ch; ch = styler.SafeGetCharAt( newPos ); while( isalpha( ch ) || isdigit( ch ) || ch == '_' ) { newPos++; if( newPos >= endPos ) return false; ch = styler.SafeGetCharAt( newPos ); } while( isspace( styler.SafeGetCharAt( newPos ) ) ) { newPos++; if( newPos >= endPos ) return false; } if( styler.SafeGetCharAt( newPos ) != etk ) return false; curPos = newPos; return true; } static void FoldModulaDoc( unsigned int startPos, int length, int , WordList *[], Accessor &styler) { int curLine = styler.GetLine(startPos); int curLevel = SC_FOLDLEVELBASE; int endPos = startPos + length; if( curLine > 0 ) curLevel = styler.LevelAt( curLine - 1 ) >> 16; int curPos = startPos; int style = styler.StyleAt( curPos ); int visChars = 0; int nextLevel = curLevel; while( curPos < endPos ) { if( ! isspace( styler.SafeGetCharAt( curPos ) ) ) visChars++; switch( style ) { case SCE_MODULA_COMMENT: if( checkStatement( styler, curPos, "(*" ) ) nextLevel++; else if( checkStatement( styler, curPos, "*)" ) ) nextLevel--; break; case SCE_MODULA_DOXYCOMM: if( checkStatement( styler, curPos, "(**", false ) ) nextLevel++; else if( checkStatement( styler, curPos, "*)" ) ) nextLevel--; break; case SCE_MODULA_KEYWORD: if( checkStatement( styler, curPos, "IF" ) ) nextLevel++; else if( checkStatement( styler, curPos, "BEGIN" ) ) nextLevel++; else if( checkStatement( styler, curPos, "TRY" ) ) nextLevel++; else if( checkStatement( styler, curPos, "LOOP" ) ) nextLevel++; else if( checkStatement( styler, curPos, "FOR" ) ) nextLevel++; else if( checkStatement( styler, curPos, "WHILE" ) ) nextLevel++; else if( checkStatement( styler, curPos, "REPEAT" ) ) nextLevel++; else if( checkStatement( styler, curPos, "UNTIL" ) ) nextLevel--; else if( checkStatement( styler, curPos, "WITH" ) ) nextLevel++; else if( checkStatement( styler, curPos, "CASE" ) ) nextLevel++; else if( checkStatement( styler, curPos, "TYPECASE" ) ) nextLevel++; else if( checkStatement( styler, curPos, "LOCK" ) ) nextLevel++; else if( checkKeyIdentOper( styler, curPos, endPos, "PROCEDURE", '(' ) ) nextLevel++; else if( checkKeyIdentOper( styler, curPos, endPos, "END", ';' ) ) { int cln = curLine; int clv_old = curLevel; int pos; char ch; int clv_new; while( cln > 0 ) { clv_new = styler.LevelAt( cln - 1 ) >> 16; if( clv_new < clv_old ) { nextLevel--; pos = styler.LineStart( cln ); while( ( ch = styler.SafeGetCharAt( pos ) ) != '\n' ) { if( ch == 'P' ) { if( styler.StyleAt(pos) == SCE_MODULA_KEYWORD ) { if( checkKeyIdentOper( styler, pos, endPos, "PROCEDURE", '(' ) ) { break; } } } pos++; } clv_old = clv_new; } cln--; } } else if( checkKeyIdentOper( styler, curPos, endPos, "END", '.' ) ) nextLevel--; else if( checkEndSemicolon( styler, curPos, endPos ) ) nextLevel--; else { while( styler.StyleAt( curPos + 1 ) == SCE_MODULA_KEYWORD ) curPos++; } break; default: break; } if( IsEOL( styler, curPos ) || ( curPos == endPos - 1 ) ) { int efectiveLevel = curLevel | nextLevel << 16; if( visChars == 0 ) efectiveLevel |= SC_FOLDLEVELWHITEFLAG; if( curLevel < nextLevel ) efectiveLevel |= SC_FOLDLEVELHEADERFLAG; if( efectiveLevel != styler.LevelAt(curLine) ) { styler.SetLevel(curLine, efectiveLevel ); } curLine++; curLevel = nextLevel; if( IsEOL( styler, curPos ) && ( curPos == endPos - 1 ) ) { styler.SetLevel( curLine, ( curLevel | curLevel << 16) | SC_FOLDLEVELWHITEFLAG); } visChars = 0; } curPos++; style = styler.StyleAt( curPos ); } } static inline bool skipWhiteSpaces( StyleContext & sc ) { while( isspace( sc.ch ) ) { sc.SetState( SCE_MODULA_DEFAULT ); if( sc.More() ) sc.Forward(); else return false; } return true; } static void ColouriseModulaDoc( unsigned int startPos, int length, int initStyle, WordList *wl[], Accessor &styler ) { WordList& keyWords = *wl[0]; WordList& reservedWords = *wl[1]; WordList& operators = *wl[2]; WordList& pragmaWords = *wl[3]; WordList& escapeCodes = *wl[4]; WordList& doxyKeys = *wl[5]; const int BUFLEN = 128; char buf[BUFLEN]; int i, kl; int charPos = 0; StyleContext sc( startPos, length, initStyle, styler ); while( sc.More() ) { switch( sc.state ) { case SCE_MODULA_DEFAULT: if( ! skipWhiteSpaces( sc ) ) break; if( sc.ch == '(' && sc.chNext == '*' ) { if( sc.GetRelative(2) == '*' ) { sc.SetState( SCE_MODULA_DOXYCOMM ); sc.Forward(); } else { sc.SetState( SCE_MODULA_COMMENT ); } sc.Forward(); } else if( isalpha( sc.ch ) ) { if( isupper( sc.ch ) && isupper( sc.chNext ) ) { for( i = 0; i < BUFLEN - 1; i++ ) { buf[i] = sc.GetRelative(i); if( !isalpha( buf[i] ) && !(buf[i] == '_') ) break; } kl = i; buf[kl] = 0; if( keyWords.InList( buf ) ) { sc.SetState( SCE_MODULA_KEYWORD ); sc.Forward( kl ); sc.SetState( SCE_MODULA_DEFAULT ); continue; } else if( reservedWords.InList( buf ) ) { sc.SetState( SCE_MODULA_RESERVED ); sc.Forward( kl ); sc.SetState( SCE_MODULA_DEFAULT ); continue; } else { /** check procedure identifier */ } } else { for( i = 0; i < BUFLEN - 1; i++ ) { buf[i] = sc.GetRelative(i); if( !isalpha( buf[i] ) && !isdigit( buf[i] ) && !(buf[i] == '_') ) break; } kl = i; buf[kl] = 0; sc.SetState( SCE_MODULA_DEFAULT ); sc.Forward( kl ); continue; } } else if( isdigit( sc.ch ) ) { sc.SetState( SCE_MODULA_NUMBER ); continue; } else if( sc.ch == '\"' ) { sc.SetState( SCE_MODULA_STRING ); } else if( sc.ch == '\'' ) { charPos = sc.currentPos; sc.SetState( SCE_MODULA_CHAR ); } else if( sc.ch == '<' && sc.chNext == '*' ) { sc.SetState( SCE_MODULA_PRAGMA ); sc.Forward(); } else { unsigned len = IsOperator( sc, operators ); if( len > 0 ) { sc.SetState( SCE_MODULA_OPERATOR ); sc.Forward( len ); sc.SetState( SCE_MODULA_DEFAULT ); continue; } else { DEBUG_STATE( sc.currentPos, sc.ch ); } } break; case SCE_MODULA_COMMENT: if( sc.ch == '*' && sc.chNext == ')' ) { sc.Forward( 2 ); sc.SetState( SCE_MODULA_DEFAULT ); continue; } break; case SCE_MODULA_DOXYCOMM: switch( sc.ch ) { case '*': if( sc.chNext == ')' ) { sc.Forward( 2 ); sc.SetState( SCE_MODULA_DEFAULT ); continue; } break; case '@': if( islower( sc.chNext ) ) { for( i = 0; i < BUFLEN - 1; i++ ) { buf[i] = sc.GetRelative(i+1); if( isspace( buf[i] ) ) break; } buf[i] = 0; kl = i; if( doxyKeys.InList( buf ) ) { sc.SetState( SCE_MODULA_DOXYKEY ); sc.Forward( kl + 1 ); sc.SetState( SCE_MODULA_DOXYCOMM ); } } break; default: break; } break; case SCE_MODULA_NUMBER: { buf[0] = sc.ch; for( i = 1; i < BUFLEN - 1; i++ ) { buf[i] = sc.GetRelative(i); if( ! isdigit( buf[i] ) ) break; } kl = i; buf[kl] = 0; switch( sc.GetRelative(kl) ) { case '_': { int base = atoi( buf ); if( base < 2 || base > 16 ) { sc.SetState( SCE_MODULA_BADSTR ); } else { int imax; kl++; for( i = 0; i < BUFLEN - 1; i++ ) { buf[i] = sc.GetRelative(kl+i); if( ! IsDigitOfBase( buf[i], 16 ) ) { break; } } imax = i; for( i = 0; i < imax; i++ ) { if( ! IsDigitOfBase( buf[i], base ) ) { sc.SetState( SCE_MODULA_BADSTR ); break; } } kl += imax; } sc.SetState( SCE_MODULA_BASENUM ); for( i = 0; i < kl; i++ ) { sc.Forward(); } sc.SetState( SCE_MODULA_DEFAULT ); continue; } break; case '.': if( sc.GetRelative(kl+1) == '.' ) { kl--; for( i = 0; i < kl; i++ ) { sc.Forward(); } sc.Forward(); sc.SetState( SCE_MODULA_DEFAULT ); continue; } else { bool doNext = false; kl++; buf[0] = sc.GetRelative(kl); if( isdigit( buf[0] ) ) { for( i = 0;; i++ ) { if( !isdigit(sc.GetRelative(kl+i)) ) break; } kl += i; buf[0] = sc.GetRelative(kl); switch( buf[0] ) { case 'E': case 'e': case 'D': case 'd': case 'X': case 'x': kl++; buf[0] = sc.GetRelative(kl); if( buf[0] == '-' || buf[0] == '+' ) { kl++; } buf[0] = sc.GetRelative(kl); if( isdigit( buf[0] ) ) { for( i = 0;; i++ ) { if( !isdigit(sc.GetRelative(kl+i)) ) { buf[0] = sc.GetRelative(kl+i); break; } } kl += i; doNext = true; } else { sc.SetState( SCE_MODULA_BADSTR ); } break; default: doNext = true; break; } } else { sc.SetState( SCE_MODULA_BADSTR ); } if( doNext ) { if( ! isspace( buf[0] ) && buf[0] != ')' && buf[0] != '>' && buf[0] != '<' && buf[0] != '=' && buf[0] != '#' && buf[0] != '+' && buf[0] != '-' && buf[0] != '*' && buf[0] != '/' && buf[0] != ',' && buf[0] != ';' ) { sc.SetState( SCE_MODULA_BADSTR ); } else { kl--; } } } sc.SetState( SCE_MODULA_FLOAT ); for( i = 0; i < kl; i++ ) { sc.Forward(); } sc.SetState( SCE_MODULA_DEFAULT ); continue; break; default: for( i = 0; i < kl; i++ ) { sc.Forward(); } break; } sc.SetState( SCE_MODULA_DEFAULT ); continue; } break; case SCE_MODULA_STRING: if( sc.ch == '\"' ) { sc.Forward(); sc.SetState( SCE_MODULA_DEFAULT ); continue; } else { if( sc.ch == '\\' ) { i = 1; if( IsDigitOfBase( sc.chNext, 8 ) ) { for( i = 1; i < BUFLEN - 1; i++ ) { if( ! IsDigitOfBase(sc.GetRelative(i+1), 8 ) ) break; } if( i == 3 ) { sc.SetState( SCE_MODULA_STRSPEC ); } else { sc.SetState( SCE_MODULA_BADSTR ); } } else { buf[0] = sc.chNext; buf[1] = 0; if( escapeCodes.InList( buf ) ) { sc.SetState( SCE_MODULA_STRSPEC ); } else { sc.SetState( SCE_MODULA_BADSTR ); } } sc.Forward(i+1); sc.SetState( SCE_MODULA_STRING ); continue; } } break; case SCE_MODULA_CHAR: if( sc.ch == '\'' ) { sc.Forward(); sc.SetState( SCE_MODULA_DEFAULT ); continue; } else if( ( sc.currentPos - charPos ) == 1 ) { if( sc.ch == '\\' ) { i = 1; if( IsDigitOfBase( sc.chNext, 8 ) ) { for( i = 1; i < BUFLEN - 1; i++ ) { if( ! IsDigitOfBase(sc.GetRelative(i+1), 8 ) ) break; } if( i == 3 ) { sc.SetState( SCE_MODULA_CHARSPEC ); } else { sc.SetState( SCE_MODULA_BADSTR ); } } else { buf[0] = sc.chNext; buf[1] = 0; if( escapeCodes.InList( buf ) ) { sc.SetState( SCE_MODULA_CHARSPEC ); } else { sc.SetState( SCE_MODULA_BADSTR ); } } sc.Forward(i+1); sc.SetState( SCE_MODULA_CHAR ); continue; } } else { sc.SetState( SCE_MODULA_BADSTR ); sc.Forward(); sc.SetState( SCE_MODULA_CHAR ); continue; } break; case SCE_MODULA_PRAGMA: if( sc.ch == '*' && sc.chNext == '>' ) { sc.Forward(); sc.Forward(); sc.SetState( SCE_MODULA_DEFAULT ); continue; } else if( isupper( sc.ch ) && isupper( sc.chNext ) ) { buf[0] = sc.ch; buf[1] = sc.chNext; for( i = 2; i < BUFLEN - 1; i++ ) { buf[i] = sc.GetRelative(i); if( !isupper( buf[i] ) ) break; } kl = i; buf[kl] = 0; if( pragmaWords.InList( buf ) ) { sc.SetState( SCE_MODULA_PRGKEY ); sc.Forward( kl ); sc.SetState( SCE_MODULA_PRAGMA ); continue; } } break; default: break; } sc.Forward(); } sc.Complete(); } static const char *const modulaWordListDesc[] = { "Keywords", "ReservedKeywords", "Operators", "PragmaKeyswords", "EscapeCodes", "DoxygeneKeywords", 0 }; LexerModule lmModula( SCLEX_MODULA, ColouriseModulaDoc, "modula", FoldModulaDoc, modulaWordListDesc); |
Added lexers/LexMySQL.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 |
/** * Scintilla source code edit control * @file LexMySQL.cxx * Lexer for MySQL * * Improved by Mike Lischke <mike.lischke@oracle.com> * Adopted from LexSQL.cxx by Anders Karlsson <anders@mysql.com> * Original work by Neil Hodgson <neilh@scintilla.org> * Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org> * The License.txt file describes the conditions under which this software may be distributed. */ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_'); } static inline bool IsAWordStart(int ch) { return (ch < 0x80) && (isalpha(ch) || ch == '_'); } static inline bool IsADoxygenChar(int ch) { return (islower(ch) || ch == '$' || ch == '@' || ch == '\\' || ch == '&' || ch == '<' || ch == '>' || ch == '#' || ch == '{' || ch == '}' || ch == '[' || ch == ']'); } static inline bool IsANumberChar(int ch) { // Not exactly following number definition (several dots are seen as OK, etc.) // but probably enough in most cases. return (ch < 0x80) && (isdigit(ch) || toupper(ch) == 'E' || ch == '.' || ch == '-' || ch == '+'); } //-------------------------------------------------------------------------------------------------- /** * Check if the current content context represent a keyword and set the context state if so. */ static void CheckForKeyword(StyleContext& sc, WordList* keywordlists[], int activeState) { int length = sc.LengthCurrent() + 1; // +1 for the next char char* s = new char[length]; sc.GetCurrentLowered(s, length); if (keywordlists[0]->InList(s)) sc.ChangeState(SCE_MYSQL_MAJORKEYWORD | activeState); else if (keywordlists[1]->InList(s)) sc.ChangeState(SCE_MYSQL_KEYWORD | activeState); else if (keywordlists[2]->InList(s)) sc.ChangeState(SCE_MYSQL_DATABASEOBJECT | activeState); else if (keywordlists[3]->InList(s)) sc.ChangeState(SCE_MYSQL_FUNCTION | activeState); else if (keywordlists[5]->InList(s)) sc.ChangeState(SCE_MYSQL_PROCEDUREKEYWORD | activeState); else if (keywordlists[6]->InList(s)) sc.ChangeState(SCE_MYSQL_USER1 | activeState); else if (keywordlists[7]->InList(s)) sc.ChangeState(SCE_MYSQL_USER2 | activeState); else if (keywordlists[8]->InList(s)) sc.ChangeState(SCE_MYSQL_USER3 | activeState); delete [] s; } //-------------------------------------------------------------------------------------------------- #define HIDDENCOMMAND_STATE 0x40 // Offset for states within a hidden command. #define MASKACTIVE(style) (style & ~HIDDENCOMMAND_STATE) static void SetDefaultState(StyleContext& sc, int activeState) { if (activeState == 0) sc.SetState(SCE_MYSQL_DEFAULT); else sc.SetState(SCE_MYSQL_HIDDENCOMMAND); } static void ForwardDefaultState(StyleContext& sc, int activeState) { if (activeState == 0) sc.ForwardSetState(SCE_MYSQL_DEFAULT); else sc.ForwardSetState(SCE_MYSQL_HIDDENCOMMAND); } static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { StyleContext sc(startPos, length, initStyle, styler, 127); int activeState = (initStyle == SCE_MYSQL_HIDDENCOMMAND) ? HIDDENCOMMAND_STATE : initStyle & HIDDENCOMMAND_STATE; for (; sc.More(); sc.Forward()) { // Determine if the current state should terminate. switch (MASKACTIVE(sc.state)) { case SCE_MYSQL_OPERATOR: SetDefaultState(sc, activeState); break; case SCE_MYSQL_NUMBER: // We stop the number definition on non-numerical non-dot non-eE non-sign char. if (!IsANumberChar(sc.ch)) SetDefaultState(sc, activeState); break; case SCE_MYSQL_IDENTIFIER: // Switch from identifier to keyword state and open a new state for the new char. if (!IsAWordChar(sc.ch)) { CheckForKeyword(sc, keywordlists, activeState); // Additional check for function keywords needed. // A function name must be followed by an opening parenthesis. if (MASKACTIVE(sc.state) == SCE_MYSQL_FUNCTION && sc.ch != '(') { if (activeState > 0) sc.ChangeState(SCE_MYSQL_HIDDENCOMMAND); else sc.ChangeState(SCE_MYSQL_DEFAULT); } SetDefaultState(sc, activeState); } break; case SCE_MYSQL_VARIABLE: if (!IsAWordChar(sc.ch)) SetDefaultState(sc, activeState); break; case SCE_MYSQL_SYSTEMVARIABLE: if (!IsAWordChar(sc.ch)) { int length = sc.LengthCurrent() + 1; char* s = new char[length]; sc.GetCurrentLowered(s, length); // Check for known system variables here. if (keywordlists[4]->InList(&s[2])) sc.ChangeState(SCE_MYSQL_KNOWNSYSTEMVARIABLE | activeState); delete [] s; SetDefaultState(sc, activeState); } break; case SCE_MYSQL_QUOTEDIDENTIFIER: if (sc.ch == '`') { if (sc.chNext == '`') sc.Forward(); // Ignore it else ForwardDefaultState(sc, activeState); } break; case SCE_MYSQL_COMMENT: if (sc.Match('*', '/')) { sc.Forward(); ForwardDefaultState(sc, activeState); } break; case SCE_MYSQL_COMMENTLINE: if (sc.atLineStart) SetDefaultState(sc, activeState); break; case SCE_MYSQL_SQSTRING: if (sc.ch == '\\') sc.Forward(); // Escape sequence else if (sc.ch == '\'') { // End of single quoted string reached? if (sc.chNext == '\'') sc.Forward(); else ForwardDefaultState(sc, activeState); } break; case SCE_MYSQL_DQSTRING: if (sc.ch == '\\') sc.Forward(); // Escape sequence else if (sc.ch == '\"') { // End of single quoted string reached? if (sc.chNext == '\"') sc.Forward(); else ForwardDefaultState(sc, activeState); } break; case SCE_MYSQL_PLACEHOLDER: if (sc.Match('}', '>')) { sc.Forward(); ForwardDefaultState(sc, activeState); } break; } if (sc.state == SCE_MYSQL_HIDDENCOMMAND && sc.Match('*', '/')) { activeState = 0; sc.Forward(); ForwardDefaultState(sc, activeState); } // Determine if a new state should be entered. if (sc.state == SCE_MYSQL_DEFAULT || sc.state == SCE_MYSQL_HIDDENCOMMAND) { switch (sc.ch) { case '@': if (sc.chNext == '@') { sc.SetState(SCE_MYSQL_SYSTEMVARIABLE | activeState); sc.Forward(2); // Skip past @@. } else if (IsAWordStart(sc.ch)) { sc.SetState(SCE_MYSQL_VARIABLE | activeState); sc.Forward(); // Skip past @. } else sc.SetState(SCE_MYSQL_OPERATOR | activeState); break; case '`': sc.SetState(SCE_MYSQL_QUOTEDIDENTIFIER | activeState); break; case '#': sc.SetState(SCE_MYSQL_COMMENTLINE | activeState); break; case '\'': sc.SetState(SCE_MYSQL_SQSTRING | activeState); break; case '\"': sc.SetState(SCE_MYSQL_DQSTRING | activeState); break; default: if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) sc.SetState(SCE_MYSQL_NUMBER | activeState); else if (IsAWordStart(sc.ch)) sc.SetState(SCE_MYSQL_IDENTIFIER | activeState); else if (sc.Match('/', '*')) { sc.SetState(SCE_MYSQL_COMMENT | activeState); // Skip comment introducer and check for hidden command. sc.Forward(2); if (sc.ch == '!') { activeState = HIDDENCOMMAND_STATE; sc.ChangeState(SCE_MYSQL_HIDDENCOMMAND); } } else if (sc.Match('<', '{')) { sc.SetState(SCE_MYSQL_PLACEHOLDER | activeState); } else if (sc.Match("--")) { // Special MySQL single line comment. sc.SetState(SCE_MYSQL_COMMENTLINE | activeState); sc.Forward(2); // Check the third character too. It must be a space or EOL. if (sc.ch != ' ' && sc.ch != '\n' && sc.ch != '\r') sc.ChangeState(SCE_MYSQL_OPERATOR | activeState); } else if (isoperator(static_cast<char>(sc.ch))) sc.SetState(SCE_MYSQL_OPERATOR | activeState); } } } // Do a final check for keywords if we currently have an identifier, to highlight them // also at the end of a line. if (sc.state == SCE_MYSQL_IDENTIFIER) { CheckForKeyword(sc, keywordlists, activeState); // Additional check for function keywords needed. // A function name must be followed by an opening parenthesis. if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(') SetDefaultState(sc, activeState); } sc.Complete(); } //-------------------------------------------------------------------------------------------------- /** * Helper function to determine if we have a foldable comment currently. */ static bool IsStreamCommentStyle(int style) { return MASKACTIVE(style) == SCE_MYSQL_COMMENT; } //-------------------------------------------------------------------------------------------------- /** * Code copied from StyleContext and modified to work here. Should go into Accessor as a * companion to Match()... */ bool MatchIgnoreCase(Accessor &styler, int currentPos, const char *s) { for (int n = 0; *s; n++) { if (*s != tolower(styler.SafeGetCharAt(currentPos + n))) return false; s++; } return true; } //-------------------------------------------------------------------------------------------------- // Store both the current line's fold level and the next lines in the // level store to make it easy to pick up with each increment. static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldOnlyBegin = styler.GetPropertyInt("fold.sql.only.begin", 0) != 0; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16; int levelNext = levelCurrent; int styleNext = styler.StyleAt(startPos); int style = initStyle; int activeState = (style == SCE_MYSQL_HIDDENCOMMAND) ? HIDDENCOMMAND_STATE : style & HIDDENCOMMAND_STATE; bool endPending = false; bool whenPending = false; bool elseIfPending = false; char nextChar = styler.SafeGetCharAt(startPos); for (unsigned int i = startPos; length > 0; i++, length--) { int stylePrev = style; int lastActiveState = activeState; style = styleNext; styleNext = styler.StyleAt(i + 1); activeState = (style == SCE_MYSQL_HIDDENCOMMAND) ? HIDDENCOMMAND_STATE : style & HIDDENCOMMAND_STATE; char currentChar = nextChar; nextChar = styler.SafeGetCharAt(i + 1); bool atEOL = (currentChar == '\r' && nextChar != '\n') || (currentChar == '\n'); switch (MASKACTIVE(style)) { case SCE_MYSQL_COMMENT: if (foldComment) { // Multiline comment style /* .. */ just started or is still in progress. if (IsStreamCommentStyle(style) && !IsStreamCommentStyle(stylePrev)) levelNext++; } break; case SCE_MYSQL_COMMENTLINE: if (foldComment) { // Not really a standard, but we add support for single line comments // with special curly braces syntax as foldable comments too. // MySQL needs -- comments to be followed by space or control char if (styler.Match(i, "--")) { char chNext2 = styler.SafeGetCharAt(i + 2); char chNext3 = styler.SafeGetCharAt(i + 3); if (chNext2 == '{' || chNext3 == '{') levelNext++; else if (chNext2 == '}' || chNext3 == '}') levelNext--; } } break; case SCE_MYSQL_HIDDENCOMMAND: /* if (endPending) { // A conditional command is not a white space so it should end the current block // before opening a new one. endPending = false; levelNext--; if (levelNext < SC_FOLDLEVELBASE) levelNext = SC_FOLDLEVELBASE; } }*/ if (activeState != lastActiveState) levelNext++; break; case SCE_MYSQL_OPERATOR: if (endPending) { endPending = false; levelNext--; if (levelNext < SC_FOLDLEVELBASE) levelNext = SC_FOLDLEVELBASE; } if (currentChar == '(') levelNext++; else if (currentChar == ')') { levelNext--; if (levelNext < SC_FOLDLEVELBASE) levelNext = SC_FOLDLEVELBASE; } break; case SCE_MYSQL_MAJORKEYWORD: case SCE_MYSQL_KEYWORD: case SCE_MYSQL_FUNCTION: case SCE_MYSQL_PROCEDUREKEYWORD: // Reserved and other keywords. if (style != stylePrev) { // END decreases the folding level, regardless which keyword follows. bool endFound = MatchIgnoreCase(styler, i, "end"); if (endPending) { levelNext--; if (levelNext < SC_FOLDLEVELBASE) levelNext = SC_FOLDLEVELBASE; } else if (!endFound) { if (MatchIgnoreCase(styler, i, "begin")) levelNext++; else { if (!foldOnlyBegin) { bool whileFound = MatchIgnoreCase(styler, i, "while"); bool loopFound = MatchIgnoreCase(styler, i, "loop"); bool repeatFound = MatchIgnoreCase(styler, i, "repeat"); bool caseFound = MatchIgnoreCase(styler, i, "case"); if (whileFound || loopFound || repeatFound || caseFound) levelNext++; else { // IF alone does not increase the fold level as it is also used in non-block'ed // code like DROP PROCEDURE blah IF EXISTS. // Instead THEN opens the new level (if not part of an ELSEIF or WHEN (case) branch). if (MatchIgnoreCase(styler, i, "then")) { if (!elseIfPending && !whenPending) levelNext++; else { elseIfPending = false; whenPending = false; } } else { // Neither of if/then/while/loop/repeat/case, so check for // sub parts of IF and CASE. if (MatchIgnoreCase(styler, i, "elseif")) elseIfPending = true; if (MatchIgnoreCase(styler, i, "when")) whenPending = true; } } } } } // Keep the current end state for the next round. endPending = endFound; } break; default: if (!isspacechar(currentChar) && endPending) { // END followed by a non-whitespace character (not covered by other cases like identifiers) // also should end a folding block. Typical case: END followed by self defined delimiter. levelNext--; if (levelNext < SC_FOLDLEVELBASE) levelNext = SC_FOLDLEVELBASE; } break; } // Go up one level if we just ended a multi line comment. if (IsStreamCommentStyle(stylePrev) && !IsStreamCommentStyle(style)) { levelNext--; if (levelNext < SC_FOLDLEVELBASE) levelNext = SC_FOLDLEVELBASE; } if (activeState == 0 && lastActiveState != 0) { // Decrease fold level when we left a hidden command. levelNext--; if (levelNext < SC_FOLDLEVELBASE) levelNext = SC_FOLDLEVELBASE; } if (atEOL) { // Apply the new folding level to this line. // Leave pending states as they are otherwise a line break will de-sync // code folding and valid syntax. int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) styler.SetLevel(lineCurrent, lev); lineCurrent++; levelCurrent = levelNext; visibleChars = 0; } if (!isspacechar(currentChar)) visibleChars++; } } //-------------------------------------------------------------------------------------------------- static const char * const mysqlWordListDesc[] = { "Major Keywords", "Keywords", "Database Objects", "Functions", "System Variables", "Procedure keywords", "User Keywords 1", "User Keywords 2", "User Keywords 3", 0 }; LexerModule lmMySQL(SCLEX_MYSQL, ColouriseMySQLDoc, "mysql", FoldMySQLDoc, mysqlWordListDesc, 7); |
Added lexers/LexNimrod.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 |
// Scintilla source code edit control // Nimrod lexer // (c) 2009 Andreas Rumpf /** @file LexNimrod.cxx ** Lexer for Nimrod. **/ // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(int ch) { return (ch >= 0x80) || isalnum(ch) || ch == '_'; } static int tillEndOfTripleQuote(Accessor &styler, int pos, int max) { /* search for """ */ for (;;) { if (styler.SafeGetCharAt(pos, '\0') == '\0') return pos; if (pos >= max) return pos; if (styler.Match(pos, "\"\"\"")) { return pos + 2; } pos++; } } #define CR 13 /* use both because Scite allows changing the line ending */ #define LF 10 static bool inline isNewLine(int ch) { return ch == CR || ch == LF; } static int scanString(Accessor &styler, int pos, int max, bool rawMode) { for (;;) { if (pos >= max) return pos; char ch = styler.SafeGetCharAt(pos, '\0'); if (ch == CR || ch == LF || ch == '\0') return pos; if (ch == '"') return pos; if (ch == '\\' && !rawMode) { pos += 2; } else { pos++; } } } static int scanChar(Accessor &styler, int pos, int max) { for (;;) { if (pos >= max) return pos; char ch = styler.SafeGetCharAt(pos, '\0'); if (ch == CR || ch == LF || ch == '\0') return pos; if (ch == '\'' && !isalnum(styler.SafeGetCharAt(pos+1, '\0')) ) return pos; if (ch == '\\') { pos += 2; } else { pos++; } } } static int scanIdent(Accessor &styler, int pos, WordList &keywords) { char buf[100]; /* copy to lowercase and ignore underscores */ int i = 0; for (;;) { char ch = styler.SafeGetCharAt(pos, '\0'); if (!IsAWordChar(ch)) break; if (ch != '_' && i < ((int)sizeof(buf))-1) { buf[i] = static_cast<char>(tolower(ch)); i++; } pos++; } buf[i] = '\0'; /* look for keyword */ if (keywords.InList(buf)) { styler.ColourTo(pos-1, SCE_P_WORD); } else { styler.ColourTo(pos-1, SCE_P_IDENTIFIER); } return pos; } static int scanNumber(Accessor &styler, int pos) { char ch, ch2; ch = styler.SafeGetCharAt(pos, '\0'); ch2 = styler.SafeGetCharAt(pos+1, '\0'); if (ch == '0' && (ch2 == 'b' || ch2 == 'B')) { /* binary number: */ pos += 2; for (;;) { ch = styler.SafeGetCharAt(pos, '\0'); if (ch == '_' || (ch >= '0' && ch <= '1')) ++pos; else break; } } else if (ch == '0' && (ch2 == 'o' || ch2 == 'O' || ch2 == 'c' || ch2 == 'C')) { /* octal number: */ pos += 2; for (;;) { ch = styler.SafeGetCharAt(pos, '\0'); if (ch == '_' || (ch >= '0' && ch <= '7')) ++pos; else break; } } else if (ch == '0' && (ch2 == 'x' || ch2 == 'X')) { /* hexadecimal number: */ pos += 2; for (;;) { ch = styler.SafeGetCharAt(pos, '\0'); if (ch == '_' || (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) ++pos; else break; } } else { // skip decimal part: for (;;) { ch = styler.SafeGetCharAt(pos, '\0'); if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos; else break; } ch2 = styler.SafeGetCharAt(pos+1, '\0'); if (ch == '.' && ch2 >= '0' && ch2 <= '9') { ++pos; // skip '.' for (;;) { ch = styler.SafeGetCharAt(pos, '\0'); if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos; else break; } } if (ch == 'e' || ch == 'E') { ++pos; ch = styler.SafeGetCharAt(pos, '\0'); if (ch == '-' || ch == '+') ++pos; for (;;) { ch = styler.SafeGetCharAt(pos, '\0'); if (ch == '_' || (ch >= '0' && ch <= '9')) ++pos; else break; } } } if (ch == '\'') { /* a type suffix: */ pos++; for (;;) { ch = styler.SafeGetCharAt(pos); if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '_') ++pos; else break; } } styler.ColourTo(pos-1, SCE_P_NUMBER); return pos; } /* rewritten from scratch, because I couldn't get rid of the bugs... (A character based approach sucks!) */ static void ColouriseNimrodDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { int pos = startPos; int max = startPos + length; char ch; WordList &keywords = *keywordlists[0]; styler.StartAt(startPos); styler.StartSegment(startPos); switch (initStyle) { /* check where we are: */ case SCE_P_TRIPLEDOUBLE: pos = tillEndOfTripleQuote(styler, pos, max); styler.ColourTo(pos, SCE_P_TRIPLEDOUBLE); pos++; break; default: /* nothing to do: */ break; } while (pos < max) { ch = styler.SafeGetCharAt(pos, '\0'); switch (ch) { case '\0': return; case '#': { bool doccomment = (styler.SafeGetCharAt(pos+1) == '#'); while (pos < max && !isNewLine(styler.SafeGetCharAt(pos, LF))) pos++; if (doccomment) styler.ColourTo(pos, SCE_C_COMMENTLINEDOC); else styler.ColourTo(pos, SCE_P_COMMENTLINE); } break; case 'r': case 'R': { if (styler.SafeGetCharAt(pos+1) == '"') { pos = scanString(styler, pos+2, max, true); styler.ColourTo(pos, SCE_P_STRING); pos++; } else { pos = scanIdent(styler, pos, keywords); } } break; case '"': if (styler.Match(pos+1, "\"\"")) { pos = tillEndOfTripleQuote(styler, pos+3, max); styler.ColourTo(pos, SCE_P_TRIPLEDOUBLE); } else { pos = scanString(styler, pos+1, max, false); styler.ColourTo(pos, SCE_P_STRING); } pos++; break; case '\'': pos = scanChar(styler, pos+1, max); styler.ColourTo(pos, SCE_P_CHARACTER); pos++; break; default: // identifers, numbers, operators, whitespace if (ch >= '0' && ch <= '9') { pos = scanNumber(styler, pos); } else if (IsAWordChar(ch)) { pos = scanIdent(styler, pos, keywords); } else if (ch == '`') { pos++; while (pos < max) { ch = styler.SafeGetCharAt(pos, LF); if (ch == '`') { ++pos; break; } if (ch == CR || ch == LF) break; ++pos; } styler.ColourTo(pos, SCE_P_IDENTIFIER); } else if (strchr("()[]{}:=;-\\/&%$!+<>|^?,.*~@", ch)) { styler.ColourTo(pos, SCE_P_OPERATOR); pos++; } else { styler.ColourTo(pos, SCE_P_DEFAULT); pos++; } break; } } } static bool IsCommentLine(int line, Accessor &styler) { int pos = styler.LineStart(line); int eol_pos = styler.LineStart(line + 1) - 1; for (int i = pos; i < eol_pos; i++) { char ch = styler[i]; if (ch == '#') return true; else if (ch != ' ' && ch != '\t') return false; } return false; } static bool IsQuoteLine(int line, Accessor &styler) { int style = styler.StyleAt(styler.LineStart(line)) & 31; return ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE)); } static void FoldNimrodDoc(unsigned int startPos, int length, int /*initStyle - unused*/, WordList *[], Accessor &styler) { const int maxPos = startPos + length; const int maxLines = styler.GetLine(maxPos - 1); // Requested last line const int docLines = styler.GetLine(styler.Length() - 1); // Available last line const bool foldComment = styler.GetPropertyInt("fold.comment.nimrod") != 0; const bool foldQuotes = styler.GetPropertyInt("fold.quotes.nimrod") != 0; // Backtrack to previous non-blank line so we can determine indent level // for any white space lines (needed esp. within triple quoted strings) // and so we can fix any preceding fold level (which is why we go back // at least one line in all cases) int spaceFlags = 0; int lineCurrent = styler.GetLine(startPos); int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL); while (lineCurrent > 0) { lineCurrent--; indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL); if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) && (!IsCommentLine(lineCurrent, styler)) && (!IsQuoteLine(lineCurrent, styler))) break; } int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK; // Set up initial loop state startPos = styler.LineStart(lineCurrent); int prev_state = SCE_P_DEFAULT & 31; if (lineCurrent >= 1) prev_state = styler.StyleAt(startPos - 1) & 31; int prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) || (prev_state == SCE_P_TRIPLEDOUBLE)); int prevComment = 0; if (lineCurrent >= 1) prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler); // Process all characters to end of requested range or end of any triple quote // or comment that hangs over the end of the range. Cap processing in all cases // to end of document (in case of unclosed quote or comment at end). while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevQuote || prevComment)) { // Gather info int lev = indentCurrent; int lineNext = lineCurrent + 1; int indentNext = indentCurrent; int quote = false; if (lineNext <= docLines) { // Information about next line is only available if not at end of document indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); int style = styler.StyleAt(styler.LineStart(lineNext)) & 31; quote = foldQuotes && ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE)); } const int quote_start = (quote && !prevQuote); const int quote_continue = (quote && prevQuote); const int comment = foldComment && IsCommentLine(lineCurrent, styler); const int comment_start = (comment && !prevComment && (lineNext <= docLines) && IsCommentLine(lineNext, styler) && (lev > SC_FOLDLEVELBASE)); const int comment_continue = (comment && prevComment); if ((!quote || !prevQuote) && !comment) indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK; if (quote) indentNext = indentCurrentLevel; if (indentNext & SC_FOLDLEVELWHITEFLAG) indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel; if (quote_start) { // Place fold point at start of triple quoted string lev |= SC_FOLDLEVELHEADERFLAG; } else if (quote_continue || prevQuote) { // Add level to rest of lines in the string lev = lev + 1; } else if (comment_start) { // Place fold point at start of a block of comments lev |= SC_FOLDLEVELHEADERFLAG; } else if (comment_continue) { // Add level to rest of lines in the block lev = lev + 1; } // Skip past any blank lines for next indent level info; we skip also // comments (all comments, not just those starting in column 0) // which effectively folds them into surrounding code rather // than screwing up folding. while (!quote && (lineNext < docLines) && ((indentNext & SC_FOLDLEVELWHITEFLAG) || (lineNext <= docLines && IsCommentLine(lineNext, styler)))) { lineNext++; indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); } const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK; const int levelBeforeComments = Maximum(indentCurrentLevel,levelAfterComments); // Now set all the indent levels on the lines we skipped // Do this from end to start. Once we encounter one line // which is indented more than the line after the end of // the comment-block, use the level of the block before int skipLine = lineNext; int skipLevel = levelAfterComments; while (--skipLine > lineCurrent) { int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL); if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments) skipLevel = levelBeforeComments; int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG; styler.SetLevel(skipLine, skipLevel | whiteFlag); } // Set fold header on non-quote/non-comment line if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) { if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) lev |= SC_FOLDLEVELHEADERFLAG; } // Keep track of triple quote and block comment state of previous line prevQuote = quote; prevComment = comment_start || comment_continue; // Set fold level for this line and move to next line styler.SetLevel(lineCurrent, lev); indentCurrent = indentNext; lineCurrent = lineNext; } // NOTE: Cannot set level of last line here because indentCurrent doesn't have // header flag set; the loop above is crafted to take care of this case! //styler.SetLevel(lineCurrent, indentCurrent); } static const char * const nimrodWordListDesc[] = { "Keywords", 0 }; LexerModule lmNimrod(SCLEX_NIMROD, ColouriseNimrodDoc, "nimrod", FoldNimrodDoc, nimrodWordListDesc); |
Added lexers/LexNsis.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 |
// Scintilla source code edit control /** @file LexNsis.cxx ** Lexer for NSIS **/ // Copyright 2003 - 2005 by Angelo Mandato <angelo [at] spaceblue [dot] com> // Last Updated: 03/13/2005 // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif /* // located in SciLexer.h #define SCLEX_NSIS 43 #define SCE_NSIS_DEFAULT 0 #define SCE_NSIS_COMMENT 1 #define SCE_NSIS_STRINGDQ 2 #define SCE_NSIS_STRINGLQ 3 #define SCE_NSIS_STRINGRQ 4 #define SCE_NSIS_FUNCTION 5 #define SCE_NSIS_VARIABLE 6 #define SCE_NSIS_LABEL 7 #define SCE_NSIS_USERDEFINED 8 #define SCE_NSIS_SECTIONDEF 9 #define SCE_NSIS_SUBSECTIONDEF 10 #define SCE_NSIS_IFDEFINEDEF 11 #define SCE_NSIS_MACRODEF 12 #define SCE_NSIS_STRINGVAR 13 #define SCE_NSIS_NUMBER 14 // ADDED for Scintilla v1.63 #define SCE_NSIS_SECTIONGROUP 15 #define SCE_NSIS_PAGEEX 16 #define SCE_NSIS_FUNCTIONDEF 17 #define SCE_NSIS_COMMENTBOX 18 */ static bool isNsisNumber(char ch) { return (ch >= '0' && ch <= '9'); } static bool isNsisChar(char ch) { return (ch == '.' ) || (ch == '_' ) || isNsisNumber(ch) || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); } static bool isNsisLetter(char ch) { return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); } static bool NsisNextLineHasElse(unsigned int start, unsigned int end, Accessor &styler) { int nNextLine = -1; for( unsigned int i = start; i < end; i++ ) { char cNext = styler.SafeGetCharAt( i ); if( cNext == '\n' ) { nNextLine = i+1; break; } } if( nNextLine == -1 ) // We never found the next line... return false; for( unsigned int firstChar = nNextLine; firstChar < end; firstChar++ ) { char cNext = styler.SafeGetCharAt( firstChar ); if( cNext == ' ' ) continue; if( cNext == '\t' ) continue; if( cNext == '!' ) { if( styler.Match(firstChar, "!else") ) return true; } break; } return false; } static int NsisCmp( const char *s1, const char *s2, bool bIgnoreCase ) { if( bIgnoreCase ) return CompareCaseInsensitive( s1, s2); return strcmp( s1, s2 ); } static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel, Accessor &styler, bool bElse, bool foldUtilityCmd ) { int style = styler.StyleAt(end); // If the word is too long, it is not what we are looking for if( end - start > 20 ) return foldlevel; if( foldUtilityCmd ) { // Check the style at this point, if it is not valid, then return zero if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF && style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_IFDEFINEDEF && style != SCE_NSIS_MACRODEF && style != SCE_NSIS_SECTIONGROUP && style != SCE_NSIS_PAGEEX ) return foldlevel; } else { if( style != SCE_NSIS_FUNCTIONDEF && style != SCE_NSIS_SECTIONDEF && style != SCE_NSIS_SUBSECTIONDEF && style != SCE_NSIS_SECTIONGROUP && style != SCE_NSIS_PAGEEX ) return foldlevel; } int newFoldlevel = foldlevel; bool bIgnoreCase = false; if( styler.GetPropertyInt("nsis.ignorecase") == 1 ) bIgnoreCase = true; char s[20]; // The key word we are looking for has atmost 13 characters s[0] = '\0'; for (unsigned int i = 0; i < end - start + 1 && i < 19; i++) { s[i] = static_cast<char>( styler[ start + i ] ); s[i + 1] = '\0'; } if( s[0] == '!' ) { if( NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrodef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrondef", bIgnoreCase ) == 0 || NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!macro", bIgnoreCase ) == 0 ) newFoldlevel++; else if( NsisCmp(s, "!endif", bIgnoreCase) == 0 || NsisCmp(s, "!macroend", bIgnoreCase ) == 0 ) newFoldlevel--; else if( bElse && NsisCmp(s, "!else", bIgnoreCase) == 0 ) newFoldlevel++; } else { if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionGroup", bIgnoreCase ) == 0 || NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "SubSection", bIgnoreCase ) == 0 || NsisCmp(s, "PageEx", bIgnoreCase ) == 0 ) newFoldlevel++; else if( NsisCmp(s, "SectionGroupEnd", bIgnoreCase ) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase ) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase ) == 0 ) newFoldlevel--; } return newFoldlevel; } static int classifyWordNsis(unsigned int start, unsigned int end, WordList *keywordLists[], Accessor &styler ) { bool bIgnoreCase = false; if( styler.GetPropertyInt("nsis.ignorecase") == 1 ) bIgnoreCase = true; bool bUserVars = false; if( styler.GetPropertyInt("nsis.uservars") == 1 ) bUserVars = true; char s[100]; WordList &Functions = *keywordLists[0]; WordList &Variables = *keywordLists[1]; WordList &Lables = *keywordLists[2]; WordList &UserDefined = *keywordLists[3]; for (unsigned int i = 0; i < end - start + 1 && i < 99; i++) { if( bIgnoreCase ) s[i] = static_cast<char>( tolower(styler[ start + i ] ) ); else s[i] = static_cast<char>( styler[ start + i ] ); s[i + 1] = '\0'; } // Check for special words... if( NsisCmp(s, "!macro", bIgnoreCase ) == 0 || NsisCmp(s, "!macroend", bIgnoreCase) == 0 ) // Covers !macro and !macroend return SCE_NSIS_MACRODEF; if( NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!endif", bIgnoreCase) == 0 ) // Covers !ifdef, !ifndef and !endif return SCE_NSIS_IFDEFINEDEF; if( NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!else", bIgnoreCase ) == 0 ) // Covers !if and else return SCE_NSIS_IFDEFINEDEF; if (NsisCmp(s, "!ifmacrodef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrondef", bIgnoreCase ) == 0 ) // Covers !ifmacrodef and !ifnmacrodef return SCE_NSIS_IFDEFINEDEF; if( NsisCmp(s, "SectionGroup", bIgnoreCase) == 0 || NsisCmp(s, "SectionGroupEnd", bIgnoreCase) == 0 ) // Covers SectionGroup and SectionGroupEnd return SCE_NSIS_SECTIONGROUP; if( NsisCmp(s, "Section", bIgnoreCase ) == 0 || NsisCmp(s, "SectionEnd", bIgnoreCase) == 0 ) // Covers Section and SectionEnd return SCE_NSIS_SECTIONDEF; if( NsisCmp(s, "SubSection", bIgnoreCase) == 0 || NsisCmp(s, "SubSectionEnd", bIgnoreCase) == 0 ) // Covers SubSection and SubSectionEnd return SCE_NSIS_SUBSECTIONDEF; if( NsisCmp(s, "PageEx", bIgnoreCase) == 0 || NsisCmp(s, "PageExEnd", bIgnoreCase) == 0 ) // Covers PageEx and PageExEnd return SCE_NSIS_PAGEEX; if( NsisCmp(s, "Function", bIgnoreCase) == 0 || NsisCmp(s, "FunctionEnd", bIgnoreCase) == 0 ) // Covers Function and FunctionEnd return SCE_NSIS_FUNCTIONDEF; if ( Functions.InList(s) ) return SCE_NSIS_FUNCTION; if ( Variables.InList(s) ) return SCE_NSIS_VARIABLE; if ( Lables.InList(s) ) return SCE_NSIS_LABEL; if( UserDefined.InList(s) ) return SCE_NSIS_USERDEFINED; if( strlen(s) > 3 ) { if( s[1] == '{' && s[strlen(s)-1] == '}' ) return SCE_NSIS_VARIABLE; } // See if the variable is a user defined variable if( s[0] == '$' && bUserVars ) { bool bHasSimpleNsisChars = true; for (unsigned int j = 1; j < end - start + 1 && j < 99; j++) { if( !isNsisChar( s[j] ) ) { bHasSimpleNsisChars = false; break; } } if( bHasSimpleNsisChars ) return SCE_NSIS_VARIABLE; } // To check for numbers if( isNsisNumber( s[0] ) ) { bool bHasSimpleNsisNumber = true; for (unsigned int j = 1; j < end - start + 1 && j < 99; j++) { if( !isNsisNumber( s[j] ) ) { bHasSimpleNsisNumber = false; break; } } if( bHasSimpleNsisNumber ) return SCE_NSIS_NUMBER; } return SCE_NSIS_DEFAULT; } static void ColouriseNsisDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) { int state = SCE_NSIS_DEFAULT; if( startPos > 0 ) state = styler.StyleAt(startPos-1); // Use the style from the previous line, usually default, but could be commentbox styler.StartAt( startPos ); styler.GetLine( startPos ); unsigned int nLengthDoc = startPos + length; styler.StartSegment( startPos ); char cCurrChar; bool bVarInString = false; bool bClassicVarInString = false; unsigned int i; for( i = startPos; i < nLengthDoc; i++ ) { cCurrChar = styler.SafeGetCharAt( i ); char cNextChar = styler.SafeGetCharAt(i+1); switch(state) { case SCE_NSIS_DEFAULT: if( cCurrChar == ';' || cCurrChar == '#' ) // we have a comment line { styler.ColourTo(i-1, state ); state = SCE_NSIS_COMMENT; break; } if( cCurrChar == '"' ) { styler.ColourTo(i-1, state ); state = SCE_NSIS_STRINGDQ; bVarInString = false; bClassicVarInString = false; break; } if( cCurrChar == '\'' ) { styler.ColourTo(i-1, state ); state = SCE_NSIS_STRINGRQ; bVarInString = false; bClassicVarInString = false; break; } if( cCurrChar == '`' ) { styler.ColourTo(i-1, state ); state = SCE_NSIS_STRINGLQ; bVarInString = false; bClassicVarInString = false; break; } // NSIS KeyWord,Function, Variable, UserDefined: if( cCurrChar == '$' || isNsisChar(cCurrChar) || cCurrChar == '!' ) { styler.ColourTo(i-1,state); state = SCE_NSIS_FUNCTION; // If it is a number, we must check and set style here first... if( isNsisNumber(cCurrChar) && (cNextChar == '\t' || cNextChar == ' ' || cNextChar == '\r' || cNextChar == '\n' ) ) styler.ColourTo( i, SCE_NSIS_NUMBER); break; } if( cCurrChar == '/' && cNextChar == '*' ) { styler.ColourTo(i-1,state); state = SCE_NSIS_COMMENTBOX; break; } break; case SCE_NSIS_COMMENT: if( cNextChar == '\n' || cNextChar == '\r' ) { // Special case: if( cCurrChar == '\\' ) { styler.ColourTo(i-2,state); styler.ColourTo(i,SCE_NSIS_DEFAULT); } else { styler.ColourTo(i,state); state = SCE_NSIS_DEFAULT; } } break; case SCE_NSIS_STRINGDQ: case SCE_NSIS_STRINGLQ: case SCE_NSIS_STRINGRQ: if( styler.SafeGetCharAt(i-1) == '\\' && styler.SafeGetCharAt(i-2) == '$' ) break; // Ignore the next character, even if it is a quote of some sort if( cCurrChar == '"' && state == SCE_NSIS_STRINGDQ ) { styler.ColourTo(i,state); state = SCE_NSIS_DEFAULT; break; } if( cCurrChar == '`' && state == SCE_NSIS_STRINGLQ ) { styler.ColourTo(i,state); state = SCE_NSIS_DEFAULT; break; } if( cCurrChar == '\'' && state == SCE_NSIS_STRINGRQ ) { styler.ColourTo(i,state); state = SCE_NSIS_DEFAULT; break; } if( cNextChar == '\r' || cNextChar == '\n' ) { int nCurLine = styler.GetLine(i+1); int nBack = i; // We need to check if the previous line has a \ in it... bool bNextLine = false; while( nBack > 0 ) { if( styler.GetLine(nBack) != nCurLine ) break; char cTemp = styler.SafeGetCharAt(nBack, 'a'); // Letter 'a' is safe here if( cTemp == '\\' ) { bNextLine = true; break; } if( cTemp != '\r' && cTemp != '\n' && cTemp != '\t' && cTemp != ' ' ) break; nBack--; } if( bNextLine ) { styler.ColourTo(i+1,state); } if( bNextLine == false ) { styler.ColourTo(i,state); state = SCE_NSIS_DEFAULT; } } break; case SCE_NSIS_FUNCTION: // NSIS KeyWord: if( cCurrChar == '$' ) state = SCE_NSIS_DEFAULT; else if( cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' ) ) state = SCE_NSIS_DEFAULT; else if( (isNsisChar(cCurrChar) && !isNsisChar( cNextChar) && cNextChar != '}') || cCurrChar == '}' ) { state = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler ); styler.ColourTo( i, state); state = SCE_NSIS_DEFAULT; } else if( !isNsisChar( cCurrChar ) && cCurrChar != '{' && cCurrChar != '}' ) { if( classifyWordNsis( styler.GetStartSegment(), i-1, keywordLists, styler) == SCE_NSIS_NUMBER ) styler.ColourTo( i-1, SCE_NSIS_NUMBER ); state = SCE_NSIS_DEFAULT; if( cCurrChar == '"' ) { state = SCE_NSIS_STRINGDQ; bVarInString = false; bClassicVarInString = false; } else if( cCurrChar == '`' ) { state = SCE_NSIS_STRINGLQ; bVarInString = false; bClassicVarInString = false; } else if( cCurrChar == '\'' ) { state = SCE_NSIS_STRINGRQ; bVarInString = false; bClassicVarInString = false; } else if( cCurrChar == '#' || cCurrChar == ';' ) { state = SCE_NSIS_COMMENT; } } break; case SCE_NSIS_COMMENTBOX: if( styler.SafeGetCharAt(i-1) == '*' && cCurrChar == '/' ) { styler.ColourTo(i,state); state = SCE_NSIS_DEFAULT; } break; } if( state == SCE_NSIS_COMMENT || state == SCE_NSIS_COMMENTBOX ) { styler.ColourTo(i,state); } else if( state == SCE_NSIS_STRINGDQ || state == SCE_NSIS_STRINGLQ || state == SCE_NSIS_STRINGRQ ) { bool bIngoreNextDollarSign = false; bool bUserVars = false; if( styler.GetPropertyInt("nsis.uservars") == 1 ) bUserVars = true; if( bVarInString && cCurrChar == '$' ) { bVarInString = false; bIngoreNextDollarSign = true; } else if( bVarInString && cCurrChar == '\\' && (cNextChar == 'n' || cNextChar == 'r' || cNextChar == 't' || cNextChar == '"' || cNextChar == '`' || cNextChar == '\'' ) ) { styler.ColourTo( i+1, SCE_NSIS_STRINGVAR); bVarInString = false; bIngoreNextDollarSign = false; } // Covers "$INSTDIR and user vars like $MYVAR" else if( bVarInString && !isNsisChar(cNextChar) ) { int nWordState = classifyWordNsis( styler.GetStartSegment(), i, keywordLists, styler); if( nWordState == SCE_NSIS_VARIABLE ) styler.ColourTo( i, SCE_NSIS_STRINGVAR); else if( bUserVars ) styler.ColourTo( i, SCE_NSIS_STRINGVAR); bVarInString = false; } // Covers "${TEST}..." else if( bClassicVarInString && cNextChar == '}' ) { styler.ColourTo( i+1, SCE_NSIS_STRINGVAR); bClassicVarInString = false; } // Start of var in string if( !bIngoreNextDollarSign && cCurrChar == '$' && cNextChar == '{' ) { styler.ColourTo( i-1, state); bClassicVarInString = true; bVarInString = false; } else if( !bIngoreNextDollarSign && cCurrChar == '$' ) { styler.ColourTo( i-1, state); bVarInString = true; bClassicVarInString = false; } } } // Colourise remaining document styler.ColourTo(nLengthDoc-1,state); } static void FoldNsisDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { // No folding enabled, no reason to continue... if( styler.GetPropertyInt("fold") == 0 ) return; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) == 1; bool foldUtilityCmd = styler.GetPropertyInt("nsis.foldutilcmd", 1) == 1; bool blockComment = false; int lineCurrent = styler.GetLine(startPos); unsigned int safeStartPos = styler.LineStart( lineCurrent ); bool bArg1 = true; int nWordStart = -1; int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelNext = levelCurrent; int style = styler.StyleAt(safeStartPos); if( style == SCE_NSIS_COMMENTBOX ) { if( styler.SafeGetCharAt(safeStartPos) == '/' && styler.SafeGetCharAt(safeStartPos+1) == '*' ) levelNext++; blockComment = true; } for (unsigned int i = safeStartPos; i < startPos + length; i++) { char chCurr = styler.SafeGetCharAt(i); style = styler.StyleAt(i); if( blockComment && style != SCE_NSIS_COMMENTBOX ) { levelNext--; blockComment = false; } else if( !blockComment && style == SCE_NSIS_COMMENTBOX ) { levelNext++; blockComment = true; } if( bArg1 && !blockComment) { if( nWordStart == -1 && (isNsisLetter(chCurr) || chCurr == '!') ) { nWordStart = i; } else if( isNsisLetter(chCurr) == false && nWordStart > -1 ) { int newLevel = calculateFoldNsis( nWordStart, i-1, levelNext, styler, foldAtElse, foldUtilityCmd ); if( newLevel == levelNext ) { if( foldAtElse && foldUtilityCmd ) { if( NsisNextLineHasElse(i, startPos + length, styler) ) levelNext--; } } else levelNext = newLevel; bArg1 = false; } } if( chCurr == '\n' ) { if( bArg1 && foldAtElse && foldUtilityCmd && !blockComment ) { if( NsisNextLineHasElse(i, startPos + length, styler) ) levelNext--; } // If we are on a new line... int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; if (levelUse < levelNext ) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) styler.SetLevel(lineCurrent, lev); lineCurrent++; levelCurrent = levelNext; bArg1 = true; // New line, lets look at first argument again nWordStart = -1; } } int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) styler.SetLevel(lineCurrent, lev); } static const char * const nsisWordLists[] = { "Functions", "Variables", "Lables", "UserDefined", 0, }; LexerModule lmNsis(SCLEX_NSIS, ColouriseNsisDoc, "nsis", FoldNsisDoc, nsisWordLists); |
Added lexers/LexOScript.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 |
// Scintilla source code edit control /** @file LexOScript.cxx ** Lexer for OScript sources; ocx files and/or OSpace dumps. ** OScript is a programming language used to develop applications for the ** Livelink server platform. **/ // Written by Ferdinand Prantl <prantlf@gmail.com>, inspired by the code from // LexVB.cxx and LexPascal.cxx. The License.txt file describes the conditions // under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // ----------------------------------------- // Functions classifying a single character. // This function is generic and should be probably moved to CharSet.h where // IsAlphaNumeric the others reside. inline bool IsAlpha(int ch) { return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); } static inline bool IsIdentifierChar(int ch) { // Identifiers cannot contain non-ASCII letters; a word with non-English // language-specific characters cannot be an identifier. return IsAlphaNumeric(ch) || ch == '_'; } static inline bool IsIdentifierStart(int ch) { // Identifiers cannot contain non-ASCII letters; a word with non-English // language-specific characters cannot be an identifier. return IsAlpha(ch) || ch == '_'; } static inline bool IsNumberChar(int ch, int chNext) { // Numeric constructs are not checked for lexical correctness. They are // expected to look like +1.23-E9 but actually any bunch of the following // characters will be styled as number. // KNOWN PROBLEM: if you put + or - operators immediately after a number // and the next operand starts with the letter E, the operator will not be // recognized and it will be styled together with the preceding number. // This should not occur; at least not often. The coding style recommends // putting spaces around operators. return IsADigit(ch) || toupper(ch) == 'E' || ch == '.' || ((ch == '-' || ch == '+') && toupper(chNext) == 'E'); } // This function checks for the start or a natural number without any symbols // or operators as a prefix; the IsPrefixedNumberStart should be called // immediately after this one to cover all possible numeric constructs. static inline bool IsNaturalNumberStart(int ch) { return IsADigit(ch) != 0; } static inline bool IsPrefixedNumberStart(int ch, int chNext) { // KNOWN PROBLEM: if you put + or - operators immediately before a number // the operator will not be recognized and it will be styled together with // the succeeding number. This should not occur; at least not often. The // coding style recommends putting spaces around operators. return (ch == '.' || ch == '-' || ch == '+') && IsADigit(chNext); } static inline bool IsOperator(int ch) { return strchr("%^&*()-+={}[]:;<>,/?!.~|\\", ch) != NULL; } // --------------------------------------------------------------- // Functions classifying a token currently processed in the lexer. // Checks if the current line starts with the preprocessor directive used // usually to introduce documentation comments: #ifdef DOC. This method is // supposed to be called if the line has been recognized as a preprocessor // directive already. static bool IsDocCommentStart(StyleContext &sc) { // Check the line back to its start only if the end looks promising. if (sc.LengthCurrent() == 10 && !IsAlphaNumeric(sc.ch)) { char s[11]; sc.GetCurrentLowered(s, sizeof(s)); return strcmp(s, "#ifdef doc") == 0; } return false; } // Checks if the current line starts with the preprocessor directive that // is complementary to the #ifdef DOC start: #endif. This method is supposed // to be called if the current state point to the documentation comment. // QUESTIONAL ASSUMPTION: The complete #endif directive is not checked; just // the starting #e. However, there is no other preprocessor directive with // the same starting letter and thus this optimization should always work. static bool IsDocCommentEnd(StyleContext &sc) { return sc.ch == '#' && sc.chNext == 'e'; } class IdentifierClassifier { WordList &keywords; // Passed from keywords property. WordList &constants; // Passed from keywords2 property. WordList &operators; // Passed from keywords3 property. WordList &types; // Passed from keywords4 property. WordList &functions; // Passed from keywords5 property. WordList &objects; // Passed from keywords6 property. IdentifierClassifier(IdentifierClassifier const&); IdentifierClassifier& operator=(IdentifierClassifier const&); public: IdentifierClassifier(WordList *keywordlists[]) : keywords(*keywordlists[0]), constants(*keywordlists[1]), operators(*keywordlists[2]), types(*keywordlists[3]), functions(*keywordlists[4]), objects(*keywordlists[5]) {} void ClassifyIdentifier(StyleContext &sc) { // Opening parenthesis following an identifier makes it a possible // function call. // KNOWN PROBLEM: If some whitespace is inserted between the // identifier and the parenthesis they will not be able to be // recognized as a function call. This should not occur; at // least not often. Such coding style would be weird. if (sc.Match('(')) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); // Before an opening brace can be control statements and // operators too; function call is the last option. if (keywords.InList(s)) { sc.ChangeState(SCE_OSCRIPT_KEYWORD); } else if (operators.InList(s)) { sc.ChangeState(SCE_OSCRIPT_OPERATOR); } else if (functions.InList(s)) { sc.ChangeState(SCE_OSCRIPT_FUNCTION); } else { sc.ChangeState(SCE_OSCRIPT_METHOD); } sc.SetState(SCE_OSCRIPT_OPERATOR); } else { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); // A dot following an identifier means an access to an object // member. The related object identifier can be special. // KNOWN PROBLEM: If there is whitespace between the identifier // and the following dot, the identifier will not be recognized // as an object in an object member access. If it is one of the // listed static objects it will not be styled. if (sc.Match('.') && objects.InList(s)) { sc.ChangeState(SCE_OSCRIPT_OBJECT); sc.SetState(SCE_OSCRIPT_OPERATOR); } else { if (keywords.InList(s)) { sc.ChangeState(SCE_OSCRIPT_KEYWORD); } else if (constants.InList(s)) { sc.ChangeState(SCE_OSCRIPT_CONSTANT); } else if (operators.InList(s)) { sc.ChangeState(SCE_OSCRIPT_OPERATOR); } else if (types.InList(s)) { sc.ChangeState(SCE_OSCRIPT_TYPE); } else if (functions.InList(s)) { sc.ChangeState(SCE_OSCRIPT_FUNCTION); } sc.SetState(SCE_OSCRIPT_DEFAULT); } } } }; // ------------------------------------------------ // Function colourising an excerpt of OScript code. static void ColouriseOScriptDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { // I wonder how whole-line styles ended by EOLN can escape the resetting // code in the loop below and overflow to the next line. Let us make sure // that a new line does not start with them carried from the previous one. // NOTE: An overflowing string is intentionally not checked; it reminds // the developer that the string must be ended on the same line. if (initStyle == SCE_OSCRIPT_LINE_COMMENT || initStyle == SCE_OSCRIPT_PREPROCESSOR) { initStyle = SCE_OSCRIPT_DEFAULT; } styler.StartAt(startPos); StyleContext sc(startPos, length, initStyle, styler); IdentifierClassifier identifierClassifier(keywordlists); // It starts with true at the beginning of a line and changes to false as // soon as the first non-whitespace character has been processed. bool isFirstToken = true; // It starts with true at the beginning of a line and changes to false as // soon as the first identifier on the line is passed by. bool isFirstIdentifier = true; // It becomes false when #ifdef DOC (the preprocessor directive often // used to start a documentation comment) is encountered and remain false // until the end of the documentation block is not detected. This is done // by checking for the complementary #endif preprocessor directive. bool endDocComment = false; for (; sc.More(); sc.Forward()) { if (sc.atLineStart) { isFirstToken = true; isFirstIdentifier = true; // Detect the current state is neither whitespace nor identifier. It // means that no next identifier can be the first token on the line. } else if (isFirstIdentifier && sc.state != SCE_OSCRIPT_DEFAULT && sc.state != SCE_OSCRIPT_IDENTIFIER) { isFirstIdentifier = false; } // Check if the current state should be changed. if (sc.state == SCE_OSCRIPT_OPERATOR) { // Multiple-symbol operators are marked by single characters. sc.SetState(SCE_OSCRIPT_DEFAULT); } else if (sc.state == SCE_OSCRIPT_IDENTIFIER) { if (!IsIdentifierChar(sc.ch)) { // Colon after an identifier makes it a label if it is the // first token on the line. // KNOWN PROBLEM: If some whitespace is inserted between the // identifier and the colon they will not be recognized as a // label. This should not occur; at least not often. It would // make the code structure less legible and examples in the // Livelink documentation do not show it. if (sc.Match(':') && isFirstIdentifier) { sc.ChangeState(SCE_OSCRIPT_LABEL); sc.ForwardSetState(SCE_OSCRIPT_DEFAULT); } else { identifierClassifier.ClassifyIdentifier(sc); } // Avoid a sequence of two words be mistaken for a label. A // switch case would be an example. isFirstIdentifier = false; } } else if (sc.state == SCE_OSCRIPT_GLOBAL) { if (!IsIdentifierChar(sc.ch)) { sc.SetState(SCE_OSCRIPT_DEFAULT); } } else if (sc.state == SCE_OSCRIPT_PROPERTY) { if (!IsIdentifierChar(sc.ch)) { // Any member access introduced by the dot operator is // initially marked as a property access. If an opening // parenthesis is detected later it is changed to method call. // KNOWN PROBLEM: The same as at the function call recognition // for SCE_OSCRIPT_IDENTIFIER above. if (sc.Match('(')) { sc.ChangeState(SCE_OSCRIPT_METHOD); } sc.SetState(SCE_OSCRIPT_DEFAULT); } } else if (sc.state == SCE_OSCRIPT_NUMBER) { if (!IsNumberChar(sc.ch, sc.chNext)) { sc.SetState(SCE_OSCRIPT_DEFAULT); } } else if (sc.state == SCE_OSCRIPT_SINGLEQUOTE_STRING) { if (sc.ch == '\'') { // Two consequential apostrophes convert to a single one. if (sc.chNext == '\'') { sc.Forward(); } else { sc.ForwardSetState(SCE_OSCRIPT_DEFAULT); } } else if (sc.atLineEnd) { sc.ForwardSetState(SCE_OSCRIPT_DEFAULT); } } else if (sc.state == SCE_OSCRIPT_DOUBLEQUOTE_STRING) { if (sc.ch == '\"') { // Two consequential quotation marks convert to a single one. if (sc.chNext == '\"') { sc.Forward(); } else { sc.ForwardSetState(SCE_OSCRIPT_DEFAULT); } } else if (sc.atLineEnd) { sc.ForwardSetState(SCE_OSCRIPT_DEFAULT); } } else if (sc.state == SCE_OSCRIPT_BLOCK_COMMENT) { if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_OSCRIPT_DEFAULT); } } else if (sc.state == SCE_OSCRIPT_LINE_COMMENT) { if (sc.atLineEnd) { sc.ForwardSetState(SCE_OSCRIPT_DEFAULT); } } else if (sc.state == SCE_OSCRIPT_PREPROCESSOR) { if (IsDocCommentStart(sc)) { sc.ChangeState(SCE_OSCRIPT_DOC_COMMENT); endDocComment = false; } else if (sc.atLineEnd) { sc.ForwardSetState(SCE_OSCRIPT_DEFAULT); } } else if (sc.state == SCE_OSCRIPT_DOC_COMMENT) { // KNOWN PROBLEM: The first line detected that would close a // conditional preprocessor block (#endif) the documentation // comment block will end. (Nested #if-#endif blocks are not // supported. Hopefully it will not occur often that a line // within the text block would stat with #endif. if (isFirstToken && IsDocCommentEnd(sc)) { endDocComment = true; } else if (sc.atLineEnd && endDocComment) { sc.ForwardSetState(SCE_OSCRIPT_DEFAULT); } } // Check what state starts with the current character. if (sc.state == SCE_OSCRIPT_DEFAULT) { if (sc.Match('\'')) { sc.SetState(SCE_OSCRIPT_SINGLEQUOTE_STRING); } else if (sc.Match('\"')) { sc.SetState(SCE_OSCRIPT_DOUBLEQUOTE_STRING); } else if (sc.Match('/', '/')) { sc.SetState(SCE_OSCRIPT_LINE_COMMENT); sc.Forward(); } else if (sc.Match('/', '*')) { sc.SetState(SCE_OSCRIPT_BLOCK_COMMENT); sc.Forward(); } else if (isFirstToken && sc.Match('#')) { sc.SetState(SCE_OSCRIPT_PREPROCESSOR); } else if (sc.Match('$')) { // Both process-global ($xxx) and thread-global ($$xxx) // variables are handled as one global. sc.SetState(SCE_OSCRIPT_GLOBAL); } else if (IsNaturalNumberStart(sc.ch)) { sc.SetState(SCE_OSCRIPT_NUMBER); } else if (IsPrefixedNumberStart(sc.ch, sc.chNext)) { sc.SetState(SCE_OSCRIPT_NUMBER); sc.Forward(); } else if (sc.Match('.') && IsIdentifierStart(sc.chNext)) { // Every object member access is marked as a property access // initially. The decision between property and method is made // after parsing the identifier and looking what comes then. // KNOWN PROBLEM: If there is whitespace between the following // identifier and the dot, the dot will not be recognized // as a member accessing operator. In turn, the identifier // will not be recognizable as a property or a method too. sc.SetState(SCE_OSCRIPT_OPERATOR); sc.Forward(); sc.SetState(SCE_OSCRIPT_PROPERTY); } else if (IsIdentifierStart(sc.ch)) { sc.SetState(SCE_OSCRIPT_IDENTIFIER); } else if (IsOperator(sc.ch)) { sc.SetState(SCE_OSCRIPT_OPERATOR); } } if (isFirstToken && !IsASpaceOrTab(sc.ch)) { isFirstToken = false; } } sc.Complete(); } // ------------------------------------------ // Functions supporting OScript code folding. static inline bool IsBlockComment(int style) { return style == SCE_OSCRIPT_BLOCK_COMMENT; } static bool IsLineComment(int line, Accessor &styler) { int pos = styler.LineStart(line); int eolPos = styler.LineStart(line + 1) - 1; for (int i = pos; i < eolPos; i++) { char ch = styler[i]; char chNext = styler.SafeGetCharAt(i + 1); int style = styler.StyleAt(i); if (ch == '/' && chNext == '/' && style == SCE_OSCRIPT_LINE_COMMENT) { return true; } else if (!IsASpaceOrTab(ch)) { return false; } } return false; } static inline bool IsPreprocessor(int style) { return style == SCE_OSCRIPT_PREPROCESSOR || style == SCE_OSCRIPT_DOC_COMMENT; } static void GetRangeLowered(unsigned int start, unsigned int end, Accessor &styler, char *s, unsigned int len) { unsigned int i = 0; while (i < end - start + 1 && i < len - 1) { s[i] = static_cast<char>(tolower(styler[start + i])); i++; } s[i] = '\0'; } static void GetForwardWordLowered(unsigned int start, Accessor &styler, char *s, unsigned int len) { unsigned int i = 0; while (i < len - 1 && IsAlpha(styler.SafeGetCharAt(start + i))) { s[i] = static_cast<char>(tolower(styler.SafeGetCharAt(start + i))); i++; } s[i] = '\0'; } static void UpdatePreprocessorFoldLevel(int &levelCurrent, unsigned int startPos, Accessor &styler) { char s[7]; // Size of the longest possible keyword + null. GetForwardWordLowered(startPos, styler, s, sizeof(s)); if (strcmp(s, "ifdef") == 0 || strcmp(s, "ifndef") == 0) { levelCurrent++; } else if (strcmp(s, "endif") == 0) { levelCurrent--; if (levelCurrent < SC_FOLDLEVELBASE) { levelCurrent = SC_FOLDLEVELBASE; } } } static void UpdateKeywordFoldLevel(int &levelCurrent, unsigned int lastStart, unsigned int currentPos, Accessor &styler) { char s[9]; GetRangeLowered(lastStart, currentPos, styler, s, sizeof(s)); if (strcmp(s, "if") == 0 || strcmp(s, "for") == 0 || strcmp(s, "switch") == 0 || strcmp(s, "function") == 0 || strcmp(s, "while") == 0 || strcmp(s, "repeat") == 0) { levelCurrent++; } else if (strcmp(s, "end") == 0 || strcmp(s, "until") == 0) { levelCurrent--; if (levelCurrent < SC_FOLDLEVELBASE) { levelCurrent = SC_FOLDLEVELBASE; } } } // ------------------------------ // Function folding OScript code. static void FoldOScriptDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; int lastStart = 0; for (int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atLineEnd = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment && IsBlockComment(style)) { if (!IsBlockComment(stylePrev)) { levelCurrent++; } else if (!IsBlockComment(styleNext) && !atLineEnd) { // Comments do not end at end of line and the next character // may not be styled. levelCurrent--; } } if (foldComment && atLineEnd && IsLineComment(lineCurrent, styler)) { if (!IsLineComment(lineCurrent - 1, styler) && IsLineComment(lineCurrent + 1, styler)) levelCurrent++; else if (IsLineComment(lineCurrent - 1, styler) && !IsLineComment(lineCurrent+1, styler)) levelCurrent--; } if (foldPreprocessor) { if (ch == '#' && IsPreprocessor(style)) { UpdatePreprocessorFoldLevel(levelCurrent, i + 1, styler); } } if (stylePrev != SCE_OSCRIPT_KEYWORD && style == SCE_OSCRIPT_KEYWORD) { lastStart = i; } if (stylePrev == SCE_OSCRIPT_KEYWORD) { if(IsIdentifierChar(ch) && !IsIdentifierChar(chNext)) { UpdateKeywordFoldLevel(levelCurrent, lastStart, i, styler); } } if (!IsASpace(ch)) visibleChars++; if (atLineEnd) { int level = levelPrev; if (visibleChars == 0 && foldCompact) level |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) level |= SC_FOLDLEVELHEADERFLAG; if (level != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, level); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } } // If we did not reach EOLN in the previous loop, store the line level and // whitespace information. The rest will be filled in later. int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; styler.SetLevel(lineCurrent, lev); } // -------------------------------------------- // Declaration of the OScript lexer descriptor. static const char * const oscriptWordListDesc[] = { "Keywords and reserved words", "Literal constants", "Literal operators", "Built-in value and reference types", "Built-in global functions", "Built-in static objects", 0 }; LexerModule lmOScript(SCLEX_OSCRIPT, ColouriseOScriptDoc, "oscript", FoldOScriptDoc, oscriptWordListDesc); |
Added lexers/LexOpal.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 |
// Scintilla source code edit control /** @file LexOpal.cxx ** Lexer for OPAL (functional language similar to Haskell) ** Written by Sebastian Pipping <webmaster@hartwork.org> **/ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif inline static void getRange( unsigned int start, unsigned int end, Accessor & styler, char * s, unsigned int len ) { unsigned int i = 0; while( ( i < end - start + 1 ) && ( i < len - 1 ) ) { s[i] = static_cast<char>( styler[ start + i ] ); i++; } s[ i ] = '\0'; } inline bool HandleString( unsigned int & cur, unsigned int one_too_much, Accessor & styler ) { char ch; // Wait for string to close bool even_backslash_count = true; // Without gaps in between cur++; // Skip initial quote for( ; ; ) { if( cur >= one_too_much ) { styler.ColourTo( cur - 1, SCE_OPAL_STRING ); return false; // STOP } ch = styler.SafeGetCharAt( cur ); if( ( ch == '\015' ) || ( ch == '\012' ) ) // Deny multi-line strings { styler.ColourTo( cur - 1, SCE_OPAL_STRING ); styler.StartSegment( cur ); return true; } else { if( even_backslash_count ) { if( ch == '"' ) { styler.ColourTo( cur, SCE_OPAL_STRING ); cur++; if( cur >= one_too_much ) { return false; // STOP } else { styler.StartSegment( cur ); return true; } } else if( ch == '\\' ) { even_backslash_count = false; } } else { even_backslash_count = true; } } cur++; } } inline bool HandleCommentBlock( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail ) { char ch; if( could_fail ) { cur++; if( cur >= one_too_much ) { styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT ); return false; // STOP } ch = styler.SafeGetCharAt( cur ); if( ch != '*' ) { styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT ); styler.StartSegment( cur ); return true; } } // Wait for comment close cur++; bool star_found = false; for( ; ; ) { if( cur >= one_too_much ) { styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_BLOCK ); return false; // STOP } ch = styler.SafeGetCharAt( cur ); if( star_found ) { if( ch == '/' ) { styler.ColourTo( cur, SCE_OPAL_COMMENT_BLOCK ); cur++; if( cur >= one_too_much ) { return false; // STOP } else { styler.StartSegment( cur ); return true; } } else if( ch != '*' ) { star_found = false; } } else if( ch == '*' ) { star_found = true; } cur++; } } inline bool HandleCommentLine( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail ) { char ch; if( could_fail ) { cur++; if( cur >= one_too_much ) { styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT ); return false; // STOP } ch = styler.SafeGetCharAt( cur ); if( ch != '-' ) { styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT ); styler.StartSegment( cur ); return true; } cur++; if( cur >= one_too_much ) { styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT ); return false; // STOP } ch = styler.SafeGetCharAt( cur ); if( ( ch != ' ' ) && ( ch != '\t' ) ) { styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT ); styler.StartSegment( cur ); return true; } } // Wait for end of line bool fifteen_found = false; for( ; ; ) { cur++; if( cur >= one_too_much ) { styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE ); return false; // STOP } ch = styler.SafeGetCharAt( cur ); if( fifteen_found ) { /* if( ch == '\012' ) { // One newline on Windows (015, 012) } else { // One newline on MAC (015) and another char } */ cur--; styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE ); styler.StartSegment( cur ); return true; } else { if( ch == '\015' ) { fifteen_found = true; } else if( ch == '\012' ) { // One newline on Linux (012) styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE ); styler.StartSegment( cur ); return true; } } } } inline bool HandlePar( unsigned int & cur, Accessor & styler ) { styler.ColourTo( cur, SCE_OPAL_PAR ); cur++; styler.StartSegment( cur ); return true; } inline bool HandleSpace( unsigned int & cur, unsigned int one_too_much, Accessor & styler ) { char ch; cur++; for( ; ; ) { if( cur >= one_too_much ) { styler.ColourTo( cur - 1, SCE_OPAL_SPACE ); return false; } ch = styler.SafeGetCharAt( cur ); switch( ch ) { case ' ': case '\t': case '\015': case '\012': cur++; break; default: styler.ColourTo( cur - 1, SCE_OPAL_SPACE ); styler.StartSegment( cur ); return true; } } } inline bool HandleInteger( unsigned int & cur, unsigned int one_too_much, Accessor & styler ) { char ch; for( ; ; ) { cur++; if( cur >= one_too_much ) { styler.ColourTo( cur - 1, SCE_OPAL_INTEGER ); return false; // STOP } ch = styler.SafeGetCharAt( cur ); if( !( isascii( ch ) && isdigit( ch ) ) ) { styler.ColourTo( cur - 1, SCE_OPAL_INTEGER ); styler.StartSegment( cur ); return true; } } } inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor & styler, WordList * keywordlists[] ) { char ch; const unsigned int beg = cur; cur++; for( ; ; ) { ch = styler.SafeGetCharAt( cur ); if( ( ch != '_' ) && ( ch != '-' ) && !( isascii( ch ) && ( islower( ch ) || isupper( ch ) || isdigit( ch ) ) ) ) break; cur++; if( cur >= one_too_much ) { break; } } const int ide_len = cur - beg + 1; char * ide = new char[ ide_len ]; getRange( beg, cur, styler, ide, ide_len ); WordList & keywords = *keywordlists[ 0 ]; WordList & classwords = *keywordlists[ 1 ]; if( keywords.InList( ide ) ) // Keyword { delete [] ide; styler.ColourTo( cur - 1, SCE_OPAL_KEYWORD ); if( cur >= one_too_much ) { return false; // STOP } else { styler.StartSegment( cur ); return true; } } else if( classwords.InList( ide ) ) // Sort { delete [] ide; styler.ColourTo( cur - 1, SCE_OPAL_SORT ); if( cur >= one_too_much ) { return false; // STOP } else { styler.StartSegment( cur ); return true; } } else if( !strcmp( ide, "true" ) || !strcmp( ide, "false" ) ) // Bool const { delete [] ide; styler.ColourTo( cur - 1, SCE_OPAL_BOOL_CONST ); if( cur >= one_too_much ) { return false; // STOP } else { styler.StartSegment( cur ); return true; } } else // Unknown keyword { delete [] ide; styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT ); if( cur >= one_too_much ) { return false; // STOP } else { styler.StartSegment( cur ); return true; } } } inline bool HandleSkip( unsigned int & cur, unsigned int one_too_much, Accessor & styler ) { cur++; styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT ); if( cur >= one_too_much ) { return false; // STOP } else { styler.StartSegment( cur ); return true; } } static void ColouriseOpalDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor & styler ) { styler.StartAt( startPos ); styler.StartSegment( startPos ); unsigned int & cur = startPos; const unsigned int one_too_much = startPos + length; int state = initStyle; for( ; ; ) { switch( state ) { case SCE_OPAL_KEYWORD: case SCE_OPAL_SORT: if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return; state = SCE_OPAL_DEFAULT; break; case SCE_OPAL_INTEGER: if( !HandleInteger( cur, one_too_much, styler ) ) return; state = SCE_OPAL_DEFAULT; break; case SCE_OPAL_COMMENT_BLOCK: if( !HandleCommentBlock( cur, one_too_much, styler, false ) ) return; state = SCE_OPAL_DEFAULT; break; case SCE_OPAL_COMMENT_LINE: if( !HandleCommentLine( cur, one_too_much, styler, false ) ) return; state = SCE_OPAL_DEFAULT; break; case SCE_OPAL_STRING: if( !HandleString( cur, one_too_much, styler ) ) return; state = SCE_OPAL_DEFAULT; break; default: // SCE_OPAL_DEFAULT: { char ch = styler.SafeGetCharAt( cur ); switch( ch ) { // String case '"': if( !HandleString( cur, one_too_much, styler ) ) return; break; // Comment block case '/': if( !HandleCommentBlock( cur, one_too_much, styler, true ) ) return; break; // Comment line case '-': if( !HandleCommentLine( cur, one_too_much, styler, true ) ) return; break; // Par case '(': case ')': case '[': case ']': case '{': case '}': if( !HandlePar( cur, styler ) ) return; break; // Whitespace case ' ': case '\t': case '\015': case '\012': if( !HandleSpace( cur, one_too_much, styler ) ) return; break; default: { // Integer if( isascii( ch ) && isdigit( ch ) ) { if( !HandleInteger( cur, one_too_much, styler ) ) return; } // Keyword else if( isascii( ch ) && ( islower( ch ) || isupper( ch ) ) ) { if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return; } // Skip else { if( !HandleSkip( cur, one_too_much, styler ) ) return; } } } break; } } } } static const char * const opalWordListDesc[] = { "Keywords", "Sorts", 0 }; LexerModule lmOpal(SCLEX_OPAL, ColouriseOpalDoc, "opal", NULL, opalWordListDesc); |
Added lexers/LexOthers.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 |
// Scintilla source code edit control /** @file LexOthers.cxx ** Lexers for batch files, diff results, properties files, make files and error lists. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static bool strstart(const char *haystack, const char *needle) { return strncmp(haystack, needle, strlen(needle)) == 0; } static bool Is0To9(char ch) { return (ch >= '0') && (ch <= '9'); } static bool Is1To9(char ch) { return (ch >= '1') && (ch <= '9'); } static bool IsAlphabetic(int ch) { return isascii(ch) && isalpha(ch); } static inline bool AtEOL(Accessor &styler, unsigned int i) { return (styler[i] == '\n') || ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')); } // Tests for BATCH Operators static bool IsBOperator(char ch) { return (ch == '=') || (ch == '+') || (ch == '>') || (ch == '<') || (ch == '|') || (ch == '?') || (ch == '*'); } // Tests for BATCH Separators static bool IsBSeparator(char ch) { return (ch == '\\') || (ch == '.') || (ch == ';') || (ch == '\"') || (ch == '\'') || (ch == '/'); } static void ColouriseBatchLine( char *lineBuffer, unsigned int lengthLine, unsigned int startLine, unsigned int endPos, WordList *keywordlists[], Accessor &styler) { unsigned int offset = 0; // Line Buffer Offset unsigned int cmdLoc; // External Command / Program Location char wordBuffer[81]; // Word Buffer - large to catch long paths unsigned int wbl; // Word Buffer Length unsigned int wbo; // Word Buffer Offset - also Special Keyword Buffer Length WordList &keywords = *keywordlists[0]; // Internal Commands WordList &keywords2 = *keywordlists[1]; // External Commands (optional) // CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords // Toggling Regular Keyword Checking off improves readability // Other Regular Keywords and External Commands / Programs might also benefit from toggling // Need a more robust algorithm to properly toggle Regular Keyword Checking bool continueProcessing = true; // Used to toggle Regular Keyword Checking // Special Keywords are those that allow certain characters without whitespace after the command // Examples are: cd. cd\ md. rd. dir| dir> echo: echo. path= // Special Keyword Buffer used to determine if the first n characters is a Keyword char sKeywordBuffer[10]; // Special Keyword Buffer bool sKeywordFound; // Exit Special Keyword for-loop if found // Skip initial spaces while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { offset++; } // Colorize Default Text styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); // Set External Command / Program Location cmdLoc = offset; // Check for Fake Label (Comment) or Real Label - return if found if (lineBuffer[offset] == ':') { if (lineBuffer[offset + 1] == ':') { // Colorize Fake Label (Comment) - :: is similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm styler.ColourTo(endPos, SCE_BAT_COMMENT); } else { // Colorize Real Label styler.ColourTo(endPos, SCE_BAT_LABEL); } return; // Check for Drive Change (Drive Change is internal command) - return if found } else if ((IsAlphabetic(lineBuffer[offset])) && (lineBuffer[offset + 1] == ':') && ((isspacechar(lineBuffer[offset + 2])) || (((lineBuffer[offset + 2] == '\\')) && (isspacechar(lineBuffer[offset + 3]))))) { // Colorize Regular Keyword styler.ColourTo(endPos, SCE_BAT_WORD); return; } // Check for Hide Command (@ECHO OFF/ON) if (lineBuffer[offset] == '@') { styler.ColourTo(startLine + offset, SCE_BAT_HIDE); offset++; } // Skip next spaces while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { offset++; } // Read remainder of line word-at-a-time or remainder-of-word-at-a-time while (offset < lengthLine) { if (offset > startLine) { // Colorize Default Text styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); } // Copy word from Line Buffer into Word Buffer wbl = 0; for (; offset < lengthLine && wbl < 80 && !isspacechar(lineBuffer[offset]); wbl++, offset++) { wordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset])); } wordBuffer[wbl] = '\0'; wbo = 0; // Check for Comment - return if found if (CompareCaseInsensitive(wordBuffer, "rem") == 0) { styler.ColourTo(endPos, SCE_BAT_COMMENT); return; } // Check for Separator if (IsBSeparator(wordBuffer[0])) { // Check for External Command / Program if ((cmdLoc == offset - wbl) && ((wordBuffer[0] == ':') || (wordBuffer[0] == '\\') || (wordBuffer[0] == '.'))) { // Reset Offset to re-process remainder of word offset -= (wbl - 1); // Colorize External Command / Program if (!keywords2) { styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); } else if (keywords2.InList(wordBuffer)) { styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); } else { styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); } // Reset External Command / Program Location cmdLoc = offset; } else { // Reset Offset to re-process remainder of word offset -= (wbl - 1); // Colorize Default Text styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); } // Check for Regular Keyword in list } else if ((keywords.InList(wordBuffer)) && (continueProcessing)) { // ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) || (CompareCaseInsensitive(wordBuffer, "goto") == 0) || (CompareCaseInsensitive(wordBuffer, "prompt") == 0) || (CompareCaseInsensitive(wordBuffer, "set") == 0)) { continueProcessing = false; } // Identify External Command / Program Location for ERRORLEVEL, and EXIST if ((CompareCaseInsensitive(wordBuffer, "errorlevel") == 0) || (CompareCaseInsensitive(wordBuffer, "exist") == 0)) { // Reset External Command / Program Location cmdLoc = offset; // Skip next spaces while ((cmdLoc < lengthLine) && (isspacechar(lineBuffer[cmdLoc]))) { cmdLoc++; } // Skip comparison while ((cmdLoc < lengthLine) && (!isspacechar(lineBuffer[cmdLoc]))) { cmdLoc++; } // Skip next spaces while ((cmdLoc < lengthLine) && (isspacechar(lineBuffer[cmdLoc]))) { cmdLoc++; } // Identify External Command / Program Location for CALL, DO, LOADHIGH and LH } else if ((CompareCaseInsensitive(wordBuffer, "call") == 0) || (CompareCaseInsensitive(wordBuffer, "do") == 0) || (CompareCaseInsensitive(wordBuffer, "loadhigh") == 0) || (CompareCaseInsensitive(wordBuffer, "lh") == 0)) { // Reset External Command / Program Location cmdLoc = offset; // Skip next spaces while ((cmdLoc < lengthLine) && (isspacechar(lineBuffer[cmdLoc]))) { cmdLoc++; } } // Colorize Regular keyword styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD); // No need to Reset Offset // Check for Special Keyword in list, External Command / Program, or Default Text } else if ((wordBuffer[0] != '%') && (wordBuffer[0] != '!') && (!IsBOperator(wordBuffer[0])) && (continueProcessing)) { // Check for Special Keyword // Affected Commands are in Length range 2-6 // Good that ERRORLEVEL, EXIST, CALL, DO, LOADHIGH, and LH are unaffected sKeywordFound = false; for (unsigned int keywordLength = 2; keywordLength < wbl && keywordLength < 7 && !sKeywordFound; keywordLength++) { wbo = 0; // Copy Keyword Length from Word Buffer into Special Keyword Buffer for (; wbo < keywordLength; wbo++) { sKeywordBuffer[wbo] = static_cast<char>(wordBuffer[wbo]); } sKeywordBuffer[wbo] = '\0'; // Check for Special Keyword in list if ((keywords.InList(sKeywordBuffer)) && ((IsBOperator(wordBuffer[wbo])) || (IsBSeparator(wordBuffer[wbo])))) { sKeywordFound = true; // ECHO requires no further Regular Keyword Checking if (CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) { continueProcessing = false; } // Colorize Special Keyword as Regular Keyword styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD); // Reset Offset to re-process remainder of word offset -= (wbl - wbo); } } // Check for External Command / Program or Default Text if (!sKeywordFound) { wbo = 0; // Check for External Command / Program if (cmdLoc == offset - wbl) { // Read up to %, Operator or Separator while ((wbo < wbl) && (wordBuffer[wbo] != '%') && (wordBuffer[wbo] != '!') && (!IsBOperator(wordBuffer[wbo])) && (!IsBSeparator(wordBuffer[wbo]))) { wbo++; } // Reset External Command / Program Location cmdLoc = offset - (wbl - wbo); // Reset Offset to re-process remainder of word offset -= (wbl - wbo); // CHOICE requires no further Regular Keyword Checking if (CompareCaseInsensitive(wordBuffer, "choice") == 0) { continueProcessing = false; } // Check for START (and its switches) - What follows is External Command \ Program if (CompareCaseInsensitive(wordBuffer, "start") == 0) { // Reset External Command / Program Location cmdLoc = offset; // Skip next spaces while ((cmdLoc < lengthLine) && (isspacechar(lineBuffer[cmdLoc]))) { cmdLoc++; } // Reset External Command / Program Location if command switch detected if (lineBuffer[cmdLoc] == '/') { // Skip command switch while ((cmdLoc < lengthLine) && (!isspacechar(lineBuffer[cmdLoc]))) { cmdLoc++; } // Skip next spaces while ((cmdLoc < lengthLine) && (isspacechar(lineBuffer[cmdLoc]))) { cmdLoc++; } } } // Colorize External Command / Program if (!keywords2) { styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); } else if (keywords2.InList(wordBuffer)) { styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); } else { styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); } // No need to Reset Offset // Check for Default Text } else { // Read up to %, Operator or Separator while ((wbo < wbl) && (wordBuffer[wbo] != '%') && (wordBuffer[wbo] != '!') && (!IsBOperator(wordBuffer[wbo])) && (!IsBSeparator(wordBuffer[wbo]))) { wbo++; } // Colorize Default Text styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT); // Reset Offset to re-process remainder of word offset -= (wbl - wbo); } } // Check for Argument (%n), Environment Variable (%x...%) or Local Variable (%%a) } else if (wordBuffer[0] == '%') { // Colorize Default Text styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); wbo++; // Search to end of word for second % (can be a long path) while ((wbo < wbl) && (wordBuffer[wbo] != '%') && (!IsBOperator(wordBuffer[wbo])) && (!IsBSeparator(wordBuffer[wbo]))) { wbo++; } // Check for Argument (%n) or (%*) if (((Is0To9(wordBuffer[1])) || (wordBuffer[1] == '*')) && (wordBuffer[wbo] != '%')) { // Check for External Command / Program if (cmdLoc == offset - wbl) { cmdLoc = offset - (wbl - 2); } // Colorize Argument styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_IDENTIFIER); // Reset Offset to re-process remainder of word offset -= (wbl - 2); // Check for Expanded Argument (%~...) / Variable (%%~...) } else if (((wbl > 1) && (wordBuffer[1] == '~')) || ((wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] == '~'))) { // Check for External Command / Program if (cmdLoc == offset - wbl) { cmdLoc = offset - (wbl - wbo); } // Colorize Expanded Argument / Variable styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); // Reset Offset to re-process remainder of word offset -= (wbl - wbo); // Check for Environment Variable (%x...%) } else if ((wordBuffer[1] != '%') && (wordBuffer[wbo] == '%')) { wbo++; // Check for External Command / Program if (cmdLoc == offset - wbl) { cmdLoc = offset - (wbl - wbo); } // Colorize Environment Variable styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); // Reset Offset to re-process remainder of word offset -= (wbl - wbo); // Check for Local Variable (%%a) } else if ( (wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] != '%') && (!IsBOperator(wordBuffer[2])) && (!IsBSeparator(wordBuffer[2]))) { // Check for External Command / Program if (cmdLoc == offset - wbl) { cmdLoc = offset - (wbl - 3); } // Colorize Local Variable styler.ColourTo(startLine + offset - 1 - (wbl - 3), SCE_BAT_IDENTIFIER); // Reset Offset to re-process remainder of word offset -= (wbl - 3); } // Check for Environment Variable (!x...!) } else if (wordBuffer[0] == '!') { // Colorize Default Text styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); wbo++; // Search to end of word for second ! (can be a long path) while ((wbo < wbl) && (wordBuffer[wbo] != '!') && (!IsBOperator(wordBuffer[wbo])) && (!IsBSeparator(wordBuffer[wbo]))) { wbo++; } if (wordBuffer[wbo] == '!') { wbo++; // Check for External Command / Program if (cmdLoc == offset - wbl) { cmdLoc = offset - (wbl - wbo); } // Colorize Environment Variable styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); // Reset Offset to re-process remainder of word offset -= (wbl - wbo); } // Check for Operator } else if (IsBOperator(wordBuffer[0])) { // Colorize Default Text styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); // Check for Comparison Operator if ((wordBuffer[0] == '=') && (wordBuffer[1] == '=')) { // Identify External Command / Program Location for IF cmdLoc = offset; // Skip next spaces while ((cmdLoc < lengthLine) && (isspacechar(lineBuffer[cmdLoc]))) { cmdLoc++; } // Colorize Comparison Operator styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_OPERATOR); // Reset Offset to re-process remainder of word offset -= (wbl - 2); // Check for Pipe Operator } else if (wordBuffer[0] == '|') { // Reset External Command / Program Location cmdLoc = offset - wbl + 1; // Skip next spaces while ((cmdLoc < lengthLine) && (isspacechar(lineBuffer[cmdLoc]))) { cmdLoc++; } // Colorize Pipe Operator styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR); // Reset Offset to re-process remainder of word offset -= (wbl - 1); // Check for Other Operator } else { // Check for > Operator if (wordBuffer[0] == '>') { // Turn Keyword and External Command / Program checking back on continueProcessing = true; } // Colorize Other Operator styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR); // Reset Offset to re-process remainder of word offset -= (wbl - 1); } // Check for Default Text } else { // Read up to %, Operator or Separator while ((wbo < wbl) && (wordBuffer[wbo] != '%') && (wordBuffer[wbo] != '!') && (!IsBOperator(wordBuffer[wbo])) && (!IsBSeparator(wordBuffer[wbo]))) { wbo++; } // Colorize Default Text styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT); // Reset Offset to re-process remainder of word offset -= (wbl - wbo); } // Skip next spaces - nothing happens if Offset was Reset while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { offset++; } } // Colorize Default Text for remainder of line - currently not lexed styler.ColourTo(endPos, SCE_BAT_DEFAULT); } static void ColouriseBatchDoc( unsigned int startPos, int length, int /*initStyle*/, WordList *keywordlists[], Accessor &styler) { char lineBuffer[1024]; styler.StartAt(startPos); styler.StartSegment(startPos); unsigned int linePos = 0; unsigned int startLine = startPos; for (unsigned int i = startPos; i < startPos + length; i++) { lineBuffer[linePos++] = styler[i]; if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { // End of line (or of line buffer) met, colourise it lineBuffer[linePos] = '\0'; ColouriseBatchLine(lineBuffer, linePos, startLine, i, keywordlists, styler); linePos = 0; startLine = i + 1; } } if (linePos > 0) { // Last line does not have ending characters lineBuffer[linePos] = '\0'; ColouriseBatchLine(lineBuffer, linePos, startLine, startPos + length - 1, keywordlists, styler); } } #define DIFF_BUFFER_START_SIZE 16 // Note that ColouriseDiffLine analyzes only the first DIFF_BUFFER_START_SIZE // characters of each line to classify the line. static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) { // It is needed to remember the current state to recognize starting // comment lines before the first "diff " or "--- ". If a real // difference starts then each line starting with ' ' is a whitespace // otherwise it is considered a comment (Only in..., Binary file...) if (0 == strncmp(lineBuffer, "diff ", 5)) { styler.ColourTo(endLine, SCE_DIFF_COMMAND); } else if (0 == strncmp(lineBuffer, "Index: ", 7)) { // For subversion's diff styler.ColourTo(endLine, SCE_DIFF_COMMAND); } else if (0 == strncmp(lineBuffer, "---", 3) && lineBuffer[3] != '-') { // In a context diff, --- appears in both the header and the position markers if (lineBuffer[3] == ' ' && atoi(lineBuffer + 4) && !strchr(lineBuffer, '/')) styler.ColourTo(endLine, SCE_DIFF_POSITION); else if (lineBuffer[3] == '\r' || lineBuffer[3] == '\n') styler.ColourTo(endLine, SCE_DIFF_POSITION); else styler.ColourTo(endLine, SCE_DIFF_HEADER); } else if (0 == strncmp(lineBuffer, "+++ ", 4)) { // I don't know of any diff where "+++ " is a position marker, but for // consistency, do the same as with "--- " and "*** ". if (atoi(lineBuffer+4) && !strchr(lineBuffer, '/')) styler.ColourTo(endLine, SCE_DIFF_POSITION); else styler.ColourTo(endLine, SCE_DIFF_HEADER); } else if (0 == strncmp(lineBuffer, "====", 4)) { // For p4's diff styler.ColourTo(endLine, SCE_DIFF_HEADER); } else if (0 == strncmp(lineBuffer, "***", 3)) { // In a context diff, *** appears in both the header and the position markers. // Also ******** is a chunk header, but here it's treated as part of the // position marker since there is no separate style for a chunk header. if (lineBuffer[3] == ' ' && atoi(lineBuffer+4) && !strchr(lineBuffer, '/')) styler.ColourTo(endLine, SCE_DIFF_POSITION); else if (lineBuffer[3] == '*') styler.ColourTo(endLine, SCE_DIFF_POSITION); else styler.ColourTo(endLine, SCE_DIFF_HEADER); } else if (0 == strncmp(lineBuffer, "? ", 2)) { // For difflib styler.ColourTo(endLine, SCE_DIFF_HEADER); } else if (lineBuffer[0] == '@') { styler.ColourTo(endLine, SCE_DIFF_POSITION); } else if (lineBuffer[0] >= '0' && lineBuffer[0] <= '9') { styler.ColourTo(endLine, SCE_DIFF_POSITION); } else if (lineBuffer[0] == '-' || lineBuffer[0] == '<') { styler.ColourTo(endLine, SCE_DIFF_DELETED); } else if (lineBuffer[0] == '+' || lineBuffer[0] == '>') { styler.ColourTo(endLine, SCE_DIFF_ADDED); } else if (lineBuffer[0] == '!') { styler.ColourTo(endLine, SCE_DIFF_CHANGED); } else if (lineBuffer[0] != ' ') { styler.ColourTo(endLine, SCE_DIFF_COMMENT); } else { styler.ColourTo(endLine, SCE_DIFF_DEFAULT); } } static void ColouriseDiffDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { char lineBuffer[DIFF_BUFFER_START_SIZE] = ""; styler.StartAt(startPos); styler.StartSegment(startPos); unsigned int linePos = 0; for (unsigned int i = startPos; i < startPos + length; i++) { if (AtEOL(styler, i)) { if (linePos < DIFF_BUFFER_START_SIZE) { lineBuffer[linePos] = 0; } ColouriseDiffLine(lineBuffer, i, styler); linePos = 0; } else if (linePos < DIFF_BUFFER_START_SIZE - 1) { lineBuffer[linePos++] = styler[i]; } else if (linePos == DIFF_BUFFER_START_SIZE - 1) { lineBuffer[linePos++] = 0; } } if (linePos > 0) { // Last line does not have ending characters if (linePos < DIFF_BUFFER_START_SIZE) { lineBuffer[linePos] = 0; } ColouriseDiffLine(lineBuffer, startPos + length - 1, styler); } } static void FoldDiffDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { int curLine = styler.GetLine(startPos); int curLineStart = styler.LineStart(curLine); int prevLevel = curLine > 0 ? styler.LevelAt(curLine - 1) : SC_FOLDLEVELBASE; int nextLevel; do { int lineType = styler.StyleAt(curLineStart); if (lineType == SCE_DIFF_COMMAND) nextLevel = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG; else if (lineType == SCE_DIFF_HEADER) nextLevel = (SC_FOLDLEVELBASE + 1) | SC_FOLDLEVELHEADERFLAG; else if (lineType == SCE_DIFF_POSITION && styler[curLineStart] != '-') nextLevel = (SC_FOLDLEVELBASE + 2) | SC_FOLDLEVELHEADERFLAG; else if (prevLevel & SC_FOLDLEVELHEADERFLAG) nextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1; else nextLevel = prevLevel; if ((nextLevel & SC_FOLDLEVELHEADERFLAG) && (nextLevel == prevLevel)) styler.SetLevel(curLine-1, prevLevel & ~SC_FOLDLEVELHEADERFLAG); styler.SetLevel(curLine, nextLevel); prevLevel = nextLevel; curLineStart = styler.LineStart(++curLine); } while (static_cast<int>(startPos) + length > curLineStart); } static inline bool isassignchar(unsigned char ch) { return (ch == '=') || (ch == ':'); } static void ColourisePropsLine( char *lineBuffer, unsigned int lengthLine, unsigned int startLine, unsigned int endPos, Accessor &styler, bool allowInitialSpaces) { unsigned int i = 0; if (allowInitialSpaces) { while ((i < lengthLine) && isspacechar(lineBuffer[i])) // Skip initial spaces i++; } else { if (isspacechar(lineBuffer[i])) // don't allow initial spaces i = lengthLine; } if (i < lengthLine) { if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') { styler.ColourTo(endPos, SCE_PROPS_COMMENT); } else if (lineBuffer[i] == '[') { styler.ColourTo(endPos, SCE_PROPS_SECTION); } else if (lineBuffer[i] == '@') { styler.ColourTo(startLine + i, SCE_PROPS_DEFVAL); if (isassignchar(lineBuffer[i++])) styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT); styler.ColourTo(endPos, SCE_PROPS_DEFAULT); } else { // Search for the '=' character while ((i < lengthLine) && !isassignchar(lineBuffer[i])) i++; if ((i < lengthLine) && isassignchar(lineBuffer[i])) { styler.ColourTo(startLine + i - 1, SCE_PROPS_KEY); styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT); styler.ColourTo(endPos, SCE_PROPS_DEFAULT); } else { styler.ColourTo(endPos, SCE_PROPS_DEFAULT); } } } else { styler.ColourTo(endPos, SCE_PROPS_DEFAULT); } } static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { char lineBuffer[1024]; styler.StartAt(startPos); styler.StartSegment(startPos); unsigned int linePos = 0; unsigned int startLine = startPos; // property lexer.props.allow.initial.spaces // For properties files, set to 0 to style all lines that start with whitespace in the default style. // This is not suitable for SciTE .properties files which use indentation for flow control but // can be used for RFC2822 text where indentation is used for continuation lines. bool allowInitialSpaces = styler.GetPropertyInt("lexer.props.allow.initial.spaces", 1) != 0; for (unsigned int i = startPos; i < startPos + length; i++) { lineBuffer[linePos++] = styler[i]; if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { // End of line (or of line buffer) met, colourise it lineBuffer[linePos] = '\0'; ColourisePropsLine(lineBuffer, linePos, startLine, i, styler, allowInitialSpaces); linePos = 0; startLine = i + 1; } } if (linePos > 0) { // Last line does not have ending characters ColourisePropsLine(lineBuffer, linePos, startLine, startPos + length - 1, styler, allowInitialSpaces); } } // adaption by ksc, using the "} else {" trick of 1.53 // 030721 static void FoldPropsDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); bool headerPoint = false; int lev; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler[i+1]; int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (style == SCE_PROPS_SECTION) { headerPoint = true; } if (atEOL) { lev = SC_FOLDLEVELBASE; if (lineCurrent > 0) { int levelPrevious = styler.LevelAt(lineCurrent - 1); if (levelPrevious & SC_FOLDLEVELHEADERFLAG) { lev = SC_FOLDLEVELBASE + 1; } else { lev = levelPrevious & SC_FOLDLEVELNUMBERMASK; } } if (headerPoint) { lev = SC_FOLDLEVELBASE; } if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (headerPoint) { lev |= SC_FOLDLEVELHEADERFLAG; } if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; visibleChars = 0; headerPoint = false; } if (!isspacechar(ch)) visibleChars++; } if (lineCurrent > 0) { int levelPrevious = styler.LevelAt(lineCurrent - 1); if (levelPrevious & SC_FOLDLEVELHEADERFLAG) { lev = SC_FOLDLEVELBASE + 1; } else { lev = levelPrevious & SC_FOLDLEVELNUMBERMASK; } } else { lev = SC_FOLDLEVELBASE; } int flagsNext = styler.LevelAt(lineCurrent); styler.SetLevel(lineCurrent, lev | (flagsNext & ~SC_FOLDLEVELNUMBERMASK)); } static void ColouriseMakeLine( char *lineBuffer, unsigned int lengthLine, unsigned int startLine, unsigned int endPos, Accessor &styler) { unsigned int i = 0; int lastNonSpace = -1; unsigned int state = SCE_MAKE_DEFAULT; bool bSpecial = false; // check for a tab character in column 0 indicating a command bool bCommand = false; if ((lengthLine > 0) && (lineBuffer[0] == '\t')) bCommand = true; // Skip initial spaces while ((i < lengthLine) && isspacechar(lineBuffer[i])) { i++; } if (i < lengthLine) { if (lineBuffer[i] == '#') { // Comment styler.ColourTo(endPos, SCE_MAKE_COMMENT); return; } if (lineBuffer[i] == '!') { // Special directive styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR); return; } } int varCount = 0; while (i < lengthLine) { if (((i + 1) < lengthLine) && (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(')) { styler.ColourTo(startLine + i - 1, state); state = SCE_MAKE_IDENTIFIER; varCount++; } else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') { if (--varCount == 0) { styler.ColourTo(startLine + i, state); state = SCE_MAKE_DEFAULT; } } // skip identifier and target styling if this is a command line if (!bSpecial && !bCommand) { if (lineBuffer[i] == ':') { if (((i + 1) < lengthLine) && (lineBuffer[i + 1] == '=')) { // it's a ':=', so style as an identifier if (lastNonSpace >= 0) styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER); styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT); styler.ColourTo(startLine + i + 1, SCE_MAKE_OPERATOR); } else { // We should check that no colouring was made since the beginning of the line, // to avoid colouring stuff like /OUT:file if (lastNonSpace >= 0) styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET); styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT); styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR); } bSpecial = true; // Only react to the first ':' of the line state = SCE_MAKE_DEFAULT; } else if (lineBuffer[i] == '=') { if (lastNonSpace >= 0) styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER); styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT); styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR); bSpecial = true; // Only react to the first '=' of the line state = SCE_MAKE_DEFAULT; } } if (!isspacechar(lineBuffer[i])) { lastNonSpace = i; } i++; } if (state == SCE_MAKE_IDENTIFIER) { styler.ColourTo(endPos, SCE_MAKE_IDEOL); // Error, variable reference not ended } else { styler.ColourTo(endPos, SCE_MAKE_DEFAULT); } } static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { char lineBuffer[1024]; styler.StartAt(startPos); styler.StartSegment(startPos); unsigned int linePos = 0; unsigned int startLine = startPos; for (unsigned int i = startPos; i < startPos + length; i++) { lineBuffer[linePos++] = styler[i]; if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { // End of line (or of line buffer) met, colourise it lineBuffer[linePos] = '\0'; ColouriseMakeLine(lineBuffer, linePos, startLine, i, styler); linePos = 0; startLine = i + 1; } } if (linePos > 0) { // Last line does not have ending characters ColouriseMakeLine(lineBuffer, linePos, startLine, startPos + length - 1, styler); } } static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLine, int &startValue) { if (lineBuffer[0] == '>') { // Command or return status return SCE_ERR_CMD; } else if (lineBuffer[0] == '<') { // Diff removal. return SCE_ERR_DIFF_DELETION; } else if (lineBuffer[0] == '!') { return SCE_ERR_DIFF_CHANGED; } else if (lineBuffer[0] == '+') { if (strstart(lineBuffer, "+++ ")) { return SCE_ERR_DIFF_MESSAGE; } else { return SCE_ERR_DIFF_ADDITION; } } else if (lineBuffer[0] == '-') { if (strstart(lineBuffer, "--- ")) { return SCE_ERR_DIFF_MESSAGE; } else { return SCE_ERR_DIFF_DELETION; } } else if (strstart(lineBuffer, "cf90-")) { // Absoft Pro Fortran 90/95 v8.2 error and/or warning message return SCE_ERR_ABSF; } else if (strstart(lineBuffer, "fortcom:")) { // Intel Fortran Compiler v8.0 error/warning message return SCE_ERR_IFORT; } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) { return SCE_ERR_PYTHON; } else if (strstr(lineBuffer, " in ") && strstr(lineBuffer, " on line ")) { return SCE_ERR_PHP; } else if ((strstart(lineBuffer, "Error ") || strstart(lineBuffer, "Warning ")) && strstr(lineBuffer, " at (") && strstr(lineBuffer, ") : ") && (strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) { // Intel Fortran Compiler error/warning message return SCE_ERR_IFC; } else if (strstart(lineBuffer, "Error ")) { // Borland error message return SCE_ERR_BORLAND; } else if (strstart(lineBuffer, "Warning ")) { // Borland warning message return SCE_ERR_BORLAND; } else if (strstr(lineBuffer, "at line ") && (strstr(lineBuffer, "at line ") < (lineBuffer + lengthLine)) && strstr(lineBuffer, "file ") && (strstr(lineBuffer, "file ") < (lineBuffer + lengthLine))) { // Lua 4 error message return SCE_ERR_LUA; } else if (strstr(lineBuffer, " at ") && (strstr(lineBuffer, " at ") < (lineBuffer + lengthLine)) && strstr(lineBuffer, " line ") && (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) && (strstr(lineBuffer, " at ") < (strstr(lineBuffer, " line ")))) { // perl error message return SCE_ERR_PERL; } else if ((memcmp(lineBuffer, " at ", 6) == 0) && strstr(lineBuffer, ":line ")) { // A .NET traceback return SCE_ERR_NET; } else if (strstart(lineBuffer, "Line ") && strstr(lineBuffer, ", file ")) { // Essential Lahey Fortran error message return SCE_ERR_ELF; } else if (strstart(lineBuffer, "line ") && strstr(lineBuffer, " column ")) { // HTML tidy style: line 42 column 1 return SCE_ERR_TIDY; } else if (strstart(lineBuffer, "\tat ") && strstr(lineBuffer, "(") && strstr(lineBuffer, ".java:")) { // Java stack back trace return SCE_ERR_JAVA_STACK; } else if (strstart(lineBuffer, "In file included from ") || strstart(lineBuffer, " from ")) { // GCC showing include path to following error return SCE_ERR_GCC_INCLUDED_FROM; } else { // Look for one of the following formats: // GCC: <filename>:<line>:<message> // Microsoft: <filename>(<line>) :<message> // Common: <filename>(<line>): warning|error|note|remark|catastrophic|fatal // Common: <filename>(<line>) warning|error|note|remark|catastrophic|fatal // Microsoft: <filename>(<line>,<column>)<message> // CTags: \t<message> // Lua 5 traceback: \t<filename>:<line>:<message> // Lua 5.1: <exe>: <filename>:<line>:<message> bool initialTab = (lineBuffer[0] == '\t'); bool initialColonPart = false; enum { stInitial, stGccStart, stGccDigit, stGccColumn, stGcc, stMsStart, stMsDigit, stMsBracket, stMsVc, stMsDigitComma, stMsDotNet, stCtagsStart, stCtagsStartString, stCtagsStringDollar, stCtags, stUnrecognized } state = stInitial; for (unsigned int i = 0; i < lengthLine; i++) { char ch = lineBuffer[i]; char chNext = ' '; if ((i + 1) < lengthLine) chNext = lineBuffer[i + 1]; if (state == stInitial) { if (ch == ':') { // May be GCC, or might be Lua 5 (Lua traceback same but with tab prefix) if ((chNext != '\\') && (chNext != '/') && (chNext != ' ')) { // This check is not completely accurate as may be on // GTK+ with a file name that includes ':'. state = stGccStart; } else if (chNext == ' ') { // indicates a Lua 5.1 error message initialColonPart = true; } } else if ((ch == '(') && Is1To9(chNext) && (!initialTab)) { // May be Microsoft // Check against '0' often removes phone numbers state = stMsStart; } else if ((ch == '\t') && (!initialTab)) { // May be CTags state = stCtagsStart; } } else if (state == stGccStart) { // <filename>: state = Is1To9(ch) ? stGccDigit : stUnrecognized; } else if (state == stGccDigit) { // <filename>:<line> if (ch == ':') { state = stGccColumn; // :9.*: is GCC startValue = i + 1; } else if (!Is0To9(ch)) { state = stUnrecognized; } } else if (state == stGccColumn) { // <filename>:<line>:<column> if (!Is0To9(ch)) { state = stGcc; if (ch == ':') startValue = i + 1; break; } } else if (state == stMsStart) { // <filename>( state = Is0To9(ch) ? stMsDigit : stUnrecognized; } else if (state == stMsDigit) { // <filename>(<line> if (ch == ',') { state = stMsDigitComma; } else if (ch == ')') { state = stMsBracket; } else if ((ch != ' ') && !Is0To9(ch)) { state = stUnrecognized; } } else if (state == stMsBracket) { // <filename>(<line>) if ((ch == ' ') && (chNext == ':')) { state = stMsVc; } else if ((ch == ':' && chNext == ' ') || (ch == ' ')) { // Possibly Delphi.. don't test against chNext as it's one of the strings below. char word[512]; unsigned int j, chPos; unsigned numstep; chPos = 0; if (ch == ' ') numstep = 1; // ch was ' ', handle as if it's a delphi errorline, only add 1 to i. else numstep = 2; // otherwise add 2. for (j = i + numstep; j < lengthLine && IsAlphabetic(lineBuffer[j]) && chPos < sizeof(word) - 1; j++) word[chPos++] = lineBuffer[j]; word[chPos] = 0; if (!CompareCaseInsensitive(word, "error") || !CompareCaseInsensitive(word, "warning") || !CompareCaseInsensitive(word, "fatal") || !CompareCaseInsensitive(word, "catastrophic") || !CompareCaseInsensitive(word, "note") || !CompareCaseInsensitive(word, "remark")) { state = stMsVc; } else state = stUnrecognized; } else { state = stUnrecognized; } } else if (state == stMsDigitComma) { // <filename>(<line>, if (ch == ')') { state = stMsDotNet; break; } else if ((ch != ' ') && !Is0To9(ch)) { state = stUnrecognized; } } else if (state == stCtagsStart) { if ((lineBuffer[i - 1] == '\t') && ((ch == '/' && lineBuffer[i + 1] == '^') || Is0To9(ch))) { state = stCtags; break; } else if ((ch == '/') && (lineBuffer[i + 1] == '^')) { state = stCtagsStartString; } } else if ((state == stCtagsStartString) && ((lineBuffer[i] == '$') && (lineBuffer[i + 1] == '/'))) { state = stCtagsStringDollar; break; } } if (state == stGcc) { return initialColonPart ? SCE_ERR_LUA : SCE_ERR_GCC; } else if ((state == stMsVc) || (state == stMsDotNet)) { return SCE_ERR_MS; } else if ((state == stCtagsStringDollar) || (state == stCtags)) { return SCE_ERR_CTAG; } else { return SCE_ERR_DEFAULT; } } } static void ColouriseErrorListLine( char *lineBuffer, unsigned int lengthLine, unsigned int endPos, Accessor &styler, bool valueSeparate) { int startValue = -1; int style = RecogniseErrorListLine(lineBuffer, lengthLine, startValue); if (valueSeparate && (startValue >= 0)) { styler.ColourTo(endPos - (lengthLine - startValue), style); styler.ColourTo(endPos, SCE_ERR_VALUE); } else { styler.ColourTo(endPos, style); } } static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { char lineBuffer[10000]; styler.StartAt(startPos); styler.StartSegment(startPos); unsigned int linePos = 0; // property lexer.errorlist.value.separate // For lines in the output pane that are matches from Find in Files or GCC-style // diagnostics, style the path and line number separately from the rest of the // line with style 21 used for the rest of the line. // This allows matched text to be more easily distinguished from its location. bool valueSeparate = styler.GetPropertyInt("lexer.errorlist.value.separate", 0) != 0; for (unsigned int i = startPos; i < startPos + length; i++) { lineBuffer[linePos++] = styler[i]; if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { // End of line (or of line buffer) met, colourise it lineBuffer[linePos] = '\0'; ColouriseErrorListLine(lineBuffer, linePos, i, styler, valueSeparate); linePos = 0; } } if (linePos > 0) { // Last line does not have ending characters ColouriseErrorListLine(lineBuffer, linePos, startPos + length - 1, styler, valueSeparate); } } static const char *const batchWordListDesc[] = { "Internal Commands", "External Commands", 0 }; static const char *const emptyWordListDesc[] = { 0 }; static void ColouriseNullDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { // Null language means all style bytes are 0 so just mark the end - no need to fill in. if (length > 0) { styler.StartAt(startPos + length - 1); styler.StartSegment(startPos + length - 1); styler.ColourTo(startPos + length - 1, 0); } } LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", 0, batchWordListDesc); LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", FoldDiffDoc, emptyWordListDesc); LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props", FoldPropsDoc, emptyWordListDesc); LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", 0, emptyWordListDesc); LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc); LexerModule lmNull(SCLEX_NULL, ColouriseNullDoc, "null"); |
Added lexers/LexPB.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 |
// Scintilla source code edit control // @file LexPB.cxx // Lexer for PowerBasic by Roland Walter, roland@rowalt.de (for PowerBasic see www.powerbasic.com) // // Changes: // 17.10.2003: Toggling of subs/functions now until next sub/function - this gives better results // 29.10.2003: 1. Bug: Toggling didn't work for subs/functions added in editor // 2. Own colors for PB constants and Inline Assembler SCE_B_CONSTANT and SCE_B_ASM // 3. Several smaller syntax coloring improvements and speed optimizations // 12.07.2004: 1. Toggling for macros added // 2. Further folding speed optimitations (for people dealing with very large listings) // // Necessary changes for the PB lexer in Scintilla project: // - In SciLexer.h and Scintilla.iface: // // #define SCLEX_POWERBASIC 51 //ID for PowerBasic lexer // (...) // #define SCE_B_DEFAULT 0 //in both VB and PB lexer // #define SCE_B_COMMENT 1 //in both VB and PB lexer // #define SCE_B_NUMBER 2 //in both VB and PB lexer // #define SCE_B_KEYWORD 3 //in both VB and PB lexer // #define SCE_B_STRING 4 //in both VB and PB lexer // #define SCE_B_PREPROCESSOR 5 //VB lexer only, not in PB lexer // #define SCE_B_OPERATOR 6 //in both VB and PB lexer // #define SCE_B_IDENTIFIER 7 //in both VB and PB lexer // #define SCE_B_DATE 8 //VB lexer only, not in PB lexer // #define SCE_B_CONSTANT 13 //PB lexer only, not in VB lexer // #define SCE_B_ASM 14 //PB lexer only, not in VB lexer // - Statement added to KeyWords.cxx: 'LINK_LEXER(lmPB);' // - Statement added to scintilla_vc6.mak: '$(DIR_O)\LexPB.obj: ...\src\LexPB.cxx $(LEX_HEADERS)' // // Copyright for Scintilla: 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsTypeCharacter(const int ch) { return ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$' || ch == '?'; } static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_'); } static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_'); } bool MatchUpperCase(Accessor &styler, int pos, const char *s) //Same as styler.Match() but uppercase comparison (a-z,A-Z and space only) { char ch; for (int i=0; *s; i++) { ch=styler.SafeGetCharAt(pos+i); if (ch > 0x60) ch -= '\x20'; if (*s != ch) return false; s++; } return true; } static void ColourisePBDoc(unsigned int startPos, int length, int initStyle,WordList *keywordlists[],Accessor &styler) { WordList &keywords = *keywordlists[0]; styler.StartAt(startPos); StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { switch (sc.state) { case SCE_B_OPERATOR: { sc.SetState(SCE_B_DEFAULT); break; } case SCE_B_KEYWORD: { if (!IsAWordChar(sc.ch)) { if (!IsTypeCharacter(sc.ch)) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (keywords.InList(s)) { if (strcmp(s, "rem") == 0) { sc.ChangeState(SCE_B_COMMENT); if (sc.atLineEnd) {sc.SetState(SCE_B_DEFAULT);} } else if (strcmp(s, "asm") == 0) { sc.ChangeState(SCE_B_ASM); if (sc.atLineEnd) {sc.SetState(SCE_B_DEFAULT);} } else { sc.SetState(SCE_B_DEFAULT); } } else { sc.ChangeState(SCE_B_IDENTIFIER); sc.SetState(SCE_B_DEFAULT); } } } break; } case SCE_B_NUMBER: { if (!IsAWordChar(sc.ch)) {sc.SetState(SCE_B_DEFAULT);} break; } case SCE_B_STRING: { if (sc.ch == '\"'){sc.ForwardSetState(SCE_B_DEFAULT);} break; } case SCE_B_CONSTANT: { if (!IsAWordChar(sc.ch)) {sc.SetState(SCE_B_DEFAULT);} break; } case SCE_B_COMMENT: { if (sc.atLineEnd) {sc.SetState(SCE_B_DEFAULT);} break; } case SCE_B_ASM: { if (sc.atLineEnd) {sc.SetState(SCE_B_DEFAULT);} break; } } //switch (sc.state) // Determine if a new state should be entered: if (sc.state == SCE_B_DEFAULT) { if (sc.ch == '\'') {sc.SetState(SCE_B_COMMENT);} else if (sc.ch == '\"') {sc.SetState(SCE_B_STRING);} else if (sc.ch == '&' && tolower(sc.chNext) == 'h') {sc.SetState(SCE_B_NUMBER);} else if (sc.ch == '&' && tolower(sc.chNext) == 'b') {sc.SetState(SCE_B_NUMBER);} else if (sc.ch == '&' && tolower(sc.chNext) == 'o') {sc.SetState(SCE_B_NUMBER);} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {sc.SetState(SCE_B_NUMBER);} else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_B_KEYWORD);} else if (sc.ch == '%') {sc.SetState(SCE_B_CONSTANT);} else if (sc.ch == '$') {sc.SetState(SCE_B_CONSTANT);} else if (sc.ch == '#') {sc.SetState(SCE_B_KEYWORD);} else if (sc.ch == '!') {sc.SetState(SCE_B_ASM);} else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) {sc.SetState(SCE_B_OPERATOR);} } } //for (; sc.More(); sc.Forward()) sc.Complete(); } //The folding routine for PowerBasic toggles SUBs and FUNCTIONs only. This was exactly what I wanted, //nothing more. I had worked with this kind of toggling for several years when I used the great good old //GFA Basic which is dead now. After testing the feature of toggling FOR-NEXT loops, WHILE-WEND loops //and so on too I found this is more disturbing then helping (for me). So if You think in another way //you can (or must) write Your own toggling routine ;-) static void FoldPBDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { // No folding enabled, no reason to continue... if( styler.GetPropertyInt("fold") == 0 ) return; unsigned int endPos = startPos + length; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelNext = levelCurrent; char chNext = styler[startPos]; bool fNewLine=true; bool fMightBeMultiLineMacro=false; bool fBeginOfCommentFound=false; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if (fNewLine) //Begin of a new line (The Sub/Function/Macro keywords may occur at begin of line only) { fNewLine=false; fBeginOfCommentFound=false; switch (ch) { case ' ': //Most lines start with space - so check this first, the code is the same as for 'default:' case '\t': //Handle tab too { int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; styler.SetLevel(lineCurrent, lev); break; } case 'F': case 'f': { switch (chNext) { case 'U': case 'u': { if( MatchUpperCase(styler,i,"FUNCTION") ) { styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG); levelNext=SC_FOLDLEVELBASE+1; } break; } } break; } case 'S': case 's': { switch (chNext) { case 'U': case 'u': { if( MatchUpperCase(styler,i,"SUB") ) { styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG); levelNext=SC_FOLDLEVELBASE+1; } break; } case 'T': case 't': { if( MatchUpperCase(styler,i,"STATIC FUNCTION") ) { styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG); levelNext=SC_FOLDLEVELBASE+1; } else if( MatchUpperCase(styler,i,"STATIC SUB") ) { styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG); levelNext=SC_FOLDLEVELBASE+1; } break; } } break; } case 'C': case 'c': { switch (chNext) { case 'A': case 'a': { if( MatchUpperCase(styler,i,"CALLBACK FUNCTION") ) { styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG); levelNext=SC_FOLDLEVELBASE+1; } break; } } break; } case 'M': case 'm': { switch (chNext) { case 'A': case 'a': { if( MatchUpperCase(styler,i,"MACRO") ) { fMightBeMultiLineMacro=true; //Set folder level at end of line, we have to check for single line macro } break; } } break; } default: { int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; styler.SetLevel(lineCurrent, lev); break; } } //switch (ch) } //if( fNewLine ) switch (ch) { case '=': //To test single line macros { if (fBeginOfCommentFound==false) fMightBeMultiLineMacro=false; //The found macro is a single line macro only; break; } case '\'': //A comment starts { fBeginOfCommentFound=true; break; } case '\n': { if (fMightBeMultiLineMacro) //The current line is the begin of a multi line macro { fMightBeMultiLineMacro=false; styler.SetLevel(lineCurrent, (SC_FOLDLEVELBASE << 16) | SC_FOLDLEVELHEADERFLAG); levelNext=SC_FOLDLEVELBASE+1; } lineCurrent++; levelCurrent = levelNext; fNewLine=true; break; } case '\r': { if (chNext != '\n') { lineCurrent++; levelCurrent = levelNext; fNewLine=true; } break; } } //switch (ch) } //for (unsigned int i = startPos; i < endPos; i++) } static const char * const pbWordListDesc[] = { "Keywords", 0 }; LexerModule lmPB(SCLEX_POWERBASIC, ColourisePBDoc, "powerbasic", FoldPBDoc, pbWordListDesc); |
Added lexers/LexPLM.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
// Copyright (c) 1990-2007, Scientific Toolworks, Inc. // Author: Jason Haslam // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static void GetRange(unsigned int start, unsigned int end, Accessor &styler, char *s, unsigned int len) { unsigned int i = 0; while ((i < end - start + 1) && (i < len-1)) { s[i] = static_cast<char>(tolower(styler[start + i])); i++; } s[i] = '\0'; } static void ColourisePlmDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { unsigned int endPos = startPos + length; int state = initStyle; styler.StartAt(startPos); styler.StartSegment(startPos); for (unsigned int i = startPos; i < endPos; i++) { char ch = styler.SafeGetCharAt(i); char chNext = styler.SafeGetCharAt(i + 1); if (state == SCE_PLM_DEFAULT) { if (ch == '/' && chNext == '*') { styler.ColourTo(i - 1, state); state = SCE_PLM_COMMENT; } else if (ch == '\'') { styler.ColourTo(i - 1, state); state = SCE_PLM_STRING; } else if (isdigit(ch)) { styler.ColourTo(i - 1, state); state = SCE_PLM_NUMBER; } else if (isalpha(ch)) { styler.ColourTo(i - 1, state); state = SCE_PLM_IDENTIFIER; } else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '=' || ch == '<' || ch == '>' || ch == ':') { styler.ColourTo(i - 1, state); state = SCE_PLM_OPERATOR; } else if (ch == '$') { styler.ColourTo(i - 1, state); state = SCE_PLM_CONTROL; } } else if (state == SCE_PLM_COMMENT) { if (ch == '*' && chNext == '/') { i++; styler.ColourTo(i, state); state = SCE_PLM_DEFAULT; } } else if (state == SCE_PLM_STRING) { if (ch == '\'') { if (chNext == '\'') { i++; } else { styler.ColourTo(i, state); state = SCE_PLM_DEFAULT; } } } else if (state == SCE_PLM_NUMBER) { if (!isdigit(ch) && !isalpha(ch) && ch != '$') { i--; styler.ColourTo(i, state); state = SCE_PLM_DEFAULT; } } else if (state == SCE_PLM_IDENTIFIER) { if (!isdigit(ch) && !isalpha(ch) && ch != '$') { // Get the entire identifier. char word[1024]; int segmentStart = styler.GetStartSegment(); GetRange(segmentStart, i - 1, styler, word, sizeof(word)); i--; if (keywordlists[0]->InList(word)) styler.ColourTo(i, SCE_PLM_KEYWORD); else styler.ColourTo(i, state); state = SCE_PLM_DEFAULT; } } else if (state == SCE_PLM_OPERATOR) { if (ch != '=' && ch != '>') { i--; styler.ColourTo(i, state); state = SCE_PLM_DEFAULT; } } else if (state == SCE_PLM_CONTROL) { if (ch == '\r' || ch == '\n') { styler.ColourTo(i - 1, state); state = SCE_PLM_DEFAULT; } } } styler.ColourTo(endPos - 1, state); } static void FoldPlmDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; int startKeyword = 0; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (stylePrev != SCE_PLM_KEYWORD && style == SCE_PLM_KEYWORD) startKeyword = i; if (style == SCE_PLM_KEYWORD && styleNext != SCE_PLM_KEYWORD) { char word[1024]; GetRange(startKeyword, i, styler, word, sizeof(word)); if (strcmp(word, "procedure") == 0 || strcmp(word, "do") == 0) levelCurrent++; else if (strcmp(word, "end") == 0) levelCurrent--; } if (foldComment) { if (stylePrev != SCE_PLM_COMMENT && style == SCE_PLM_COMMENT) levelCurrent++; else if (stylePrev == SCE_PLM_COMMENT && style != SCE_PLM_COMMENT) levelCurrent--; } if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char *const plmWordListDesc[] = { "Keywords", 0 }; LexerModule lmPLM(SCLEX_PLM, ColourisePlmDoc, "PL/M", FoldPlmDoc, plmWordListDesc); |
Added lexers/LexPO.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
// Scintilla source code edit control /** @file LexPO.cxx ** Lexer for GetText Translation (PO) files. **/ // Copyright 2012 by Colomban Wendling <ban@herbesfolles.org> // The License.txt file describes the conditions under which this software may be distributed. // see https://www.gnu.org/software/gettext/manual/gettext.html#PO-Files for the syntax reference // some details are taken from the GNU msgfmt behavior (like that indent is allows in front of lines) // TODO: // * add keywords for flags (fuzzy, c-format, ...) // * highlight formats inside c-format strings (%s, %d, etc.) // * style for previous untranslated string? ("#|" comment) #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static void ColourisePODoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { StyleContext sc(startPos, length, initStyle, styler); bool escaped = false; int curLine = styler.GetLine(startPos); // the line state holds the last state on or before the line that isn't the default style int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : SCE_PO_DEFAULT; for (; sc.More(); sc.Forward()) { // whether we should leave a state switch (sc.state) { case SCE_PO_COMMENT: case SCE_PO_PROGRAMMER_COMMENT: case SCE_PO_REFERENCE: case SCE_PO_FLAGS: case SCE_PO_FUZZY: if (sc.atLineEnd) sc.SetState(SCE_PO_DEFAULT); else if (sc.state == SCE_PO_FLAGS && sc.Match("fuzzy")) // here we behave like the previous parser, but this should probably be highlighted // on its own like a keyword rather than changing the whole flags style sc.ChangeState(SCE_PO_FUZZY); break; case SCE_PO_MSGCTXT: case SCE_PO_MSGID: case SCE_PO_MSGSTR: if (isspacechar(sc.ch)) sc.SetState(SCE_PO_DEFAULT); break; case SCE_PO_ERROR: if (sc.atLineEnd) sc.SetState(SCE_PO_DEFAULT); break; case SCE_PO_MSGCTXT_TEXT: case SCE_PO_MSGID_TEXT: case SCE_PO_MSGSTR_TEXT: if (sc.atLineEnd) { // invalid inside a string if (sc.state == SCE_PO_MSGCTXT_TEXT) sc.ChangeState(SCE_PO_MSGCTXT_TEXT_EOL); else if (sc.state == SCE_PO_MSGID_TEXT) sc.ChangeState(SCE_PO_MSGID_TEXT_EOL); else if (sc.state == SCE_PO_MSGSTR_TEXT) sc.ChangeState(SCE_PO_MSGSTR_TEXT_EOL); sc.SetState(SCE_PO_DEFAULT); escaped = false; } else { if (escaped) escaped = false; else if (sc.ch == '\\') escaped = true; else if (sc.ch == '"') sc.ForwardSetState(SCE_PO_DEFAULT); } break; } // whether we should enter a new state if (sc.state == SCE_PO_DEFAULT) { // forward to the first non-white character on the line bool atLineStart = sc.atLineStart; if (atLineStart) { // reset line state if it is set to comment state so empty lines don't get // comment line state, and the folding code folds comments separately, // and anyway the styling don't use line state for comments if (curLineState == SCE_PO_COMMENT) curLineState = SCE_PO_DEFAULT; while (sc.More() && ! sc.atLineEnd && isspacechar(sc.ch)) sc.Forward(); } if (atLineStart && sc.ch == '#') { if (sc.chNext == '.') sc.SetState(SCE_PO_PROGRAMMER_COMMENT); else if (sc.chNext == ':') sc.SetState(SCE_PO_REFERENCE); else if (sc.chNext == ',') sc.SetState(SCE_PO_FLAGS); else sc.SetState(SCE_PO_COMMENT); } else if (atLineStart && sc.Match("msgid")) { // includes msgid_plural sc.SetState(SCE_PO_MSGID); } else if (atLineStart && sc.Match("msgstr")) { // includes [] suffixes sc.SetState(SCE_PO_MSGSTR); } else if (atLineStart && sc.Match("msgctxt")) { sc.SetState(SCE_PO_MSGCTXT); } else if (sc.ch == '"') { if (curLineState == SCE_PO_MSGCTXT || curLineState == SCE_PO_MSGCTXT_TEXT) sc.SetState(SCE_PO_MSGCTXT_TEXT); else if (curLineState == SCE_PO_MSGID || curLineState == SCE_PO_MSGID_TEXT) sc.SetState(SCE_PO_MSGID_TEXT); else if (curLineState == SCE_PO_MSGSTR || curLineState == SCE_PO_MSGSTR_TEXT) sc.SetState(SCE_PO_MSGSTR_TEXT); else sc.SetState(SCE_PO_ERROR); } else if (! isspacechar(sc.ch)) sc.SetState(SCE_PO_ERROR); if (sc.state != SCE_PO_DEFAULT) curLineState = sc.state; } if (sc.atLineEnd) { // Update the line state, so it can be seen by next line curLine = styler.GetLine(sc.currentPos); styler.SetLineState(curLine, curLineState); } } sc.Complete(); } static int FindNextNonEmptyLineState(unsigned int startPos, Accessor &styler) { unsigned int length = styler.Length(); for (unsigned int i = startPos; i < length; i++) { if (! isspacechar(styler[i])) { return styler.GetLineState(styler.GetLine(i)); } } return 0; } static void FoldPODoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { if (! styler.GetPropertyInt("fold")) return; bool foldCompact = styler.GetPropertyInt("fold.compact") != 0; bool foldComment = styler.GetPropertyInt("fold.comment") != 0; unsigned int endPos = startPos + length; int curLine = styler.GetLine(startPos); int lineState = styler.GetLineState(curLine); int nextLineState; int level = styler.LevelAt(curLine) & SC_FOLDLEVELNUMBERMASK; int nextLevel; int visible = 0; int chNext = styler[startPos]; for (unsigned int i = startPos; i < endPos; i++) { int ch = chNext; chNext = styler.SafeGetCharAt(i+1); if (! isspacechar(ch)) { visible++; } else if ((ch == '\r' && chNext != '\n') || ch == '\n' || i+1 >= endPos) { int lvl = level; int nextLine = curLine + 1; nextLineState = styler.GetLineState(nextLine); if ((lineState != SCE_PO_COMMENT || foldComment) && nextLineState == lineState && FindNextNonEmptyLineState(i, styler) == lineState) nextLevel = SC_FOLDLEVELBASE + 1; else nextLevel = SC_FOLDLEVELBASE; if (nextLevel > level) lvl |= SC_FOLDLEVELHEADERFLAG; if (visible == 0 && foldCompact) lvl |= SC_FOLDLEVELWHITEFLAG; styler.SetLevel(curLine, lvl); lineState = nextLineState; curLine = nextLine; level = nextLevel; visible = 0; } } } static const char *const poWordListDesc[] = { 0 }; LexerModule lmPO(SCLEX_PO, ColourisePODoc, "po", FoldPODoc, poWordListDesc); |
Added lexers/LexPOV.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 |
// Scintilla source code edit control /** @file LexPOV.cxx ** Lexer for POV-Ray SDL (Persistance of Vision Raytracer, Scene Description Language). ** Written by Philippe Lhoste but this is mostly a derivative of LexCPP... **/ // Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. // Some points that distinguish from a simple C lexer: // Identifiers start only by a character. // No line continuation character. // Strings are limited to 256 characters. // Directives are similar to preprocessor commands, // but we match directive keywords and colorize incorrect ones. // Block comments can be nested (code stolen from my code in LexLua). #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(int ch) { return ch < 0x80 && (isalnum(ch) || ch == '_'); } static inline bool IsAWordStart(int ch) { return ch < 0x80 && isalpha(ch); } static inline bool IsANumberChar(int ch) { // Not exactly following number definition (several dots are seen as OK, etc.) // but probably enough in most cases. return (ch < 0x80) && (isdigit(ch) || toupper(ch) == 'E' || ch == '.' || ch == '-' || ch == '+'); } static void ColourisePovDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords1 = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; WordList &keywords5 = *keywordlists[4]; WordList &keywords6 = *keywordlists[5]; WordList &keywords7 = *keywordlists[6]; WordList &keywords8 = *keywordlists[7]; int currentLine = styler.GetLine(startPos); // Initialize the block comment /* */ nesting level, if we are inside such a comment. int blockCommentLevel = 0; if (initStyle == SCE_POV_COMMENT) { blockCommentLevel = styler.GetLineState(currentLine - 1); } // Do not leak onto next line if (initStyle == SCE_POV_STRINGEOL || initStyle == SCE_POV_COMMENTLINE) { initStyle = SCE_POV_DEFAULT; } short stringLen = 0; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.atLineEnd) { // Update the line state, so it can be seen by next line currentLine = styler.GetLine(sc.currentPos); if (sc.state == SCE_POV_COMMENT) { // Inside a block comment, we set the line state styler.SetLineState(currentLine, blockCommentLevel); } else { // Reset the line state styler.SetLineState(currentLine, 0); } } if (sc.atLineStart && (sc.state == SCE_POV_STRING)) { // Prevent SCE_POV_STRINGEOL from leaking back to previous line sc.SetState(SCE_POV_STRING); } // Determine if the current state should terminate. if (sc.state == SCE_POV_OPERATOR) { sc.SetState(SCE_POV_DEFAULT); } else if (sc.state == SCE_POV_NUMBER) { // We stop the number definition on non-numerical non-dot non-eE non-sign char if (!IsANumberChar(sc.ch)) { sc.SetState(SCE_POV_DEFAULT); } } else if (sc.state == SCE_POV_IDENTIFIER) { if (!IsAWordChar(sc.ch)) { char s[100]; sc.GetCurrent(s, sizeof(s)); if (keywords2.InList(s)) { sc.ChangeState(SCE_POV_WORD2); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_POV_WORD3); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_POV_WORD4); } else if (keywords5.InList(s)) { sc.ChangeState(SCE_POV_WORD5); } else if (keywords6.InList(s)) { sc.ChangeState(SCE_POV_WORD6); } else if (keywords7.InList(s)) { sc.ChangeState(SCE_POV_WORD7); } else if (keywords8.InList(s)) { sc.ChangeState(SCE_POV_WORD8); } sc.SetState(SCE_POV_DEFAULT); } } else if (sc.state == SCE_POV_DIRECTIVE) { if (!IsAWordChar(sc.ch)) { char s[100]; char *p; sc.GetCurrent(s, sizeof(s)); p = s; // Skip # and whitespace between # and directive word do { p++; } while ((*p == ' ' || *p == '\t') && *p != '\0'); if (!keywords1.InList(p)) { sc.ChangeState(SCE_POV_BADDIRECTIVE); } sc.SetState(SCE_POV_DEFAULT); } } else if (sc.state == SCE_POV_COMMENT) { if (sc.Match('/', '*')) { blockCommentLevel++; sc.Forward(); } else if (sc.Match('*', '/') && blockCommentLevel > 0) { blockCommentLevel--; sc.Forward(); if (blockCommentLevel == 0) { sc.ForwardSetState(SCE_POV_DEFAULT); } } } else if (sc.state == SCE_POV_COMMENTLINE) { if (sc.atLineEnd) { sc.ForwardSetState(SCE_POV_DEFAULT); } } else if (sc.state == SCE_POV_STRING) { if (sc.ch == '\\') { stringLen++; if (strchr("abfnrtuv0'\"", sc.chNext)) { // Compound characters are counted as one. // Note: for Unicode chars \u, we shouldn't count the next 4 digits... sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_POV_DEFAULT); } else if (sc.atLineEnd) { sc.ChangeState(SCE_POV_STRINGEOL); sc.ForwardSetState(SCE_POV_DEFAULT); } else { stringLen++; } if (stringLen > 256) { // Strings are limited to 256 chars sc.SetState(SCE_POV_STRINGEOL); } } else if (sc.state == SCE_POV_STRINGEOL) { if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_C_DEFAULT); } else if (sc.atLineEnd) { sc.ForwardSetState(SCE_POV_DEFAULT); } } // Determine if a new state should be entered. if (sc.state == SCE_POV_DEFAULT) { if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_POV_NUMBER); } else if (IsAWordStart(sc.ch)) { sc.SetState(SCE_POV_IDENTIFIER); } else if (sc.Match('/', '*')) { blockCommentLevel = 1; sc.SetState(SCE_POV_COMMENT); sc.Forward(); // Eat the * so it isn't used for the end of the comment } else if (sc.Match('/', '/')) { sc.SetState(SCE_POV_COMMENTLINE); } else if (sc.ch == '\"') { sc.SetState(SCE_POV_STRING); stringLen = 0; } else if (sc.ch == '#') { sc.SetState(SCE_POV_DIRECTIVE); // Skip whitespace between # and directive word do { sc.Forward(); } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More()); if (sc.atLineEnd) { sc.SetState(SCE_POV_DEFAULT); } } else if (isoperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_POV_OPERATOR); } } } sc.Complete(); } static void FoldPovDoc( unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldDirective = styler.GetPropertyInt("fold.directive") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment && (style == SCE_POV_COMMENT)) { if (stylePrev != SCE_POV_COMMENT) { levelCurrent++; } else if ((styleNext != SCE_POV_COMMENT) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelCurrent--; } } if (foldComment && (style == SCE_POV_COMMENTLINE)) { if ((ch == '/') && (chNext == '/')) { char chNext2 = styler.SafeGetCharAt(i + 2); if (chNext2 == '{') { levelCurrent++; } else if (chNext2 == '}') { levelCurrent--; } } } if (foldDirective && (style == SCE_POV_DIRECTIVE)) { if (ch == '#') { unsigned int j=i+1; while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { j++; } } } if (style == SCE_POV_OPERATOR) { if (ch == '{') { levelCurrent++; } else if (ch == '}') { levelCurrent--; } } if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char * const povWordLists[] = { "Language directives", "Objects & CSG & Appearance", "Types & Modifiers & Items", "Predefined Identifiers", "Predefined Functions", "User defined 1", "User defined 2", "User defined 3", 0, }; LexerModule lmPOV(SCLEX_POV, ColourisePovDoc, "pov", FoldPovDoc, povWordLists); |
Added lexers/LexPS.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 |
// Scintilla source code edit control /** @file LexPS.cxx ** Lexer for PostScript ** ** Written by Nigel Hathaway <nigel@bprj.co.uk>. ** The License.txt file describes the conditions under which this software may be distributed. **/ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsASelfDelimitingChar(const int ch) { return (ch == '[' || ch == ']' || ch == '{' || ch == '}' || ch == '/' || ch == '<' || ch == '>' || ch == '(' || ch == ')' || ch == '%'); } static inline bool IsAWhitespaceChar(const int ch) { return (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == '\f' || ch == '\0'); } static bool IsABaseNDigit(const int ch, const int base) { int maxdig = '9'; int letterext = -1; if (base <= 10) maxdig = '0' + base - 1; else letterext = base - 11; return ((ch >= '0' && ch <= maxdig) || (ch >= 'A' && ch <= ('A' + letterext)) || (ch >= 'a' && ch <= ('a' + letterext))); } static inline bool IsABase85Char(const int ch) { return ((ch >= '!' && ch <= 'u') || ch == 'z'); } static void ColourisePSDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords1 = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; WordList &keywords5 = *keywordlists[4]; StyleContext sc(startPos, length, initStyle, styler); bool tokenizing = styler.GetPropertyInt("ps.tokenize") != 0; int pslevel = styler.GetPropertyInt("ps.level", 3); int lineCurrent = styler.GetLine(startPos); int nestTextCurrent = 0; if (lineCurrent > 0 && initStyle == SCE_PS_TEXT) nestTextCurrent = styler.GetLineState(lineCurrent - 1); int numRadix = 0; bool numHasPoint = false; bool numHasExponent = false; bool numHasSign = false; // Clear out existing tokenization if (tokenizing && length > 0) { styler.StartAt(startPos, static_cast<char>(INDIC2_MASK)); styler.ColourTo(startPos + length-1, 0); styler.Flush(); styler.StartAt(startPos); styler.StartSegment(startPos); } for (; sc.More(); sc.Forward()) { if (sc.atLineStart) lineCurrent = styler.GetLine(sc.currentPos); // Determine if the current state should terminate. if (sc.state == SCE_PS_COMMENT || sc.state == SCE_PS_DSC_VALUE) { if (sc.atLineEnd) { sc.SetState(SCE_C_DEFAULT); } } else if (sc.state == SCE_PS_DSC_COMMENT) { if (sc.ch == ':') { sc.Forward(); if (!sc.atLineEnd) sc.SetState(SCE_PS_DSC_VALUE); else sc.SetState(SCE_C_DEFAULT); } else if (sc.atLineEnd) { sc.SetState(SCE_C_DEFAULT); } else if (IsAWhitespaceChar(sc.ch) && sc.ch != '\r') { sc.ChangeState(SCE_PS_COMMENT); } } else if (sc.state == SCE_PS_NUMBER) { if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch)) { if ((sc.chPrev == '+' || sc.chPrev == '-' || sc.chPrev == 'E' || sc.chPrev == 'e') && numRadix == 0) sc.ChangeState(SCE_PS_NAME); sc.SetState(SCE_C_DEFAULT); } else if (sc.ch == '#') { if (numHasPoint || numHasExponent || numHasSign || numRadix != 0) { sc.ChangeState(SCE_PS_NAME); } else { char szradix[5]; sc.GetCurrent(szradix, 4); numRadix = atoi(szradix); if (numRadix < 2 || numRadix > 36) sc.ChangeState(SCE_PS_NAME); } } else if ((sc.ch == 'E' || sc.ch == 'e') && numRadix == 0) { if (numHasExponent) { sc.ChangeState(SCE_PS_NAME); } else { numHasExponent = true; if (sc.chNext == '+' || sc.chNext == '-') sc.Forward(); } } else if (sc.ch == '.') { if (numHasPoint || numHasExponent || numRadix != 0) { sc.ChangeState(SCE_PS_NAME); } else { numHasPoint = true; } } else if (numRadix == 0) { if (!IsABaseNDigit(sc.ch, 10)) sc.ChangeState(SCE_PS_NAME); } else { if (!IsABaseNDigit(sc.ch, numRadix)) sc.ChangeState(SCE_PS_NAME); } } else if (sc.state == SCE_PS_NAME || sc.state == SCE_PS_KEYWORD) { if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch)) { char s[100]; sc.GetCurrent(s, sizeof(s)); if ((pslevel >= 1 && keywords1.InList(s)) || (pslevel >= 2 && keywords2.InList(s)) || (pslevel >= 3 && keywords3.InList(s)) || keywords4.InList(s) || keywords5.InList(s)) { sc.ChangeState(SCE_PS_KEYWORD); } sc.SetState(SCE_C_DEFAULT); } } else if (sc.state == SCE_PS_LITERAL || sc.state == SCE_PS_IMMEVAL) { if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch)) sc.SetState(SCE_C_DEFAULT); } else if (sc.state == SCE_PS_PAREN_ARRAY || sc.state == SCE_PS_PAREN_DICT || sc.state == SCE_PS_PAREN_PROC) { sc.SetState(SCE_C_DEFAULT); } else if (sc.state == SCE_PS_TEXT) { if (sc.ch == '(') { nestTextCurrent++; } else if (sc.ch == ')') { if (--nestTextCurrent == 0) sc.ForwardSetState(SCE_PS_DEFAULT); } else if (sc.ch == '\\') { sc.Forward(); } } else if (sc.state == SCE_PS_HEXSTRING) { if (sc.ch == '>') { sc.ForwardSetState(SCE_PS_DEFAULT); } else if (!IsABaseNDigit(sc.ch, 16) && !IsAWhitespaceChar(sc.ch)) { sc.SetState(SCE_PS_HEXSTRING); styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR); } } else if (sc.state == SCE_PS_BASE85STRING) { if (sc.Match('~', '>')) { sc.Forward(); sc.ForwardSetState(SCE_PS_DEFAULT); } else if (!IsABase85Char(sc.ch) && !IsAWhitespaceChar(sc.ch)) { sc.SetState(SCE_PS_BASE85STRING); styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR); } } // Determine if a new state should be entered. if (sc.state == SCE_C_DEFAULT) { unsigned int tokenpos = sc.currentPos; if (sc.ch == '[' || sc.ch == ']') { sc.SetState(SCE_PS_PAREN_ARRAY); } else if (sc.ch == '{' || sc.ch == '}') { sc.SetState(SCE_PS_PAREN_PROC); } else if (sc.ch == '/') { if (sc.chNext == '/') { sc.SetState(SCE_PS_IMMEVAL); sc.Forward(); } else { sc.SetState(SCE_PS_LITERAL); } } else if (sc.ch == '<') { if (sc.chNext == '<') { sc.SetState(SCE_PS_PAREN_DICT); sc.Forward(); } else if (sc.chNext == '~') { sc.SetState(SCE_PS_BASE85STRING); sc.Forward(); } else { sc.SetState(SCE_PS_HEXSTRING); } } else if (sc.ch == '>' && sc.chNext == '>') { sc.SetState(SCE_PS_PAREN_DICT); sc.Forward(); } else if (sc.ch == '>' || sc.ch == ')') { sc.SetState(SCE_C_DEFAULT); styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR); } else if (sc.ch == '(') { sc.SetState(SCE_PS_TEXT); nestTextCurrent = 1; } else if (sc.ch == '%') { if (sc.chNext == '%' && sc.atLineStart) { sc.SetState(SCE_PS_DSC_COMMENT); sc.Forward(); if (sc.chNext == '+') { sc.Forward(); sc.ForwardSetState(SCE_PS_DSC_VALUE); } } else { sc.SetState(SCE_PS_COMMENT); } } else if ((sc.ch == '+' || sc.ch == '-' || sc.ch == '.') && IsABaseNDigit(sc.chNext, 10)) { sc.SetState(SCE_PS_NUMBER); numRadix = 0; numHasPoint = (sc.ch == '.'); numHasExponent = false; numHasSign = (sc.ch == '+' || sc.ch == '-'); } else if ((sc.ch == '+' || sc.ch == '-') && sc.chNext == '.' && IsABaseNDigit(sc.GetRelative(2), 10)) { sc.SetState(SCE_PS_NUMBER); numRadix = 0; numHasPoint = false; numHasExponent = false; numHasSign = true; } else if (IsABaseNDigit(sc.ch, 10)) { sc.SetState(SCE_PS_NUMBER); numRadix = 0; numHasPoint = false; numHasExponent = false; numHasSign = false; } else if (!IsAWhitespaceChar(sc.ch)) { sc.SetState(SCE_PS_NAME); } // Mark the start of tokens if (tokenizing && sc.state != SCE_C_DEFAULT && sc.state != SCE_PS_COMMENT && sc.state != SCE_PS_DSC_COMMENT && sc.state != SCE_PS_DSC_VALUE) { styler.Flush(); styler.StartAt(tokenpos, static_cast<char>(INDIC2_MASK)); styler.ColourTo(tokenpos, INDIC2_MASK); styler.Flush(); styler.StartAt(tokenpos); styler.StartSegment(tokenpos); } } if (sc.atLineEnd) styler.SetLineState(lineCurrent, nestTextCurrent); } sc.Complete(); } static void FoldPSDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelMinCurrent = levelCurrent; int levelNext = levelCurrent; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); //mac?? if ((style & 31) == SCE_PS_PAREN_PROC) { if (ch == '{') { // Measure the minimum before a '{' to allow // folding on "} {" if (levelMinCurrent > levelNext) { levelMinCurrent = levelNext; } levelNext++; } else if (ch == '}') { levelNext--; } } if (atEOL) { int levelUse = levelCurrent; if (foldAtElse) { levelUse = levelMinCurrent; } int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelCurrent = levelNext; levelMinCurrent = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } } static const char * const psWordListDesc[] = { "PS Level 1 operators", "PS Level 2 operators", "PS Level 3 operators", "RIP-specific operators", "User-defined operators", 0 }; LexerModule lmPS(SCLEX_PS, ColourisePSDoc, "ps", FoldPSDoc, psWordListDesc); |
Added lexers/LexPascal.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 |
// Scintilla source code edit control /** @file LexPascal.cxx ** Lexer for Pascal. ** Written by Laurent le Tynevez ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002 ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments) ** Completely rewritten by Marko Njezic <sf@maxempire.com> October 2008 **/ /* A few words about features of the new completely rewritten LexPascal... Generally speaking LexPascal tries to support all available Delphi features (up to Delphi 2009 at this time), including .NET specific features. ~ HIGHLIGHTING: If you enable "lexer.pascal.smart.highlighting" property, some keywords will only be highlighted in appropriate context. As implemented those are keywords related to property and DLL exports declarations (similar to how Delphi IDE works). For example, keywords "read" and "write" will only be highlighted if they are in property declaration: property MyProperty: boolean read FMyProperty write FMyProperty; ~ FOLDING: Folding is supported in the following cases: - Folding of stream-like comments - Folding of groups of consecutive line comments - Folding of preprocessor blocks (the following preprocessor blocks are supported: IF / IFEND; IFDEF, IFNDEF, IFOPT / ENDIF and REGION / ENDREGION blocks), including nesting of preprocessor blocks up to 255 levels - Folding of code blocks on appropriate keywords (the following code blocks are supported: "begin, asm, record, try, case / end" blocks, class & object declarations and interface declarations) Remarks: - Folding of code blocks tries to handle all special cases in which folding should not occur. As implemented those are: 1. Structure "record case / end" (there's only one "end" statement and "case" is ignored as fold point) 2. Forward class declarations ("type TMyClass = class;") and object method declarations ("TNotifyEvent = procedure(Sender: TObject) of object;") are ignored as fold points 3. Simplified complete class declarations ("type TMyClass = class(TObject);") are ignored as fold points 4. Every other situation when class keyword doesn't actually start class declaration ("class procedure", "class function", "class of", "class var", "class property" and "class operator") 5. Forward (disp)interface declarations ("type IMyInterface = interface;") are ignored as fold points - Folding of code blocks inside preprocessor blocks is disabled (any comments inside them will be folded fine) because there is no guarantee that complete code block will be contained inside folded preprocessor block in which case folded code block could end prematurely at the end of preprocessor block if there is no closing statement inside. This was done in order to properly process document that may contain something like this: type {$IFDEF UNICODE} TMyClass = class(UnicodeAncestor) {$ELSE} TMyClass = class(AnsiAncestor) {$ENDIF} private ... public ... published ... end; If class declarations were folded, then the second class declaration would end at "$ENDIF" statement, first class statement would end at "end;" statement and preprocessor "$IFDEF" block would go all the way to the end of document. However, having in mind all this, if you want to enable folding of code blocks inside preprocessor blocks, you can disable folding of preprocessor blocks by changing "fold.preprocessor" property, in which case everything inside them would be folded. ~ KEYWORDS: The list of keywords that can be used in pascal.properties file (up to Delphi 2009): - Keywords: absolute abstract and array as asm assembler automated begin case cdecl class const constructor deprecated destructor dispid dispinterface div do downto dynamic else end except export exports external far file final finalization finally for forward function goto if implementation in inherited initialization inline interface is label library message mod near nil not object of on or out overload override packed pascal platform private procedure program property protected public published raise record register reintroduce repeat resourcestring safecall sealed set shl shr static stdcall strict string then threadvar to try type unit unsafe until uses var varargs virtual while with xor - Keywords related to the "smart highlithing" feature: add default implements index name nodefault read readonly remove stored write writeonly - Keywords related to Delphi packages (in addition to all above): package contains requires */ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static void GetRangeLowered(unsigned int start, unsigned int end, Accessor &styler, char *s, unsigned int len) { unsigned int i = 0; while ((i < end - start + 1) && (i < len-1)) { s[i] = static_cast<char>(tolower(styler[start + i])); i++; } s[i] = '\0'; } static void GetForwardRangeLowered(unsigned int start, CharacterSet &charSet, Accessor &styler, char *s, unsigned int len) { unsigned int i = 0; while ((i < len-1) && charSet.Contains(styler.SafeGetCharAt(start + i))) { s[i] = static_cast<char>(tolower(styler.SafeGetCharAt(start + i))); i++; } s[i] = '\0'; } enum { stateInAsm = 0x1000, stateInProperty = 0x2000, stateInExport = 0x4000, stateFoldInPreprocessor = 0x0100, stateFoldInRecord = 0x0200, stateFoldInPreprocessorLevelMask = 0x00FF, stateFoldMaskAll = 0x0FFF }; static void ClassifyPascalWord(WordList *keywordlists[], StyleContext &sc, int &curLineState, bool bSmartHighlighting) { WordList& keywords = *keywordlists[0]; char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (keywords.InList(s)) { if (curLineState & stateInAsm) { if (strcmp(s, "end") == 0 && sc.GetRelative(-4) != '@') { curLineState &= ~stateInAsm; sc.ChangeState(SCE_PAS_WORD); } else { sc.ChangeState(SCE_PAS_ASM); } } else { bool ignoreKeyword = false; if (strcmp(s, "asm") == 0) { curLineState |= stateInAsm; } else if (bSmartHighlighting) { if (strcmp(s, "property") == 0) { curLineState |= stateInProperty; } else if (strcmp(s, "exports") == 0) { curLineState |= stateInExport; } else if (!(curLineState & (stateInProperty | stateInExport)) && strcmp(s, "index") == 0) { ignoreKeyword = true; } else if (!(curLineState & stateInExport) && strcmp(s, "name") == 0) { ignoreKeyword = true; } else if (!(curLineState & stateInProperty) && (strcmp(s, "read") == 0 || strcmp(s, "write") == 0 || strcmp(s, "default") == 0 || strcmp(s, "nodefault") == 0 || strcmp(s, "stored") == 0 || strcmp(s, "implements") == 0 || strcmp(s, "readonly") == 0 || strcmp(s, "writeonly") == 0 || strcmp(s, "add") == 0 || strcmp(s, "remove") == 0)) { ignoreKeyword = true; } } if (!ignoreKeyword) { sc.ChangeState(SCE_PAS_WORD); } } } else if (curLineState & stateInAsm) { sc.ChangeState(SCE_PAS_ASM); } sc.SetState(SCE_PAS_DEFAULT); } static void ColourisePascalDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { bool bSmartHighlighting = styler.GetPropertyInt("lexer.pascal.smart.highlighting", 1) != 0; CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true); CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true); CharacterSet setNumber(CharacterSet::setDigits, ".-+eE"); CharacterSet setHexNumber(CharacterSet::setDigits, "abcdefABCDEF"); CharacterSet setOperator(CharacterSet::setNone, "#$&'()*+,-./:;<=>@[]^{}"); int curLine = styler.GetLine(startPos); int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.atLineEnd) { // Update the line state, so it can be seen by next line curLine = styler.GetLine(sc.currentPos); styler.SetLineState(curLine, curLineState); } // Determine if the current state should terminate. switch (sc.state) { case SCE_PAS_NUMBER: if (!setNumber.Contains(sc.ch) || (sc.ch == '.' && sc.chNext == '.')) { sc.SetState(SCE_PAS_DEFAULT); } else if (sc.ch == '-' || sc.ch == '+') { if (sc.chPrev != 'E' && sc.chPrev != 'e') { sc.SetState(SCE_PAS_DEFAULT); } } break; case SCE_PAS_IDENTIFIER: if (!setWord.Contains(sc.ch)) { ClassifyPascalWord(keywordlists, sc, curLineState, bSmartHighlighting); } break; case SCE_PAS_HEXNUMBER: if (!setHexNumber.Contains(sc.ch)) { sc.SetState(SCE_PAS_DEFAULT); } break; case SCE_PAS_COMMENT: case SCE_PAS_PREPROCESSOR: if (sc.ch == '}') { sc.ForwardSetState(SCE_PAS_DEFAULT); } break; case SCE_PAS_COMMENT2: case SCE_PAS_PREPROCESSOR2: if (sc.Match('*', ')')) { sc.Forward(); sc.ForwardSetState(SCE_PAS_DEFAULT); } break; case SCE_PAS_COMMENTLINE: if (sc.atLineStart) { sc.SetState(SCE_PAS_DEFAULT); } break; case SCE_PAS_STRING: if (sc.atLineEnd) { sc.ChangeState(SCE_PAS_STRINGEOL); } else if (sc.ch == '\'' && sc.chNext == '\'') { sc.Forward(); } else if (sc.ch == '\'') { sc.ForwardSetState(SCE_PAS_DEFAULT); } break; case SCE_PAS_STRINGEOL: if (sc.atLineStart) { sc.SetState(SCE_PAS_DEFAULT); } break; case SCE_PAS_CHARACTER: if (!setHexNumber.Contains(sc.ch) && sc.ch != '$') { sc.SetState(SCE_PAS_DEFAULT); } break; case SCE_PAS_OPERATOR: if (bSmartHighlighting && sc.chPrev == ';') { curLineState &= ~(stateInProperty | stateInExport); } sc.SetState(SCE_PAS_DEFAULT); break; case SCE_PAS_ASM: sc.SetState(SCE_PAS_DEFAULT); break; } // Determine if a new state should be entered. if (sc.state == SCE_PAS_DEFAULT) { if (IsADigit(sc.ch) && !(curLineState & stateInAsm)) { sc.SetState(SCE_PAS_NUMBER); } else if (setWordStart.Contains(sc.ch)) { sc.SetState(SCE_PAS_IDENTIFIER); } else if (sc.ch == '$' && !(curLineState & stateInAsm)) { sc.SetState(SCE_PAS_HEXNUMBER); } else if (sc.Match('{', '$')) { sc.SetState(SCE_PAS_PREPROCESSOR); } else if (sc.ch == '{') { sc.SetState(SCE_PAS_COMMENT); } else if (sc.Match("(*$")) { sc.SetState(SCE_PAS_PREPROCESSOR2); } else if (sc.Match('(', '*')) { sc.SetState(SCE_PAS_COMMENT2); sc.Forward(); // Eat the * so it isn't used for the end of the comment } else if (sc.Match('/', '/')) { sc.SetState(SCE_PAS_COMMENTLINE); } else if (sc.ch == '\'') { sc.SetState(SCE_PAS_STRING); } else if (sc.ch == '#') { sc.SetState(SCE_PAS_CHARACTER); } else if (setOperator.Contains(sc.ch) && !(curLineState & stateInAsm)) { sc.SetState(SCE_PAS_OPERATOR); } else if (curLineState & stateInAsm) { sc.SetState(SCE_PAS_ASM); } } } if (sc.state == SCE_PAS_IDENTIFIER && setWord.Contains(sc.chPrev)) { ClassifyPascalWord(keywordlists, sc, curLineState, bSmartHighlighting); } sc.Complete(); } static bool IsStreamCommentStyle(int style) { return style == SCE_PAS_COMMENT || style == SCE_PAS_COMMENT2; } static bool IsCommentLine(int line, Accessor &styler) { int pos = styler.LineStart(line); int eolPos = styler.LineStart(line + 1) - 1; for (int i = pos; i < eolPos; i++) { char ch = styler[i]; char chNext = styler.SafeGetCharAt(i + 1); int style = styler.StyleAt(i); if (ch == '/' && chNext == '/' && style == SCE_PAS_COMMENTLINE) { return true; } else if (!IsASpaceOrTab(ch)) { return false; } } return false; } static unsigned int GetFoldInPreprocessorLevelFlag(int lineFoldStateCurrent) { return lineFoldStateCurrent & stateFoldInPreprocessorLevelMask; } static void SetFoldInPreprocessorLevelFlag(int &lineFoldStateCurrent, unsigned int nestLevel) { lineFoldStateCurrent &= ~stateFoldInPreprocessorLevelMask; lineFoldStateCurrent |= nestLevel & stateFoldInPreprocessorLevelMask; } static void ClassifyPascalPreprocessorFoldPoint(int &levelCurrent, int &lineFoldStateCurrent, unsigned int startPos, Accessor &styler) { CharacterSet setWord(CharacterSet::setAlpha); char s[11]; // Size of the longest possible keyword + one additional character + null GetForwardRangeLowered(startPos, setWord, styler, s, sizeof(s)); unsigned int nestLevel = GetFoldInPreprocessorLevelFlag(lineFoldStateCurrent); if (strcmp(s, "if") == 0 || strcmp(s, "ifdef") == 0 || strcmp(s, "ifndef") == 0 || strcmp(s, "ifopt") == 0 || strcmp(s, "region") == 0) { nestLevel++; SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel); lineFoldStateCurrent |= stateFoldInPreprocessor; levelCurrent++; } else if (strcmp(s, "endif") == 0 || strcmp(s, "ifend") == 0 || strcmp(s, "endregion") == 0) { nestLevel--; SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel); if (nestLevel == 0) { lineFoldStateCurrent &= ~stateFoldInPreprocessor; } levelCurrent--; if (levelCurrent < SC_FOLDLEVELBASE) { levelCurrent = SC_FOLDLEVELBASE; } } } static unsigned int SkipWhiteSpace(unsigned int currentPos, unsigned int endPos, Accessor &styler, bool includeChars = false) { CharacterSet setWord(CharacterSet::setAlphaNum, "_"); unsigned int j = currentPos + 1; char ch = styler.SafeGetCharAt(j); while ((j < endPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' || IsStreamCommentStyle(styler.StyleAt(j)) || (includeChars && setWord.Contains(ch)))) { j++; ch = styler.SafeGetCharAt(j); } return j; } static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCurrent, int startPos, unsigned int endPos, unsigned int lastStart, unsigned int currentPos, Accessor &styler) { char s[100]; GetRangeLowered(lastStart, currentPos, styler, s, sizeof(s)); if (strcmp(s, "record") == 0) { lineFoldStateCurrent |= stateFoldInRecord; levelCurrent++; } else if (strcmp(s, "begin") == 0 || strcmp(s, "asm") == 0 || strcmp(s, "try") == 0 || (strcmp(s, "case") == 0 && !(lineFoldStateCurrent & stateFoldInRecord))) { levelCurrent++; } else if (strcmp(s, "class") == 0 || strcmp(s, "object") == 0) { // "class" & "object" keywords require special handling... bool ignoreKeyword = false; unsigned int j = SkipWhiteSpace(currentPos, endPos, styler); if (j < endPos) { CharacterSet setWordStart(CharacterSet::setAlpha, "_"); CharacterSet setWord(CharacterSet::setAlphaNum, "_"); if (styler.SafeGetCharAt(j) == ';') { // Handle forward class declarations ("type TMyClass = class;") // and object method declarations ("TNotifyEvent = procedure(Sender: TObject) of object;") ignoreKeyword = true; } else if (strcmp(s, "class") == 0) { // "class" keyword has a few more special cases... if (styler.SafeGetCharAt(j) == '(') { // Handle simplified complete class declarations ("type TMyClass = class(TObject);") j = SkipWhiteSpace(j, endPos, styler, true); if (j < endPos && styler.SafeGetCharAt(j) == ')') { j = SkipWhiteSpace(j, endPos, styler); if (j < endPos && styler.SafeGetCharAt(j) == ';') { ignoreKeyword = true; } } } else if (setWordStart.Contains(styler.SafeGetCharAt(j))) { char s2[11]; // Size of the longest possible keyword + one additional character + null GetForwardRangeLowered(j, setWord, styler, s2, sizeof(s2)); if (strcmp(s2, "procedure") == 0 || strcmp(s2, "function") == 0 || strcmp(s2, "of") == 0 || strcmp(s2, "var") == 0 || strcmp(s2, "property") == 0 || strcmp(s2, "operator") == 0) { ignoreKeyword = true; } } } } if (!ignoreKeyword) { levelCurrent++; } } else if (strcmp(s, "interface") == 0) { // "interface" keyword requires special handling... bool ignoreKeyword = true; int j = lastStart - 1; char ch = styler.SafeGetCharAt(j); while ((j >= startPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' || IsStreamCommentStyle(styler.StyleAt(j)))) { j--; ch = styler.SafeGetCharAt(j); } if (j >= startPos && styler.SafeGetCharAt(j) == '=') { ignoreKeyword = false; } if (!ignoreKeyword) { unsigned int k = SkipWhiteSpace(currentPos, endPos, styler); if (k < endPos && styler.SafeGetCharAt(k) == ';') { // Handle forward interface declarations ("type IMyInterface = interface;") ignoreKeyword = true; } } if (!ignoreKeyword) { levelCurrent++; } } else if (strcmp(s, "dispinterface") == 0) { // "dispinterface" keyword requires special handling... bool ignoreKeyword = false; unsigned int j = SkipWhiteSpace(currentPos, endPos, styler); if (j < endPos && styler.SafeGetCharAt(j) == ';') { // Handle forward dispinterface declarations ("type IMyInterface = dispinterface;") ignoreKeyword = true; } if (!ignoreKeyword) { levelCurrent++; } } else if (strcmp(s, "end") == 0) { lineFoldStateCurrent &= ~stateFoldInRecord; levelCurrent--; if (levelCurrent < SC_FOLDLEVELBASE) { levelCurrent = SC_FOLDLEVELBASE; } } } static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; int lineFoldStateCurrent = lineCurrent > 0 ? styler.GetLineState(lineCurrent - 1) & stateFoldMaskAll : 0; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; int lastStart = 0; CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true); for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment && IsStreamCommentStyle(style)) { if (!IsStreamCommentStyle(stylePrev)) { levelCurrent++; } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelCurrent--; } } if (foldComment && atEOL && IsCommentLine(lineCurrent, styler)) { if (!IsCommentLine(lineCurrent - 1, styler) && IsCommentLine(lineCurrent + 1, styler)) levelCurrent++; else if (IsCommentLine(lineCurrent - 1, styler) && !IsCommentLine(lineCurrent+1, styler)) levelCurrent--; } if (foldPreprocessor) { if (style == SCE_PAS_PREPROCESSOR && ch == '{' && chNext == '$') { ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 2, styler); } else if (style == SCE_PAS_PREPROCESSOR2 && ch == '(' && chNext == '*' && styler.SafeGetCharAt(i + 2) == '$') { ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 3, styler); } } if (stylePrev != SCE_PAS_WORD && style == SCE_PAS_WORD) { // Store last word start point. lastStart = i; } if (stylePrev == SCE_PAS_WORD && !(lineFoldStateCurrent & stateFoldInPreprocessor)) { if(setWord.Contains(ch) && !setWord.Contains(chNext)) { ClassifyPascalWordFoldPoint(levelCurrent, lineFoldStateCurrent, startPos, endPos, lastStart, i, styler); } } if (!IsASpace(ch)) visibleChars++; if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } int newLineState = (styler.GetLineState(lineCurrent) & ~stateFoldMaskAll) | lineFoldStateCurrent; styler.SetLineState(lineCurrent, newLineState); lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } } // If we didn't reach the EOL in previous loop, store line level and whitespace information. // The rest will be filled in later... int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; styler.SetLevel(lineCurrent, lev); } static const char * const pascalWordListDesc[] = { "Keywords", 0 }; LexerModule lmPascal(SCLEX_PASCAL, ColourisePascalDoc, "pascal", FoldPascalDoc, pascalWordListDesc); |
Added lexers/LexPerl.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 |
// Scintilla source code edit control /** @file LexPerl.cxx ** Lexer for Perl. ** Converted to lexer object by "Udo Lechner" <dlchnr(at)gmx(dot)net> **/ // Copyright 1998-2008 by Neil Hodgson <neilh@scintilla.org> // Lexical analysis fixes by Kein-Hong Man <mkh@pl.jaring.my> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include <string> #include <map> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #include "OptionSet.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // Info for HERE document handling from perldata.pod (reformatted): // ---------------------------------------------------------------- // A line-oriented form of quoting is based on the shell ``here-doc'' syntax. // Following a << you specify a string to terminate the quoted material, and // all lines following the current line down to the terminating string are // the value of the item. // * The terminating string may be either an identifier (a word), or some // quoted text. // * If quoted, the type of quotes you use determines the treatment of the // text, just as in regular quoting. // * An unquoted identifier works like double quotes. // * There must be no space between the << and the identifier. // (If you put a space it will be treated as a null identifier, // which is valid, and matches the first empty line.) // (This is deprecated, -w warns of this syntax) // * The terminating string must appear by itself (unquoted and // with no surrounding whitespace) on the terminating line. #define HERE_DELIM_MAX 256 // maximum length of HERE doc delimiter #define PERLNUM_BINARY 1 // order is significant: 1-4 cannot have a dot #define PERLNUM_HEX 2 #define PERLNUM_OCTAL 3 #define PERLNUM_FLOAT_EXP 4 // exponent part only #define PERLNUM_DECIMAL 5 // 1-5 are numbers; 6-7 are strings #define PERLNUM_VECTOR 6 #define PERLNUM_V_VECTOR 7 #define PERLNUM_BAD 8 #define BACK_NONE 0 // lookback state for bareword disambiguation: #define BACK_OPERATOR 1 // whitespace/comments are insignificant #define BACK_KEYWORD 2 // operators/keywords are needed for disambiguation // all interpolated styles are different from their parent styles by a constant difference // we also assume SCE_PL_STRING_VAR is the interpolated style with the smallest value #define INTERPOLATE_SHIFT (SCE_PL_STRING_VAR - SCE_PL_STRING) static bool isPerlKeyword(unsigned int start, unsigned int end, WordList &keywords, LexAccessor &styler) { // old-style keyword matcher; needed because GetCurrent() needs // current segment to be committed, but we may abandon early... char s[100]; unsigned int i, len = end - start; if (len > 30) { len = 30; } for (i = 0; i < len; i++, start++) s[i] = styler[start]; s[i] = '\0'; return keywords.InList(s); } static int disambiguateBareword(LexAccessor &styler, unsigned int bk, unsigned int fw, int backFlag, unsigned int backPos, unsigned int endPos) { // identifiers are recognized by Perl as barewords under some // conditions, the following attempts to do the disambiguation // by looking backward and forward; result in 2 LSB int result = 0; bool moreback = false; // true if passed newline/comments bool brace = false; // true if opening brace found // if BACK_NONE, neither operator nor keyword, so skip test if (backFlag == BACK_NONE) return result; // first look backwards past whitespace/comments to set EOL flag // (some disambiguation patterns must be on a single line) if (backPos <= static_cast<unsigned int>(styler.LineStart(styler.GetLine(bk)))) moreback = true; // look backwards at last significant lexed item for disambiguation bk = backPos - 1; int ch = static_cast<unsigned char>(styler.SafeGetCharAt(bk)); if (ch == '{' && !moreback) { // {bareword: possible variable spec brace = true; } else if ((ch == '&' && styler.SafeGetCharAt(bk - 1) != '&') // &bareword: subroutine call || styler.Match(bk - 1, "->") // ->bareword: part of variable spec || styler.Match(bk - 2, "sub")) { // sub bareword: subroutine declaration // (implied BACK_KEYWORD, no keywords end in 'sub'!) result |= 1; } // next, scan forward after word past tab/spaces only; // if ch isn't one of '[{(,' we can skip the test if ((ch == '{' || ch == '(' || ch == '['|| ch == ',') && fw < endPos) { while (ch = static_cast<unsigned char>(styler.SafeGetCharAt(fw)), IsASpaceOrTab(ch) && fw < endPos) { fw++; } if ((ch == '}' && brace) // {bareword}: variable spec || styler.Match(fw, "=>")) { // [{(, bareword=>: hash literal result |= 2; } } return result; } static void skipWhitespaceComment(LexAccessor &styler, unsigned int &p) { // when backtracking, we need to skip whitespace and comments int style; while ((p > 0) && (style = styler.StyleAt(p), style == SCE_PL_DEFAULT || style == SCE_PL_COMMENTLINE)) p--; } static int styleBeforeBracePair(LexAccessor &styler, unsigned int bk) { // backtrack to find open '{' corresponding to a '}', balanced // return significant style to be tested for '/' disambiguation int braceCount = 1; if (bk == 0) return SCE_PL_DEFAULT; while (--bk > 0) { if (styler.StyleAt(bk) == SCE_PL_OPERATOR) { int bkch = static_cast<unsigned char>(styler.SafeGetCharAt(bk)); if (bkch == ';') { // early out break; } else if (bkch == '}') { braceCount++; } else if (bkch == '{') { if (--braceCount == 0) break; } } } if (bk > 0 && braceCount == 0) { // balanced { found, bk > 0, skip more whitespace/comments bk--; skipWhitespaceComment(styler, bk); return styler.StyleAt(bk); } return SCE_PL_DEFAULT; } static int styleCheckIdentifier(LexAccessor &styler, unsigned int bk) { // backtrack to classify sub-styles of identifier under test // return sub-style to be tested for '/' disambiguation if (styler.SafeGetCharAt(bk) == '>') // inputsymbol, like <foo> return 1; // backtrack to check for possible "->" or "::" before identifier while (bk > 0 && styler.StyleAt(bk) == SCE_PL_IDENTIFIER) { bk--; } while (bk > 0) { int bkstyle = styler.StyleAt(bk); if (bkstyle == SCE_PL_DEFAULT || bkstyle == SCE_PL_COMMENTLINE) { // skip whitespace, comments } else if (bkstyle == SCE_PL_OPERATOR) { // test for "->" and "::" if (styler.Match(bk - 1, "->") || styler.Match(bk - 1, "::")) return 2; } else return 3; // bare identifier bk--; } return 0; } static int inputsymbolScan(LexAccessor &styler, unsigned int pos, unsigned int endPos) { // looks forward for matching > on same line; a bit ugly unsigned int fw = pos; while (++fw < endPos) { int fwch = static_cast<unsigned char>(styler.SafeGetCharAt(fw)); if (fwch == '\r' || fwch == '\n') { return 0; } else if (fwch == '>') { if (styler.Match(fw - 2, "<=>")) // '<=>' case return 0; return fw - pos; } } return 0; } static int podLineScan(LexAccessor &styler, unsigned int &pos, unsigned int endPos) { // forward scan the current line to classify line for POD style int state = -1; while (pos <= endPos) { int ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos)); if (ch == '\n' || ch == '\r' || pos >= endPos) { if (ch == '\r' && styler.SafeGetCharAt(pos + 1) == '\n') pos++; break; } if (IsASpaceOrTab(ch)) { // whitespace, take note if (state == -1) state = SCE_PL_DEFAULT; } else if (state == SCE_PL_DEFAULT) { // verbatim POD line state = SCE_PL_POD_VERB; } else if (state != SCE_PL_POD_VERB) { // regular POD line state = SCE_PL_POD; } pos++; } if (state == -1) state = SCE_PL_DEFAULT; return state; } static bool styleCheckSubPrototype(LexAccessor &styler, unsigned int bk) { // backtrack to identify if we're starting a subroutine prototype // we also need to ignore whitespace/comments: // 'sub' [whitespace|comment] <identifier> [whitespace|comment] styler.Flush(); skipWhitespaceComment(styler, bk); if (bk == 0 || styler.StyleAt(bk) != SCE_PL_IDENTIFIER) // check identifier return false; while (bk > 0 && (styler.StyleAt(bk) == SCE_PL_IDENTIFIER)) { bk--; } skipWhitespaceComment(styler, bk); if (bk < 2 || styler.StyleAt(bk) != SCE_PL_WORD // check "sub" keyword || !styler.Match(bk - 2, "sub")) // assume suffix is unique! return false; return true; } static int actualNumStyle(int numberStyle) { if (numberStyle == PERLNUM_VECTOR || numberStyle == PERLNUM_V_VECTOR) { return SCE_PL_STRING; } else if (numberStyle == PERLNUM_BAD) { return SCE_PL_ERROR; } return SCE_PL_NUMBER; } static int opposite(int ch) { if (ch == '(') return ')'; if (ch == '[') return ']'; if (ch == '{') return '}'; if (ch == '<') return '>'; return ch; } static bool IsCommentLine(int line, LexAccessor &styler) { int pos = styler.LineStart(line); int eol_pos = styler.LineStart(line + 1) - 1; for (int i = pos; i < eol_pos; i++) { char ch = styler[i]; int style = styler.StyleAt(i); if (ch == '#' && style == SCE_PL_COMMENTLINE) return true; else if (!IsASpaceOrTab(ch)) return false; } return false; } static bool IsPackageLine(int line, LexAccessor &styler) { int pos = styler.LineStart(line); int style = styler.StyleAt(pos); if (style == SCE_PL_WORD && styler.Match(pos, "package")) { return true; } return false; } static int PodHeadingLevel(int pos, LexAccessor &styler) { int lvl = static_cast<unsigned char>(styler.SafeGetCharAt(pos + 5)); if (lvl >= '1' && lvl <= '4') { return lvl - '0'; } return 0; } // An individual named option for use in an OptionSet // Options used for LexerPerl struct OptionsPerl { bool fold; bool foldComment; bool foldCompact; // Custom folding of POD and packages bool foldPOD; // fold.perl.pod // Enable folding Pod blocks when using the Perl lexer. bool foldPackage; // fold.perl.package // Enable folding packages when using the Perl lexer. bool foldCommentExplicit; bool foldAtElse; OptionsPerl() { fold = false; foldComment = false; foldCompact = true; foldPOD = true; foldPackage = true; foldCommentExplicit = true; foldAtElse = false; } }; static const char *const perlWordListDesc[] = { "Keywords", 0 }; struct OptionSetPerl : public OptionSet<OptionsPerl> { OptionSetPerl() { DefineProperty("fold", &OptionsPerl::fold); DefineProperty("fold.comment", &OptionsPerl::foldComment); DefineProperty("fold.compact", &OptionsPerl::foldCompact); DefineProperty("fold.perl.pod", &OptionsPerl::foldPOD, "Set to 0 to disable folding Pod blocks when using the Perl lexer."); DefineProperty("fold.perl.package", &OptionsPerl::foldPackage, "Set to 0 to disable folding packages when using the Perl lexer."); DefineProperty("fold.perl.comment.explicit", &OptionsPerl::foldCommentExplicit, "Set to 0 to disable explicit folding."); DefineProperty("fold.perl.at.else", &OptionsPerl::foldAtElse, "This option enables Perl folding on a \"} else {\" line of an if statement."); DefineWordListSets(perlWordListDesc); } }; class LexerPerl : public ILexer { CharacterSet setWordStart; CharacterSet setWord; CharacterSet setSpecialVar; CharacterSet setControlVar; WordList keywords; OptionsPerl options; OptionSetPerl osPerl; public: LexerPerl() : setWordStart(CharacterSet::setAlpha, "_", 0x80, true), setWord(CharacterSet::setAlphaNum, "_", 0x80, true), setSpecialVar(CharacterSet::setNone, "\"$;<>&`'+,./\\%:=~!?@[]"), setControlVar(CharacterSet::setNone, "ACDEFHILMNOPRSTVWX") { } virtual ~LexerPerl() { } void SCI_METHOD Release() { delete this; } int SCI_METHOD Version() const { return lvOriginal; } const char *SCI_METHOD PropertyNames() { return osPerl.PropertyNames(); } int SCI_METHOD PropertyType(const char *name) { return osPerl.PropertyType(name); } const char *SCI_METHOD DescribeProperty(const char *name) { return osPerl.DescribeProperty(name); } int SCI_METHOD PropertySet(const char *key, const char *val); const char *SCI_METHOD DescribeWordListSets() { return osPerl.DescribeWordListSets(); } int SCI_METHOD WordListSet(int n, const char *wl); void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess); void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess); void *SCI_METHOD PrivateCall(int, void *) { return 0; } static ILexer *LexerFactoryPerl() { return new LexerPerl(); } void InterpolateSegment(StyleContext &sc, int maxSeg, bool isPattern=false); }; int SCI_METHOD LexerPerl::PropertySet(const char *key, const char *val) { if (osPerl.PropertySet(&options, key, val)) { return 0; } return -1; } int SCI_METHOD LexerPerl::WordListSet(int n, const char *wl) { WordList *wordListN = 0; switch (n) { case 0: wordListN = &keywords; break; } int firstModification = -1; if (wordListN) { WordList wlNew; wlNew.Set(wl); if (*wordListN != wlNew) { wordListN->Set(wl); firstModification = 0; } } return firstModification; } void LexerPerl::InterpolateSegment(StyleContext &sc, int maxSeg, bool isPattern) { // interpolate a segment (with no active backslashes or delimiters within) // switch in or out of an interpolation style or continue current style // commit variable patterns if found, trim segment, repeat until done while (maxSeg > 0) { bool isVar = false; int sLen = 0; if ((maxSeg > 1) && (sc.ch == '$' || sc.ch == '@')) { // $#[$]*word [$@][$]*word (where word or {word} is always present) bool braces = false; sLen = 1; if (sc.ch == '$' && sc.chNext == '#') { // starts with $# sLen++; } while ((maxSeg > sLen) && (sc.GetRelative(sLen) == '$')) // >0 $ dereference within sLen++; if ((maxSeg > sLen) && (sc.GetRelative(sLen) == '{')) { // { start for {word} sLen++; braces = true; } if (maxSeg > sLen) { int c = sc.GetRelative(sLen); if (setWordStart.Contains(c)) { // word (various) sLen++; isVar = true; while ((maxSeg > sLen) && setWord.Contains(sc.GetRelative(sLen))) sLen++; } else if (braces && IsADigit(c) && (sLen == 2)) { // digit for ${digit} sLen++; isVar = true; } } if (braces) { if ((maxSeg > sLen) && (sc.GetRelative(sLen) == '}')) { // } end for {word} sLen++; } else isVar = false; } } if (!isVar && (maxSeg > 1)) { // $- or @-specific variable patterns sLen = 1; int c = sc.chNext; if (sc.ch == '$') { if (IsADigit(c)) { // $[0-9] and slurp trailing digits sLen++; isVar = true; while ((maxSeg > sLen) && IsADigit(sc.GetRelative(sLen))) sLen++; } else if (setSpecialVar.Contains(c)) { // $ special variables sLen++; isVar = true; } else if (!isPattern && ((c == '(') || (c == ')') || (c == '|'))) { // $ additional sLen++; isVar = true; } else if (c == '^') { // $^A control-char style sLen++; if ((maxSeg > sLen) && setControlVar.Contains(sc.GetRelative(sLen))) { sLen++; isVar = true; } } } else if (sc.ch == '@') { if (!isPattern && ((c == '+') || (c == '-'))) { // @ specials non-pattern sLen++; isVar = true; } } } if (isVar) { // commit as interpolated variable or normal character if (sc.state < SCE_PL_STRING_VAR) sc.SetState(sc.state + INTERPOLATE_SHIFT); sc.Forward(sLen); maxSeg -= sLen; } else { if (sc.state >= SCE_PL_STRING_VAR) sc.SetState(sc.state - INTERPOLATE_SHIFT); sc.Forward(); maxSeg--; } } if (sc.state >= SCE_PL_STRING_VAR) sc.SetState(sc.state - INTERPOLATE_SHIFT); } void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { LexAccessor styler(pAccess); // keywords that forces /PATTERN/ at all times; should track vim's behaviour WordList reWords; reWords.Set("elsif if split while"); // charset classes CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMAC"); // lexing of "%*</" operators is non-trivial; these are missing in the set below CharacterSet setPerlOperator(CharacterSet::setNone, "^&\\()-+=|{}[]:;>,?!.~"); CharacterSet setQDelim(CharacterSet::setNone, "qrwx"); CharacterSet setModifiers(CharacterSet::setAlpha); CharacterSet setPreferRE(CharacterSet::setNone, "*/<%"); // setArray and setHash also accepts chars for special vars like $_, // which are then truncated when the next char does not match setVar CharacterSet setVar(CharacterSet::setAlphaNum, "#$_'", 0x80, true); CharacterSet setArray(CharacterSet::setAlpha, "#$_+-", 0x80, true); CharacterSet setHash(CharacterSet::setAlpha, "#$_!^+-", 0x80, true); CharacterSet &setPOD = setModifiers; CharacterSet setNonHereDoc(CharacterSet::setDigits, "=$@"); CharacterSet setHereDocDelim(CharacterSet::setAlphaNum, "_"); CharacterSet setSubPrototype(CharacterSet::setNone, "\\[$@%&*+];"); // for format identifiers CharacterSet setFormatStart(CharacterSet::setAlpha, "_="); CharacterSet &setFormat = setHereDocDelim; // Lexer for perl often has to backtrack to start of current style to determine // which characters are being used as quotes, how deeply nested is the // start position and what the termination string is for HERE documents. class HereDocCls { // Class to manage HERE doc sequence public: int State; // 0: '<<' encountered // 1: collect the delimiter // 2: here doc text (lines after the delimiter) int Quote; // the char after '<<' bool Quoted; // true if Quote in ('\'','"','`') int DelimiterLength; // strlen(Delimiter) char *Delimiter; // the Delimiter, 256: sizeof PL_tokenbuf HereDocCls() { State = 0; Quote = 0; Quoted = false; DelimiterLength = 0; Delimiter = new char[HERE_DELIM_MAX]; Delimiter[0] = '\0'; } void Append(int ch) { Delimiter[DelimiterLength++] = static_cast<char>(ch); Delimiter[DelimiterLength] = '\0'; } ~HereDocCls() { delete []Delimiter; } }; HereDocCls HereDoc; // TODO: FIFO for stacked here-docs class QuoteCls { // Class to manage quote pairs public: int Rep; int Count; int Up, Down; QuoteCls() { this->New(1); } void New(int r = 1) { Rep = r; Count = 0; Up = '\0'; Down = '\0'; } void Open(int u) { Count++; Up = u; Down = opposite(Up); } }; QuoteCls Quote; // additional state for number lexing int numState = PERLNUM_DECIMAL; int dotCount = 0; unsigned int endPos = startPos + length; // Backtrack to beginning of style if required... // If in a long distance lexical state, backtrack to find quote characters. // Includes strings (may be multi-line), numbers (additional state), format // bodies, as well as POD sections. if (initStyle == SCE_PL_HERE_Q || initStyle == SCE_PL_HERE_QQ || initStyle == SCE_PL_HERE_QX || initStyle == SCE_PL_FORMAT || initStyle == SCE_PL_HERE_QQ_VAR || initStyle == SCE_PL_HERE_QX_VAR ) { // backtrack through multiple styles to reach the delimiter start int delim = (initStyle == SCE_PL_FORMAT) ? SCE_PL_FORMAT_IDENT:SCE_PL_HERE_DELIM; while ((startPos > 1) && (styler.StyleAt(startPos) != delim)) { startPos--; } startPos = styler.LineStart(styler.GetLine(startPos)); initStyle = styler.StyleAt(startPos - 1); } if (initStyle == SCE_PL_STRING || initStyle == SCE_PL_STRING_QQ || initStyle == SCE_PL_BACKTICKS || initStyle == SCE_PL_STRING_QX || initStyle == SCE_PL_REGEX || initStyle == SCE_PL_STRING_QR || initStyle == SCE_PL_REGSUBST || initStyle == SCE_PL_STRING_VAR || initStyle == SCE_PL_STRING_QQ_VAR || initStyle == SCE_PL_BACKTICKS_VAR || initStyle == SCE_PL_STRING_QX_VAR || initStyle == SCE_PL_REGEX_VAR || initStyle == SCE_PL_STRING_QR_VAR || initStyle == SCE_PL_REGSUBST_VAR ) { // for interpolation, must backtrack through a mix of two different styles int otherStyle = (initStyle >= SCE_PL_STRING_VAR) ? initStyle - INTERPOLATE_SHIFT : initStyle + INTERPOLATE_SHIFT; while (startPos > 1) { int st = styler.StyleAt(startPos - 1); if ((st != initStyle) && (st != otherStyle)) break; startPos--; } initStyle = SCE_PL_DEFAULT; } else if (initStyle == SCE_PL_STRING_Q || initStyle == SCE_PL_STRING_QW || initStyle == SCE_PL_XLAT || initStyle == SCE_PL_CHARACTER || initStyle == SCE_PL_NUMBER || initStyle == SCE_PL_IDENTIFIER || initStyle == SCE_PL_ERROR || initStyle == SCE_PL_SUB_PROTOTYPE ) { while ((startPos > 1) && (styler.StyleAt(startPos - 1) == initStyle)) { startPos--; } initStyle = SCE_PL_DEFAULT; } else if (initStyle == SCE_PL_POD || initStyle == SCE_PL_POD_VERB ) { // POD backtracking finds preceeding blank lines and goes back past them int ln = styler.GetLine(startPos); if (ln > 0) { initStyle = styler.StyleAt(styler.LineStart(--ln)); if (initStyle == SCE_PL_POD || initStyle == SCE_PL_POD_VERB) { while (ln > 0 && styler.GetLineState(ln) == SCE_PL_DEFAULT) ln--; } startPos = styler.LineStart(++ln); initStyle = styler.StyleAt(startPos - 1); } else { startPos = 0; initStyle = SCE_PL_DEFAULT; } } // backFlag, backPos are additional state to aid identifier corner cases. // Look backwards past whitespace and comments in order to detect either // operator or keyword. Later updated as we go along. int backFlag = BACK_NONE; unsigned int backPos = startPos; if (backPos > 0) { backPos--; skipWhitespaceComment(styler, backPos); if (styler.StyleAt(backPos) == SCE_PL_OPERATOR) backFlag = BACK_OPERATOR; else if (styler.StyleAt(backPos) == SCE_PL_WORD) backFlag = BACK_KEYWORD; backPos++; } StyleContext sc(startPos, endPos - startPos, initStyle, styler, static_cast<char>(STYLE_MAX)); for (; sc.More(); sc.Forward()) { // Determine if the current state should terminate. switch (sc.state) { case SCE_PL_OPERATOR: sc.SetState(SCE_PL_DEFAULT); backFlag = BACK_OPERATOR; backPos = sc.currentPos; break; case SCE_PL_IDENTIFIER: // identifier, bareword, inputsymbol if ((!setWord.Contains(sc.ch) && sc.ch != '\'') || sc.Match('.', '.') || sc.chPrev == '>') { // end of inputsymbol sc.SetState(SCE_PL_DEFAULT); } break; case SCE_PL_WORD: // keyword, plus special cases if (!setWord.Contains(sc.ch)) { char s[100]; sc.GetCurrent(s, sizeof(s)); if ((strcmp(s, "__DATA__") == 0) || (strcmp(s, "__END__") == 0)) { sc.ChangeState(SCE_PL_DATASECTION); } else { if ((strcmp(s, "format") == 0)) { sc.SetState(SCE_PL_FORMAT_IDENT); HereDoc.State = 0; } else { sc.SetState(SCE_PL_DEFAULT); } backFlag = BACK_KEYWORD; backPos = sc.currentPos; } } break; case SCE_PL_SCALAR: case SCE_PL_ARRAY: case SCE_PL_HASH: case SCE_PL_SYMBOLTABLE: if (sc.Match(':', ':')) { // skip :: sc.Forward(); } else if (!setVar.Contains(sc.ch)) { if (sc.LengthCurrent() == 1) { // Special variable: $(, $_ etc. sc.Forward(); } sc.SetState(SCE_PL_DEFAULT); } break; case SCE_PL_NUMBER: // if no early break, number style is terminated at "(go through)" if (sc.ch == '.') { if (sc.chNext == '.') { // double dot is always an operator (go through) } else if (numState <= PERLNUM_FLOAT_EXP) { // non-decimal number or float exponent, consume next dot sc.SetState(SCE_PL_OPERATOR); break; } else { // decimal or vectors allows dots dotCount++; if (numState == PERLNUM_DECIMAL) { if (dotCount <= 1) // number with one dot in it break; if (IsADigit(sc.chNext)) { // really a vector numState = PERLNUM_VECTOR; break; } // number then dot (go through) } else if (IsADigit(sc.chNext)) // vectors break; // vector then dot (go through) } } else if (sc.ch == '_') { // permissive underscoring for number and vector literals break; } else if (numState == PERLNUM_DECIMAL) { if (sc.ch == 'E' || sc.ch == 'e') { // exponent, sign numState = PERLNUM_FLOAT_EXP; if (sc.chNext == '+' || sc.chNext == '-') { sc.Forward(); } break; } else if (IsADigit(sc.ch)) break; // number then word (go through) } else if (numState == PERLNUM_HEX) { if (IsADigit(sc.ch, 16)) break; } else if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) { if (IsADigit(sc.ch)) // vector break; if (setWord.Contains(sc.ch) && dotCount == 0) { // change to word sc.ChangeState(SCE_PL_IDENTIFIER); break; } // vector then word (go through) } else if (IsADigit(sc.ch)) { if (numState == PERLNUM_FLOAT_EXP) { break; } else if (numState == PERLNUM_OCTAL) { if (sc.ch <= '7') break; } else if (numState == PERLNUM_BINARY) { if (sc.ch <= '1') break; } // mark invalid octal, binary numbers (go through) numState = PERLNUM_BAD; break; } // complete current number or vector sc.ChangeState(actualNumStyle(numState)); sc.SetState(SCE_PL_DEFAULT); break; case SCE_PL_COMMENTLINE: if (sc.atLineEnd) { sc.SetState(SCE_PL_DEFAULT); } break; case SCE_PL_HERE_DELIM: if (HereDoc.State == 0) { // '<<' encountered int delim_ch = sc.chNext; int ws_skip = 0; HereDoc.State = 1; // pre-init HERE doc class HereDoc.Quote = sc.chNext; HereDoc.Quoted = false; HereDoc.DelimiterLength = 0; HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0'; if (IsASpaceOrTab(delim_ch)) { // skip whitespace; legal only for quoted delimiters unsigned int i = sc.currentPos + 1; while ((i < endPos) && IsASpaceOrTab(delim_ch)) { i++; delim_ch = static_cast<unsigned char>(styler.SafeGetCharAt(i)); } ws_skip = i - sc.currentPos - 1; } if (delim_ch == '\'' || delim_ch == '"' || delim_ch == '`') { // a quoted here-doc delimiter; skip any whitespace sc.Forward(ws_skip + 1); HereDoc.Quote = delim_ch; HereDoc.Quoted = true; } else if ((ws_skip == 0 && setNonHereDoc.Contains(sc.chNext)) || ws_skip > 0) { // left shift << or <<= operator cases // restore position if operator sc.ChangeState(SCE_PL_OPERATOR); sc.ForwardSetState(SCE_PL_DEFAULT); backFlag = BACK_OPERATOR; backPos = sc.currentPos; HereDoc.State = 0; } else { // specially handle initial '\' for identifier if (ws_skip == 0 && HereDoc.Quote == '\\') sc.Forward(); // an unquoted here-doc delimiter, no special handling // (cannot be prefixed by spaces/tabs), or // symbols terminates; deprecated zero-length delimiter } } else if (HereDoc.State == 1) { // collect the delimiter backFlag = BACK_NONE; if (HereDoc.Quoted) { // a quoted here-doc delimiter if (sc.ch == HereDoc.Quote) { // closing quote => end of delimiter sc.ForwardSetState(SCE_PL_DEFAULT); } else if (!sc.atLineEnd) { if (sc.Match('\\', static_cast<char>(HereDoc.Quote))) { // escaped quote sc.Forward(); } if (sc.ch != '\r') { // skip CR if CRLF HereDoc.Append(sc.ch); } } } else { // an unquoted here-doc delimiter if (setHereDocDelim.Contains(sc.ch)) { HereDoc.Append(sc.ch); } else { sc.SetState(SCE_PL_DEFAULT); } } if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) { sc.SetState(SCE_PL_ERROR); HereDoc.State = 0; } } break; case SCE_PL_HERE_Q: case SCE_PL_HERE_QQ: case SCE_PL_HERE_QX: // also implies HereDoc.State == 2 sc.Complete(); if (HereDoc.DelimiterLength == 0 || sc.Match(HereDoc.Delimiter)) { int c = sc.GetRelative(HereDoc.DelimiterLength); if (c == '\r' || c == '\n') { // peek first, do not consume match sc.Forward(HereDoc.DelimiterLength); sc.SetState(SCE_PL_DEFAULT); backFlag = BACK_NONE; HereDoc.State = 0; if (!sc.atLineEnd) sc.Forward(); break; } } if (sc.state == SCE_PL_HERE_Q) { // \EOF and 'EOF' non-interpolated while (!sc.atLineEnd) sc.Forward(); break; } while (!sc.atLineEnd) { // "EOF" and `EOF` interpolated int s = 0, endType = 0; int maxSeg = endPos - sc.currentPos; while (s < maxSeg) { // scan to break string into segments int c = sc.GetRelative(s); if (c == '\\') { endType = 1; break; } else if (c == '\r' || c == '\n') { endType = 2; break; } s++; } if (s > 0) // process non-empty segments InterpolateSegment(sc, s); if (endType == 1) { sc.Forward(); // \ at end-of-line does not appear to have any effect, skip if (sc.ch != '\r' && sc.ch != '\n') sc.Forward(); } else if (endType == 2) { if (!sc.atLineEnd) sc.Forward(); } } break; case SCE_PL_POD: case SCE_PL_POD_VERB: { unsigned int fw = sc.currentPos; int ln = styler.GetLine(fw); if (sc.atLineStart && sc.Match("=cut")) { // end of POD sc.SetState(SCE_PL_POD); sc.Forward(4); sc.SetState(SCE_PL_DEFAULT); styler.SetLineState(ln, SCE_PL_POD); break; } int pod = podLineScan(styler, fw, endPos); // classify POD line styler.SetLineState(ln, pod); if (pod == SCE_PL_DEFAULT) { if (sc.state == SCE_PL_POD_VERB) { unsigned int fw2 = fw; while (fw2 <= endPos && pod == SCE_PL_DEFAULT) { fw = fw2++; // penultimate line (last blank line) pod = podLineScan(styler, fw2, endPos); styler.SetLineState(styler.GetLine(fw2), pod); } if (pod == SCE_PL_POD) { // truncate verbatim POD early sc.SetState(SCE_PL_POD); } else fw = fw2; } } else { if (pod == SCE_PL_POD_VERB // still part of current paragraph && (styler.GetLineState(ln - 1) == SCE_PL_POD)) { pod = SCE_PL_POD; styler.SetLineState(ln, pod); } else if (pod == SCE_PL_POD && (styler.GetLineState(ln - 1) == SCE_PL_POD_VERB)) { pod = SCE_PL_POD_VERB; styler.SetLineState(ln, pod); } sc.SetState(pod); } sc.Forward(fw - sc.currentPos); // commit style } break; case SCE_PL_REGEX: case SCE_PL_STRING_QR: if (Quote.Rep <= 0) { if (!setModifiers.Contains(sc.ch)) sc.SetState(SCE_PL_DEFAULT); } else if (!Quote.Up && !IsASpace(sc.ch)) { Quote.Open(sc.ch); } else { int s = 0, endType = 0; int maxSeg = endPos - sc.currentPos; while (s < maxSeg) { // scan to break string into segments int c = sc.GetRelative(s); if (IsASpace(c)) { break; } else if (c == '\\' && Quote.Up != '\\') { endType = 1; break; } else if (c == Quote.Down) { Quote.Count--; if (Quote.Count == 0) { Quote.Rep--; break; } } else if (c == Quote.Up) Quote.Count++; s++; } if (s > 0) { // process non-empty segments if (Quote.Up != '\'') { InterpolateSegment(sc, s, true); } else // non-interpolated path sc.Forward(s); } if (endType == 1) sc.Forward(); } break; case SCE_PL_REGSUBST: case SCE_PL_XLAT: if (Quote.Rep <= 0) { if (!setModifiers.Contains(sc.ch)) sc.SetState(SCE_PL_DEFAULT); } else if (!Quote.Up && !IsASpace(sc.ch)) { Quote.Open(sc.ch); } else { int s = 0, endType = 0; int maxSeg = endPos - sc.currentPos; bool isPattern = (Quote.Rep == 2); while (s < maxSeg) { // scan to break string into segments int c = sc.GetRelative(s); if (c == '\\' && Quote.Up != '\\') { endType = 2; break; } else if (Quote.Count == 0 && Quote.Rep == 1) { // We matched something like s(...) or tr{...}, Perl 5.10 // appears to allow almost any character for use as the // next delimiters. Whitespace and comments are accepted in // between, but we'll limit to whitespace here. // For '#', if no whitespace in between, it's a delimiter. if (IsASpace(c)) { // Keep going } else if (c == '#' && IsASpaceOrTab(sc.GetRelative(s - 1))) { endType = 3; } else Quote.Open(c); break; } else if (c == Quote.Down) { Quote.Count--; if (Quote.Count == 0) { Quote.Rep--; endType = 1; } if (Quote.Up == Quote.Down) Quote.Count++; if (endType == 1) break; } else if (c == Quote.Up) { Quote.Count++; } else if (IsASpace(c)) break; s++; } if (s > 0) { // process non-empty segments if (sc.state == SCE_PL_REGSUBST && Quote.Up != '\'') { InterpolateSegment(sc, s, isPattern); } else // non-interpolated path sc.Forward(s); } if (endType == 2) { sc.Forward(); } else if (endType == 3) sc.SetState(SCE_PL_DEFAULT); } break; case SCE_PL_STRING_Q: case SCE_PL_STRING_QQ: case SCE_PL_STRING_QX: case SCE_PL_STRING_QW: case SCE_PL_STRING: case SCE_PL_CHARACTER: case SCE_PL_BACKTICKS: if (!Quote.Down && !IsASpace(sc.ch)) { Quote.Open(sc.ch); } else { int s = 0, endType = 0; int maxSeg = endPos - sc.currentPos; while (s < maxSeg) { // scan to break string into segments int c = sc.GetRelative(s); if (IsASpace(c)) { break; } else if (c == '\\' && Quote.Up != '\\') { endType = 2; break; } else if (c == Quote.Down) { Quote.Count--; if (Quote.Count == 0) { endType = 3; break; } } else if (c == Quote.Up) Quote.Count++; s++; } if (s > 0) { // process non-empty segments switch (sc.state) { case SCE_PL_STRING: case SCE_PL_STRING_QQ: case SCE_PL_BACKTICKS: InterpolateSegment(sc, s); break; case SCE_PL_STRING_QX: if (Quote.Up != '\'') { InterpolateSegment(sc, s); break; } // (continued for ' delim) default: // non-interpolated path sc.Forward(s); } } if (endType == 2) { sc.Forward(); } else if (endType == 3) sc.ForwardSetState(SCE_PL_DEFAULT); } break; case SCE_PL_SUB_PROTOTYPE: { int i = 0; // forward scan; must all be valid proto characters while (setSubPrototype.Contains(sc.GetRelative(i))) i++; if (sc.GetRelative(i) == ')') { // valid sub prototype sc.Forward(i); sc.ForwardSetState(SCE_PL_DEFAULT); } else { // abandon prototype, restart from '(' sc.ChangeState(SCE_PL_OPERATOR); sc.SetState(SCE_PL_DEFAULT); } } break; case SCE_PL_FORMAT: { sc.Complete(); if (sc.Match('.')) { sc.Forward(); if (sc.atLineEnd || ((sc.ch == '\r' && sc.chNext == '\n'))) sc.SetState(SCE_PL_DEFAULT); } while (!sc.atLineEnd) sc.Forward(); } break; case SCE_PL_ERROR: break; } // Needed for specific continuation styles (one follows the other) switch (sc.state) { // continued from SCE_PL_WORD case SCE_PL_FORMAT_IDENT: // occupies HereDoc state 3 to avoid clashing with HERE docs if (IsASpaceOrTab(sc.ch)) { // skip whitespace sc.ChangeState(SCE_PL_DEFAULT); while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) sc.Forward(); sc.SetState(SCE_PL_FORMAT_IDENT); } if (setFormatStart.Contains(sc.ch)) { // identifier or '=' if (sc.ch != '=') { do { sc.Forward(); } while (setFormat.Contains(sc.ch)); } while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) sc.Forward(); if (sc.ch == '=') { sc.ForwardSetState(SCE_PL_DEFAULT); HereDoc.State = 3; } else { // invalid indentifier; inexact fallback, but hey sc.ChangeState(SCE_PL_IDENTIFIER); sc.SetState(SCE_PL_DEFAULT); } } else { sc.ChangeState(SCE_PL_DEFAULT); // invalid indentifier } backFlag = BACK_NONE; break; } // Must check end of HereDoc states here before default state is handled if (HereDoc.State == 1 && sc.atLineEnd) { // Begin of here-doc (the line after the here-doc delimiter): // Lexically, the here-doc starts from the next line after the >>, but the // first line of here-doc seem to follow the style of the last EOL sequence int st_new = SCE_PL_HERE_QQ; HereDoc.State = 2; if (HereDoc.Quoted) { if (sc.state == SCE_PL_HERE_DELIM) { // Missing quote at end of string! We are stricter than perl. // Colour here-doc anyway while marking this bit as an error. sc.ChangeState(SCE_PL_ERROR); } switch (HereDoc.Quote) { case '\'': st_new = SCE_PL_HERE_Q ; break; case '"' : st_new = SCE_PL_HERE_QQ; break; case '`' : st_new = SCE_PL_HERE_QX; break; } } else { if (HereDoc.Quote == '\\') st_new = SCE_PL_HERE_Q; } sc.SetState(st_new); } if (HereDoc.State == 3 && sc.atLineEnd) { // Start of format body. HereDoc.State = 0; sc.SetState(SCE_PL_FORMAT); } // Determine if a new state should be entered. if (sc.state == SCE_PL_DEFAULT) { if (IsADigit(sc.ch) || (IsADigit(sc.chNext) && (sc.ch == '.' || sc.ch == 'v'))) { sc.SetState(SCE_PL_NUMBER); backFlag = BACK_NONE; numState = PERLNUM_DECIMAL; dotCount = 0; if (sc.ch == '0') { // hex,bin,octal if (sc.chNext == 'x' || sc.chNext == 'X') { numState = PERLNUM_HEX; } else if (sc.chNext == 'b' || sc.chNext == 'B') { numState = PERLNUM_BINARY; } else if (IsADigit(sc.chNext)) { numState = PERLNUM_OCTAL; } if (numState != PERLNUM_DECIMAL) { sc.Forward(); } } else if (sc.ch == 'v') { // vector numState = PERLNUM_V_VECTOR; } } else if (setWord.Contains(sc.ch)) { // if immediately prefixed by '::', always a bareword sc.SetState(SCE_PL_WORD); if (sc.chPrev == ':' && sc.GetRelative(-2) == ':') { sc.ChangeState(SCE_PL_IDENTIFIER); } unsigned int bk = sc.currentPos; unsigned int fw = sc.currentPos + 1; // first check for possible quote-like delimiter if (sc.ch == 's' && !setWord.Contains(sc.chNext)) { sc.ChangeState(SCE_PL_REGSUBST); Quote.New(2); } else if (sc.ch == 'm' && !setWord.Contains(sc.chNext)) { sc.ChangeState(SCE_PL_REGEX); Quote.New(); } else if (sc.ch == 'q' && !setWord.Contains(sc.chNext)) { sc.ChangeState(SCE_PL_STRING_Q); Quote.New(); } else if (sc.ch == 'y' && !setWord.Contains(sc.chNext)) { sc.ChangeState(SCE_PL_XLAT); Quote.New(2); } else if (sc.Match('t', 'r') && !setWord.Contains(sc.GetRelative(2))) { sc.ChangeState(SCE_PL_XLAT); Quote.New(2); sc.Forward(); fw++; } else if (sc.ch == 'q' && setQDelim.Contains(sc.chNext) && !setWord.Contains(sc.GetRelative(2))) { if (sc.chNext == 'q') sc.ChangeState(SCE_PL_STRING_QQ); else if (sc.chNext == 'x') sc.ChangeState(SCE_PL_STRING_QX); else if (sc.chNext == 'r') sc.ChangeState(SCE_PL_STRING_QR); else sc.ChangeState(SCE_PL_STRING_QW); // sc.chNext == 'w' Quote.New(); sc.Forward(); fw++; } else if (sc.ch == 'x' && (sc.chNext == '=' || // repetition !setWord.Contains(sc.chNext) || (IsADigit(sc.chPrev) && IsADigit(sc.chNext)))) { sc.ChangeState(SCE_PL_OPERATOR); } // if potentially a keyword, scan forward and grab word, then check // if it's really one; if yes, disambiguation test is performed // otherwise it is always a bareword and we skip a lot of scanning if (sc.state == SCE_PL_WORD) { while (setWord.Contains(static_cast<unsigned char>(styler.SafeGetCharAt(fw)))) fw++; if (!isPerlKeyword(styler.GetStartSegment(), fw, keywords, styler)) { sc.ChangeState(SCE_PL_IDENTIFIER); } } // if already SCE_PL_IDENTIFIER, then no ambiguity, skip this // for quote-like delimiters/keywords, attempt to disambiguate // to select for bareword, change state -> SCE_PL_IDENTIFIER if (sc.state != SCE_PL_IDENTIFIER && bk > 0) { if (disambiguateBareword(styler, bk, fw, backFlag, backPos, endPos)) sc.ChangeState(SCE_PL_IDENTIFIER); } backFlag = BACK_NONE; } else if (sc.ch == '#') { sc.SetState(SCE_PL_COMMENTLINE); } else if (sc.ch == '\"') { sc.SetState(SCE_PL_STRING); Quote.New(); Quote.Open(sc.ch); backFlag = BACK_NONE; } else if (sc.ch == '\'') { if (sc.chPrev == '&' && setWordStart.Contains(sc.chNext)) { // Archaic call sc.SetState(SCE_PL_IDENTIFIER); } else { sc.SetState(SCE_PL_CHARACTER); Quote.New(); Quote.Open(sc.ch); } backFlag = BACK_NONE; } else if (sc.ch == '`') { sc.SetState(SCE_PL_BACKTICKS); Quote.New(); Quote.Open(sc.ch); backFlag = BACK_NONE; } else if (sc.ch == '$') { sc.SetState(SCE_PL_SCALAR); if (sc.chNext == '{') { sc.ForwardSetState(SCE_PL_OPERATOR); } else if (IsASpace(sc.chNext)) { sc.ForwardSetState(SCE_PL_DEFAULT); } else { sc.Forward(); if (sc.Match('`', '`') || sc.Match(':', ':')) { sc.Forward(); } } backFlag = BACK_NONE; } else if (sc.ch == '@') { sc.SetState(SCE_PL_ARRAY); if (setArray.Contains(sc.chNext)) { // no special treatment } else if (sc.chNext == ':' && sc.GetRelative(2) == ':') { sc.Forward(2); } else if (sc.chNext == '{' || sc.chNext == '[') { sc.ForwardSetState(SCE_PL_OPERATOR); } else { sc.ChangeState(SCE_PL_OPERATOR); } backFlag = BACK_NONE; } else if (setPreferRE.Contains(sc.ch)) { // Explicit backward peeking to set a consistent preferRE for // any slash found, so no longer need to track preferRE state. // Find first previous significant lexed element and interpret. // A few symbols shares this code for disambiguation. bool preferRE = false; bool isHereDoc = sc.Match('<', '<'); bool hereDocSpace = false; // for: SCALAR [whitespace] '<<' unsigned int bk = (sc.currentPos > 0) ? sc.currentPos - 1: 0; sc.Complete(); styler.Flush(); if (styler.StyleAt(bk) == SCE_PL_DEFAULT) hereDocSpace = true; skipWhitespaceComment(styler, bk); if (bk == 0) { // avoid backward scanning breakage preferRE = true; } else { int bkstyle = styler.StyleAt(bk); int bkch = static_cast<unsigned char>(styler.SafeGetCharAt(bk)); switch (bkstyle) { case SCE_PL_OPERATOR: preferRE = true; if (bkch == ')' || bkch == ']') { preferRE = false; } else if (bkch == '}') { // backtrack by counting balanced brace pairs // needed to test for variables like ${}, @{} etc. bkstyle = styleBeforeBracePair(styler, bk); if (bkstyle == SCE_PL_SCALAR || bkstyle == SCE_PL_ARRAY || bkstyle == SCE_PL_HASH || bkstyle == SCE_PL_SYMBOLTABLE || bkstyle == SCE_PL_OPERATOR) { preferRE = false; } } else if (bkch == '+' || bkch == '-') { if (bkch == static_cast<unsigned char>(styler.SafeGetCharAt(bk - 1)) && bkch != static_cast<unsigned char>(styler.SafeGetCharAt(bk - 2))) // exceptions for operators: unary suffixes ++, -- preferRE = false; } break; case SCE_PL_IDENTIFIER: preferRE = true; bkstyle = styleCheckIdentifier(styler, bk); if ((bkstyle == 1) || (bkstyle == 2)) { // inputsymbol or var with "->" or "::" before identifier preferRE = false; } else if (bkstyle == 3) { // bare identifier, test cases follows: if (sc.ch == '/') { // if '/', /PATTERN/ unless digit/space immediately after '/' // if '//', always expect defined-or operator to follow identifier if (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.chNext == '/') preferRE = false; } else if (sc.ch == '*' || sc.ch == '%') { if (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.Match('*', '*')) preferRE = false; } else if (sc.ch == '<') { if (IsASpace(sc.chNext) || sc.chNext == '=') preferRE = false; } } break; case SCE_PL_SCALAR: // for $var<< case: if (isHereDoc && hereDocSpace) // if SCALAR whitespace '<<', *always* a HERE doc preferRE = true; break; case SCE_PL_WORD: preferRE = true; // for HERE docs, always true if (sc.ch == '/') { // adopt heuristics similar to vim-style rules: // keywords always forced as /PATTERN/: split, if, elsif, while // everything else /PATTERN/ unless digit/space immediately after '/' // for '//', defined-or favoured unless special keywords unsigned int bkend = bk + 1; while (bk > 0 && styler.StyleAt(bk - 1) == SCE_PL_WORD) { bk--; } if (isPerlKeyword(bk, bkend, reWords, styler)) break; if (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.chNext == '/') preferRE = false; } else if (sc.ch == '*' || sc.ch == '%') { if (IsASpace(sc.chNext) || IsADigit(sc.chNext) || sc.Match('*', '*')) preferRE = false; } else if (sc.ch == '<') { if (IsASpace(sc.chNext) || sc.chNext == '=') preferRE = false; } break; // other styles uses the default, preferRE=false case SCE_PL_POD: case SCE_PL_HERE_Q: case SCE_PL_HERE_QQ: case SCE_PL_HERE_QX: preferRE = true; break; } } backFlag = BACK_NONE; if (isHereDoc) { // handle '<<', HERE doc if (preferRE) { sc.SetState(SCE_PL_HERE_DELIM); HereDoc.State = 0; } else { // << operator sc.SetState(SCE_PL_OPERATOR); sc.Forward(); } } else if (sc.ch == '*') { // handle '*', typeglob if (preferRE) { sc.SetState(SCE_PL_SYMBOLTABLE); if (sc.chNext == ':' && sc.GetRelative(2) == ':') { sc.Forward(2); } else if (sc.chNext == '{') { sc.ForwardSetState(SCE_PL_OPERATOR); } else { sc.Forward(); } } else { sc.SetState(SCE_PL_OPERATOR); if (sc.chNext == '*') // exponentiation sc.Forward(); } } else if (sc.ch == '%') { // handle '%', hash if (preferRE) { sc.SetState(SCE_PL_HASH); if (setHash.Contains(sc.chNext)) { sc.Forward(); } else if (sc.chNext == ':' && sc.GetRelative(2) == ':') { sc.Forward(2); } else if (sc.chNext == '{') { sc.ForwardSetState(SCE_PL_OPERATOR); } else { sc.ChangeState(SCE_PL_OPERATOR); } } else { sc.SetState(SCE_PL_OPERATOR); } } else if (sc.ch == '<') { // handle '<', inputsymbol if (preferRE) { // forward scan int i = inputsymbolScan(styler, sc.currentPos, endPos); if (i > 0) { sc.SetState(SCE_PL_IDENTIFIER); sc.Forward(i); } else { sc.SetState(SCE_PL_OPERATOR); } } else { sc.SetState(SCE_PL_OPERATOR); } } else { // handle '/', regexp if (preferRE) { sc.SetState(SCE_PL_REGEX); Quote.New(); Quote.Open(sc.ch); } else { // / and // operators sc.SetState(SCE_PL_OPERATOR); if (sc.chNext == '/') { sc.Forward(); } } } } else if (sc.ch == '=' // POD && setPOD.Contains(sc.chNext) && sc.atLineStart) { sc.SetState(SCE_PL_POD); backFlag = BACK_NONE; } else if (sc.ch == '-' && setWordStart.Contains(sc.chNext)) { // extended '-' cases unsigned int bk = sc.currentPos; unsigned int fw = 2; if (setSingleCharOp.Contains(sc.chNext) && // file test operators !setWord.Contains(sc.GetRelative(2))) { sc.SetState(SCE_PL_WORD); } else { // nominally a minus and bareword; find extent of bareword while (setWord.Contains(sc.GetRelative(fw))) fw++; sc.SetState(SCE_PL_OPERATOR); } // force to bareword for hash key => or {variable literal} cases if (disambiguateBareword(styler, bk, bk + fw, backFlag, backPos, endPos) & 2) { sc.ChangeState(SCE_PL_IDENTIFIER); } backFlag = BACK_NONE; } else if (sc.ch == '(' && sc.currentPos > 0) { // '(' or subroutine prototype sc.Complete(); if (styleCheckSubPrototype(styler, sc.currentPos - 1)) { sc.SetState(SCE_PL_SUB_PROTOTYPE); backFlag = BACK_NONE; } else { sc.SetState(SCE_PL_OPERATOR); } } else if (setPerlOperator.Contains(sc.ch)) { // operators sc.SetState(SCE_PL_OPERATOR); if (sc.Match('.', '.')) { // .. and ... sc.Forward(); if (sc.chNext == '.') sc.Forward(); } } else if (sc.ch == 4 || sc.ch == 26) { // ^D and ^Z ends valid perl source sc.SetState(SCE_PL_DATASECTION); } else { // keep colouring defaults sc.Complete(); } } } sc.Complete(); if (sc.state == SCE_PL_HERE_Q || sc.state == SCE_PL_HERE_QQ || sc.state == SCE_PL_HERE_QX || sc.state == SCE_PL_FORMAT) { styler.ChangeLexerState(sc.currentPos, styler.Length()); } sc.Complete(); } #define PERL_HEADFOLD_SHIFT 4 #define PERL_HEADFOLD_MASK 0xF0 void SCI_METHOD LexerPerl::Fold(unsigned int startPos, int length, int /* initStyle */, IDocument *pAccess) { if (!options.fold) return; LexAccessor styler(pAccess); unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); // Backtrack to previous line in case need to fix its fold status if (startPos > 0) { if (lineCurrent > 0) { lineCurrent--; startPos = styler.LineStart(lineCurrent); } } int levelPrev = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelPrev = styler.LevelAt(lineCurrent - 1) >> 16; int levelCurrent = levelPrev; char chNext = styler[startPos]; char chPrev = styler.SafeGetCharAt(startPos - 1); int styleNext = styler.StyleAt(startPos); // Used at end of line to determine if the line was a package definition bool isPackageLine = false; int podHeading = 0; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int style = styleNext; styleNext = styler.StyleAt(i + 1); int stylePrevCh = (i) ? styler.StyleAt(i - 1):SCE_PL_DEFAULT; bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); bool atLineStart = ((chPrev == '\r') || (chPrev == '\n')) || i == 0; // Comment folding if (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler)) { if (!IsCommentLine(lineCurrent - 1, styler) && IsCommentLine(lineCurrent + 1, styler)) levelCurrent++; else if (IsCommentLine(lineCurrent - 1, styler) && !IsCommentLine(lineCurrent + 1, styler)) levelCurrent--; } // {} [] block folding if (style == SCE_PL_OPERATOR) { if (ch == '{') { if (options.foldAtElse && levelCurrent < levelPrev) --levelPrev; levelCurrent++; } else if (ch == '}') { levelCurrent--; } if (ch == '[') { if (options.foldAtElse && levelCurrent < levelPrev) --levelPrev; levelCurrent++; } else if (ch == ']') { levelCurrent--; } } // POD folding if (options.foldPOD && atLineStart) { if (style == SCE_PL_POD) { if (stylePrevCh != SCE_PL_POD && stylePrevCh != SCE_PL_POD_VERB) levelCurrent++; else if (styler.Match(i, "=cut")) levelCurrent = (levelCurrent & ~PERL_HEADFOLD_MASK) - 1; else if (styler.Match(i, "=head")) podHeading = PodHeadingLevel(i, styler); } else if (style == SCE_PL_DATASECTION) { if (ch == '=' && isascii(chNext) && isalpha(chNext) && levelCurrent == SC_FOLDLEVELBASE) levelCurrent++; else if (styler.Match(i, "=cut") && levelCurrent > SC_FOLDLEVELBASE) levelCurrent = (levelCurrent & ~PERL_HEADFOLD_MASK) - 1; else if (styler.Match(i, "=head")) podHeading = PodHeadingLevel(i, styler); // if package used or unclosed brace, level > SC_FOLDLEVELBASE! // reset needed as level test is vs. SC_FOLDLEVELBASE else if (stylePrevCh != SCE_PL_DATASECTION) levelCurrent = SC_FOLDLEVELBASE; } } // package folding if (options.foldPackage && atLineStart) { if (IsPackageLine(lineCurrent, styler) && !IsPackageLine(lineCurrent + 1, styler)) isPackageLine = true; } //heredoc folding switch (style) { case SCE_PL_HERE_QQ : case SCE_PL_HERE_Q : case SCE_PL_HERE_QX : switch (stylePrevCh) { case SCE_PL_HERE_QQ : case SCE_PL_HERE_Q : case SCE_PL_HERE_QX : //do nothing; break; default : levelCurrent++; break; } break; default: switch (stylePrevCh) { case SCE_PL_HERE_QQ : case SCE_PL_HERE_Q : case SCE_PL_HERE_QX : levelCurrent--; break; default : //do nothing; break; } break; } //explicit folding if (options.foldCommentExplicit && style == SCE_PL_COMMENTLINE && ch == '#') { if (chNext == '{') { levelCurrent++; } else if (levelCurrent > SC_FOLDLEVELBASE && chNext == '}') { levelCurrent--; } } if (atEOL) { int lev = levelPrev; // POD headings occupy bits 7-4, leaving some breathing room for // non-standard practice -- POD sections stuck in blocks, etc. if (podHeading > 0) { levelCurrent = (lev & ~PERL_HEADFOLD_MASK) | (podHeading << PERL_HEADFOLD_SHIFT); lev = levelCurrent - 1; lev |= SC_FOLDLEVELHEADERFLAG; podHeading = 0; } // Check if line was a package declaration // because packages need "special" treatment if (isPackageLine) { lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG; levelCurrent = SC_FOLDLEVELBASE + 1; isPackageLine = false; } lev |= levelCurrent << 16; if (visibleChars == 0 && options.foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; chPrev = ch; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } LexerModule lmPerl(SCLEX_PERL, LexerPerl::LexerFactoryPerl, "perl", perlWordListDesc, 8); |
Added lexers/LexPowerPro.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 |
// Scintilla source code edit control // @file LexPowerPro.cxx // PowerPro utility, written by Bruce Switzer, is available from http://powerpro.webeddie.com // PowerPro lexer is written by Christopher Bean (cbean@cb-software.net) // // Lexer code heavily borrowed from: // LexAU3.cxx by Jos van der Zande // LexCPP.cxx by Neil Hodgson // LexVB.cxx by Neil Hodgson // // Changes: // 2008-10-25 - Initial release // 2008-10-26 - Changed how <name> is hilighted in 'function <name>' so that // local isFunction = "" and local functions = "" don't get falsely highlighted // 2008-12-14 - Added bounds checking for szFirstWord and szDo // - Replaced SetOfCharacters with CharacterSet // - Made sure that CharacterSet::Contains is passed only positive values // - Made sure that the return value of Accessor::SafeGetCharAt is positive before // passing to functions that require positive values like isspacechar() // - Removed unused visibleChars processing from ColourisePowerProDoc() // - Fixed bug with folding logic where line continuations didn't end where // they were supposed to // - Moved all helper functions to the top of the file // 2010-06-03 - Added onlySpaces variable to allow the @function and ;comment styles to be indented // - Modified HasFunction function to be a bit more robust // - Renamed HasFunction function to IsFunction // - Cleanup // Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <string.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsStreamCommentStyle(int style) { return style == SCE_POWERPRO_COMMENTBLOCK; } static inline bool IsLineEndChar(unsigned char ch) { return ch == 0x0a //LF || ch == 0x0c //FF || ch == 0x0d; //CR } static bool IsContinuationLine(unsigned int szLine, Accessor &styler) { int startPos = styler.LineStart(szLine); int endPos = styler.LineStart(szLine + 1) - 2; while (startPos < endPos) { char stylech = styler.StyleAt(startPos); if (!(stylech == SCE_POWERPRO_COMMENTBLOCK)) { char ch = styler.SafeGetCharAt(endPos); char chPrev = styler.SafeGetCharAt(endPos - 1); char chPrevPrev = styler.SafeGetCharAt(endPos - 2); if (ch > 0 && chPrev > 0 && chPrevPrev > 0 && !isspacechar(ch) && !isspacechar(chPrev) && !isspacechar(chPrevPrev) ) return (chPrevPrev == ';' && chPrev == ';' && ch == '+'); } endPos--; // skip to next char } return false; } // Routine to find first none space on the current line and return its Style // needed for comment lines not starting on pos 1 static int GetStyleFirstWord(int szLine, Accessor &styler) { int startPos = styler.LineStart(szLine); int endPos = styler.LineStart(szLine + 1) - 1; char ch = styler.SafeGetCharAt(startPos); while (ch > 0 && isspacechar(ch) && startPos < endPos) { startPos++; // skip to next char ch = styler.SafeGetCharAt(startPos); } return styler.StyleAt(startPos); } //returns true if there is a function to highlight //used to highlight <name> in 'function <name>' //note: // sample line (without quotes): "\tfunction asdf() // currentPos will be the position of 'a' static bool IsFunction(Accessor &styler, unsigned int currentPos) { const char function[10] = "function "; //10 includes \0 unsigned int numberOfCharacters = sizeof(function) - 1; unsigned int position = currentPos - numberOfCharacters; //compare each character with the letters in the function array //return false if ALL don't match for (unsigned int i = 0; i < numberOfCharacters; i++) { char c = styler.SafeGetCharAt(position++); if (c != function[i]) return false; } //make sure that there are only spaces (or tabs) between the beginning //of the line and the function declaration position = currentPos - numberOfCharacters - 1; //-1 to move to char before 'function' for (unsigned int j = 0; j < 16; j++) { //check up to 16 preceeding characters char c = styler.SafeGetCharAt(position--, '\0'); //if can't read char, return NUL (past beginning of document) if (c <= 0) //reached beginning of document return true; if (c > 0 && IsLineEndChar(c)) return true; else if (c > 0 && !IsASpaceOrTab(c)) return false; } //fall-through return false; } static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler, bool caseSensitive) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; //define the character sets CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true); CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true); StyleContext sc(startPos, length, initStyle, styler); char s_save[100]; //for last line highlighting //are there only spaces between the first letter of the line and the beginning of the line bool onlySpaces = true; for (; sc.More(); sc.Forward()) { // save the total current word for eof processing char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if ((sc.ch > 0) && setWord.Contains(sc.ch)) { strcpy(s_save,s); int tp = static_cast<int>(strlen(s_save)); if (tp < 99) { s_save[tp] = static_cast<char>(tolower(sc.ch)); s_save[tp+1] = '\0'; } } if (sc.atLineStart) { if (sc.state == SCE_POWERPRO_DOUBLEQUOTEDSTRING) { // Prevent SCE_POWERPRO_STRINGEOL from leaking back to previous line which // ends with a line continuation by locking in the state upto this position. sc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING); } } // Determine if the current state should terminate. switch (sc.state) { case SCE_POWERPRO_OPERATOR: sc.SetState(SCE_POWERPRO_DEFAULT); break; case SCE_POWERPRO_NUMBER: if (!IsADigit(sc.ch)) sc.SetState(SCE_POWERPRO_DEFAULT); break; case SCE_POWERPRO_IDENTIFIER: //if ((sc.ch > 0) && !setWord.Contains(sc.ch) || (sc.ch == '.')) { // use this line if don't want to match keywords with . in them. ie: win.debug will match both win and debug so win debug will also be colorized if ((sc.ch > 0) && !setWord.Contains(sc.ch)){ // || (sc.ch == '.')) { // use this line if you want to match keywords with a . ie: win.debug will only match win.debug neither win nor debug will be colorized separately char s[1000]; if (caseSensitive) { sc.GetCurrent(s, sizeof(s)); } else { sc.GetCurrentLowered(s, sizeof(s)); } if (keywords.InList(s)) { sc.ChangeState(SCE_POWERPRO_WORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_POWERPRO_WORD2); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_POWERPRO_WORD3); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_POWERPRO_WORD4); } sc.SetState(SCE_POWERPRO_DEFAULT); } break; case SCE_POWERPRO_LINECONTINUE: if (sc.atLineStart) { sc.SetState(SCE_POWERPRO_DEFAULT); } else if (sc.Match('/', '*') || sc.Match('/', '/')) { sc.SetState(SCE_POWERPRO_DEFAULT); } break; case SCE_POWERPRO_COMMENTBLOCK: if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_POWERPRO_DEFAULT); } break; case SCE_POWERPRO_COMMENTLINE: if (sc.atLineStart) { sc.SetState(SCE_POWERPRO_DEFAULT); } break; case SCE_POWERPRO_DOUBLEQUOTEDSTRING: if (sc.atLineEnd) { sc.ChangeState(SCE_POWERPRO_STRINGEOL); } else if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_POWERPRO_DEFAULT); } break; case SCE_POWERPRO_SINGLEQUOTEDSTRING: if (sc.atLineEnd) { sc.ChangeState(SCE_POWERPRO_STRINGEOL); } else if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\'') { sc.ForwardSetState(SCE_POWERPRO_DEFAULT); } break; case SCE_POWERPRO_STRINGEOL: if (sc.atLineStart) { sc.SetState(SCE_POWERPRO_DEFAULT); } break; case SCE_POWERPRO_VERBATIM: if (sc.ch == '\"') { if (sc.chNext == '\"') { sc.Forward(); } else { sc.ForwardSetState(SCE_POWERPRO_DEFAULT); } } break; case SCE_POWERPRO_ALTQUOTE: if (sc.ch == '#') { if (sc.chNext == '#') { sc.Forward(); } else { sc.ForwardSetState(SCE_POWERPRO_DEFAULT); } } break; case SCE_POWERPRO_FUNCTION: if (isspacechar(sc.ch) || sc.ch == '(') { sc.SetState(SCE_POWERPRO_DEFAULT); } break; } // Determine if a new state should be entered. if (sc.state == SCE_POWERPRO_DEFAULT) { if (sc.Match('?', '\"')) { sc.SetState(SCE_POWERPRO_VERBATIM); sc.Forward(); } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_POWERPRO_NUMBER); }else if (sc.Match('?','#')) { if (sc.ch == '?' && sc.chNext == '#') { sc.SetState(SCE_POWERPRO_ALTQUOTE); sc.Forward(); } } else if (IsFunction(styler, sc.currentPos)) { //highlight <name> in 'function <name>' sc.SetState(SCE_POWERPRO_FUNCTION); } else if (onlySpaces && sc.ch == '@') { //alternate function definition [label] sc.SetState(SCE_POWERPRO_FUNCTION); } else if ((sc.ch > 0) && (setWordStart.Contains(sc.ch) || (sc.ch == '?'))) { sc.SetState(SCE_POWERPRO_IDENTIFIER); } else if (sc.Match(";;+")) { sc.SetState(SCE_POWERPRO_LINECONTINUE); } else if (sc.Match('/', '*')) { sc.SetState(SCE_POWERPRO_COMMENTBLOCK); sc.Forward(); // Eat the * so it isn't used for the end of the comment } else if (sc.Match('/', '/')) { sc.SetState(SCE_POWERPRO_COMMENTLINE); } else if (onlySpaces && sc.ch == ';') { //legacy comment that can only have blank space in front of it sc.SetState(SCE_POWERPRO_COMMENTLINE); } else if (sc.Match(";;")) { sc.SetState(SCE_POWERPRO_COMMENTLINE); } else if (sc.ch == '\"') { sc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING); } else if (sc.ch == '\'') { sc.SetState(SCE_POWERPRO_SINGLEQUOTEDSTRING); } else if (isoperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_POWERPRO_OPERATOR); } } //maintain a record of whether or not all the preceding characters on //a line are space characters if (onlySpaces && !IsASpaceOrTab(sc.ch)) onlySpaces = false; //reset when starting a new line if (sc.atLineEnd) onlySpaces = true; } //************************************* // Colourize the last word correctly //************************************* if (sc.state == SCE_POWERPRO_IDENTIFIER) { if (keywords.InList(s_save)) { sc.ChangeState(SCE_POWERPRO_WORD); sc.SetState(SCE_POWERPRO_DEFAULT); } else if (keywords2.InList(s_save)) { sc.ChangeState(SCE_POWERPRO_WORD2); sc.SetState(SCE_POWERPRO_DEFAULT); } else if (keywords3.InList(s_save)) { sc.ChangeState(SCE_POWERPRO_WORD3); sc.SetState(SCE_POWERPRO_DEFAULT); } else if (keywords4.InList(s_save)) { sc.ChangeState(SCE_POWERPRO_WORD4); sc.SetState(SCE_POWERPRO_DEFAULT); } else { sc.SetState(SCE_POWERPRO_DEFAULT); } } sc.Complete(); } static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { //define the character sets CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true); CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true); //used to tell if we're recursively folding the whole document, or just a small piece (ie: if statement or 1 function) bool isFoldingAll = true; int endPos = startPos + length; int lastLine = styler.GetLine(styler.Length()); //used to help fold the last line correctly // get settings from the config files for folding comments and preprocessor lines bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldInComment = styler.GetPropertyInt("fold.comment") == 2; bool foldCompact = true; // Backtrack to previous line in case need to fix its fold status int lineCurrent = styler.GetLine(startPos); if (startPos > 0) { isFoldingAll = false; if (lineCurrent > 0) { lineCurrent--; startPos = styler.LineStart(lineCurrent); } } // vars for style of previous/current/next lines int style = GetStyleFirstWord(lineCurrent,styler); int stylePrev = 0; // find the first previous line without continuation character at the end while ((lineCurrent > 0 && IsContinuationLine(lineCurrent, styler)) || (lineCurrent > 1 && IsContinuationLine(lineCurrent - 1, styler))) { lineCurrent--; startPos = styler.LineStart(lineCurrent); } if (lineCurrent > 0) { stylePrev = GetStyleFirstWord(lineCurrent-1,styler); } // vars for getting first word to check for keywords bool isFirstWordStarted = false; bool isFirstWordEnded = false; const unsigned int FIRST_WORD_MAX_LEN = 10; char szFirstWord[FIRST_WORD_MAX_LEN] = ""; unsigned int firstWordLen = 0; char szDo[3]=""; int szDolen = 0; bool isDoLastWord = false; // var for indentlevel int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelNext = levelCurrent; int visibleChars = 0; int functionCount = 0; char chNext = styler.SafeGetCharAt(startPos); char chPrev = '\0'; char chPrevPrev = '\0'; char chPrevPrevPrev = '\0'; for (int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if ((ch > 0) && setWord.Contains(ch)) visibleChars++; // get the syle for the current character neede to check in comment int stylech = styler.StyleAt(i); // start the capture of the first word if (!isFirstWordStarted && (ch > 0)) { if (setWord.Contains(ch) || setWordStart.Contains(ch) || ch == ';' || ch == '/') { isFirstWordStarted = true; if (firstWordLen < FIRST_WORD_MAX_LEN - 1) { szFirstWord[firstWordLen++] = static_cast<char>(tolower(ch)); szFirstWord[firstWordLen] = '\0'; } } } // continue capture of the first word on the line else if (isFirstWordStarted && !isFirstWordEnded && (ch > 0)) { if (!setWord.Contains(ch)) { isFirstWordEnded = true; } else if (firstWordLen < (FIRST_WORD_MAX_LEN - 1)) { szFirstWord[firstWordLen++] = static_cast<char>(tolower(ch)); szFirstWord[firstWordLen] = '\0'; } } if (stylech != SCE_POWERPRO_COMMENTLINE) { //reset isDoLastWord if we find a character(ignoring spaces) after 'do' if (isDoLastWord && (ch > 0) && setWord.Contains(ch)) isDoLastWord = false; // --find out if the word "do" is the last on a "if" line-- // collect each letter and put it into a buffer 2 chars long // if we end up with "do" in the buffer when we reach the end of // the line, "do" was the last word on the line if ((ch > 0) && isFirstWordEnded && strcmp(szFirstWord, "if") == 0) { if (szDolen == 2) { szDo[0] = szDo[1]; szDo[1] = static_cast<char>(tolower(ch)); szDo[2] = '\0'; if (strcmp(szDo, "do") == 0) isDoLastWord = true; } else if (szDolen < 2) { szDo[szDolen++] = static_cast<char>(tolower(ch)); szDo[szDolen] = '\0'; } } } // End of Line found so process the information if ((ch == '\r' && chNext != '\n') // \r\n || ch == '\n' // \n || i == endPos) { // end of selection // ************************** // Folding logic for Keywords // ************************** // if a keyword is found on the current line and the line doesn't end with ;;+ (continuation) // and we are not inside a commentblock. if (firstWordLen > 0 && chPrev != '+' && chPrevPrev != ';' && chPrevPrevPrev !=';' && (!IsStreamCommentStyle(style) || foldInComment) ) { // only fold "if" last keyword is "then" (else its a one line if) if (strcmp(szFirstWord, "if") == 0 && isDoLastWord) levelNext++; // create new fold for these words if (strcmp(szFirstWord, "for") == 0) levelNext++; //handle folding for functions/labels //Note: Functions and labels don't have an explicit end like [end function] // 1. functions/labels end at the start of another function // 2. functions/labels end at the end of the file if ((strcmp(szFirstWord, "function") == 0) || (firstWordLen > 0 && szFirstWord[0] == '@')) { if (isFoldingAll) { //if we're folding the whole document (recursivly by lua script) if (functionCount > 0) { levelCurrent--; } else { levelNext++; } functionCount++; } else { //if just folding a small piece (by clicking on the minus sign next to the word) levelCurrent--; } } // end the fold for these words before the current line if (strcmp(szFirstWord, "endif") == 0 || strcmp(szFirstWord, "endfor") == 0) { levelNext--; levelCurrent--; } // end the fold for these words before the current line and Start new fold if (strcmp(szFirstWord, "else") == 0 || strcmp(szFirstWord, "elseif") == 0 ) levelCurrent--; } // Preprocessor and Comment folding int styleNext = GetStyleFirstWord(lineCurrent + 1,styler); // ********************************* // Folding logic for Comment blocks // ********************************* if (foldComment && IsStreamCommentStyle(style)) { // Start of a comment block if (stylePrev != style && IsStreamCommentStyle(styleNext) && styleNext == style) { levelNext++; } // fold till the last line for normal comment lines else if (IsStreamCommentStyle(stylePrev) && styleNext != SCE_POWERPRO_COMMENTLINE && stylePrev == SCE_POWERPRO_COMMENTLINE && style == SCE_POWERPRO_COMMENTLINE) { levelNext--; } // fold till the one but last line for Blockcomment lines else if (IsStreamCommentStyle(stylePrev) && styleNext != SCE_POWERPRO_COMMENTBLOCK && style == SCE_POWERPRO_COMMENTBLOCK) { levelNext--; levelCurrent--; } } int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) styler.SetLevel(lineCurrent, lev); // reset values for the next line lineCurrent++; stylePrev = style; style = styleNext; levelCurrent = levelNext; visibleChars = 0; // if the last characters are ;;+ then don't reset since the line continues on the next line. if (chPrev != '+' && chPrevPrev != ';' && chPrevPrevPrev != ';') { firstWordLen = 0; szDolen = 0; isFirstWordStarted = false; isFirstWordEnded = false; isDoLastWord = false; //blank out first word for (unsigned int i = 0; i < FIRST_WORD_MAX_LEN; i++) szFirstWord[i] = '\0'; } } // save the last processed characters if ((ch > 0) && !isspacechar(ch)) { chPrevPrevPrev = chPrevPrev; chPrevPrev = chPrev; chPrev = ch; } } //close folds on the last line - without this a 'phantom' //fold can appear when an open fold is on the last line //this can occur because functions and labels don't have an explicit end if (lineCurrent >= lastLine) { int lev = 0; lev |= SC_FOLDLEVELWHITEFLAG; styler.SetLevel(lineCurrent, lev); } } static const char * const powerProWordLists[] = { "Keyword list 1", "Keyword list 2", "Keyword list 3", "Keyword list 4", 0, }; static void ColourisePowerProDocWrapper(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { ColourisePowerProDoc(startPos, length, initStyle, keywordlists, styler, false); } LexerModule lmPowerPro(SCLEX_POWERPRO, ColourisePowerProDocWrapper, "powerpro", FoldPowerProDoc, powerProWordLists); |
Added lexers/LexPowerShell.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
// Scintilla source code edit control /** @file LexPowerShell.cxx ** Lexer for PowerShell scripts. **/ // Copyright 2008 by Tim Gerundt <tim@gerundt.de> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // Extended to accept accented characters static inline bool IsAWordChar(int ch) { return ch >= 0x80 || isalnum(ch) || ch == '-' || ch == '_'; } static void ColourisePowerShellDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; WordList &keywords5 = *keywordlists[4]; styler.StartAt(startPos); StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.state == SCE_POWERSHELL_COMMENT) { if (sc.atLineEnd) { sc.SetState(SCE_POWERSHELL_DEFAULT); } } else if (sc.state == SCE_POWERSHELL_COMMENTSTREAM) { if (sc.ch == '>' && sc.chPrev == '#') { sc.ForwardSetState(SCE_POWERSHELL_DEFAULT); } } else if (sc.state == SCE_POWERSHELL_STRING) { // This is a doubles quotes string if (sc.ch == '\"') { sc.ForwardSetState(SCE_POWERSHELL_DEFAULT); } } else if (sc.state == SCE_POWERSHELL_CHARACTER) { // This is a single quote string if (sc.ch == '\'') { sc.ForwardSetState(SCE_POWERSHELL_DEFAULT); } } else if (sc.state == SCE_POWERSHELL_NUMBER) { if (!IsADigit(sc.ch)) { sc.SetState(SCE_POWERSHELL_DEFAULT); } } else if (sc.state == SCE_POWERSHELL_VARIABLE) { if (!IsAWordChar(sc.ch)) { sc.SetState(SCE_POWERSHELL_DEFAULT); } } else if (sc.state == SCE_POWERSHELL_OPERATOR) { if (!isoperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_POWERSHELL_DEFAULT); } } else if (sc.state == SCE_POWERSHELL_IDENTIFIER) { if (!IsAWordChar(sc.ch)) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (keywords.InList(s)) { sc.ChangeState(SCE_POWERSHELL_KEYWORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_POWERSHELL_CMDLET); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_POWERSHELL_ALIAS); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_POWERSHELL_FUNCTION); } else if (keywords5.InList(s)) { sc.ChangeState(SCE_POWERSHELL_USER1); } sc.SetState(SCE_POWERSHELL_DEFAULT); } } // Determine if a new state should be entered. if (sc.state == SCE_POWERSHELL_DEFAULT) { if (sc.ch == '#') { sc.SetState(SCE_POWERSHELL_COMMENT); } else if (sc.ch == '<' && sc.chNext == '#') { sc.SetState(SCE_POWERSHELL_COMMENTSTREAM); } else if (sc.ch == '\"') { sc.SetState(SCE_POWERSHELL_STRING); } else if (sc.ch == '\'') { sc.SetState(SCE_POWERSHELL_CHARACTER); } else if (sc.ch == '$') { sc.SetState(SCE_POWERSHELL_VARIABLE); } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_POWERSHELL_NUMBER); } else if (isoperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_POWERSHELL_OPERATOR); } else if (IsAWordChar(sc.ch)) { sc.SetState(SCE_POWERSHELL_IDENTIFIER); } } } sc.Complete(); } // Store both the current line's fold level and the next lines in the // level store to make it easy to pick up with each increment // and to make it possible to fiddle the current level for "} else {". static void FoldPowerShellDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelMinCurrent = levelCurrent; int levelNext = levelCurrent; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (style == SCE_POWERSHELL_OPERATOR) { if (ch == '{') { // Measure the minimum before a '{' to allow // folding on "} else {" if (levelMinCurrent > levelNext) { levelMinCurrent = levelNext; } levelNext++; } else if (ch == '}') { levelNext--; } } else if (foldComment && style == SCE_POWERSHELL_COMMENTSTREAM) { if (stylePrev != SCE_POWERSHELL_COMMENTSTREAM) { levelNext++; } else if (styleNext != SCE_POWERSHELL_COMMENTSTREAM) { levelNext--; } } if (!IsASpace(ch)) visibleChars++; if (atEOL || (i == endPos-1)) { int levelUse = levelCurrent; if (foldAtElse) { levelUse = levelMinCurrent; } int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelCurrent = levelNext; levelMinCurrent = levelCurrent; visibleChars = 0; } } } static const char * const powershellWordLists[] = { "Commands", "Cmdlets", "Aliases", "Functions", "User1", 0 }; LexerModule lmPowerShell(SCLEX_POWERSHELL, ColourisePowerShellDoc, "powershell", FoldPowerShellDoc, powershellWordLists); |
Added lexers/LexProgress.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
// Scintilla source code edit control /** @file LexProgress.cxx ** Lexer for Progress 4GL. ** Based on LexCPP.cxx of Neil Hodgson <neilh@scintilla.org> **/ // Copyright 2006-2007 by Yuval Papish <Yuval@YuvCom.com> // The License.txt file describes the conditions under which this software may be distributed. /** TODO: WebSpeed support in html lexer Support "end triggers" expression of the triggers phrase Support more than 6 comments levels **/ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_'); } static inline bool IsAWordStart(int ch) { return (ch < 0x80) && (isalpha(ch) || ch == '_'); } enum SentenceStart { SetSentenceStart = 0xf, ResetSentenceStart = 0x10}; // true -> bit = 0 static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords1 = *keywordlists[0]; // regular keywords WordList &keywords2 = *keywordlists[1]; // block opening keywords, only when SentenceStart WordList &keywords3 = *keywordlists[2]; // block opening keywords //WordList &keywords4 = *keywordlists[3]; // preprocessor keywords. Not implemented int visibleChars = 0; int mask; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.atLineStart) { // Reset states to begining of colourise so no surprises // if different sets of lines lexed. visibleChars = 0; } // Handle line continuation generically. if ((sc.state & 0xf) < SCE_4GL_COMMENT1) { if (sc.ch == '~') { if (sc.chNext > ' ') { // skip special char after ~ sc.Forward(); continue; } else { // Skip whitespace between ~ and EOL while (sc.More() && (sc.chNext == ' ' || sc.chNext == '\t') ) { sc.Forward(); } if (sc.chNext == '\n' || sc.chNext == '\r') { sc.Forward(); if (sc.ch == '\r' && sc.chNext == '\n') { sc.Forward(); } sc.Forward(); continue; } } } } // Determine if a new state should be terminated. mask = sc.state & 0x10; switch (sc.state & 0xf) { case SCE_4GL_OPERATOR: sc.SetState(SCE_4GL_DEFAULT | mask); break; case SCE_4GL_NUMBER: if (!(IsADigit(sc.ch))) { sc.SetState(SCE_4GL_DEFAULT | mask); } break; case SCE_4GL_IDENTIFIER: if (!IsAWordChar(sc.ch) && sc.ch != '-') { char s[1000]; sc.GetCurrentLowered(s, sizeof(s)); if ((((sc.state & 0x10) == 0) && keywords2.InList(s)) || keywords3.InList(s)) { sc.ChangeState(SCE_4GL_BLOCK | ResetSentenceStart); } else if (keywords1.InList(s)) { if ((s[0] == 'e' && s[1] =='n' && s[2] == 'd' && !isalnum(s[3]) && s[3] != '-') || (s[0] == 'f' && s[1] =='o' && s[2] == 'r' && s[3] == 'w' && s[4] =='a' && s[5] == 'r' && s[6] == 'd'&& !isalnum(s[7]))) { sc.ChangeState(SCE_4GL_END | ResetSentenceStart); } else if ((s[0] == 'e' && s[1] =='l' && s[2] == 's' && s[3] == 'e') || (s[0] == 't' && s[1] =='h' && s[2] == 'e' && s[3] == 'n')) { sc.ChangeState(SCE_4GL_WORD & SetSentenceStart); } else { sc.ChangeState(SCE_4GL_WORD | ResetSentenceStart); } } sc.SetState(SCE_4GL_DEFAULT | (sc.state & 0x10)); } break; case SCE_4GL_PREPROCESSOR: if (sc.atLineStart) { sc.SetState(SCE_4GL_DEFAULT & SetSentenceStart); } /* code removed to allow comments inside preprocessor else if (sc.ch == '*' && sc.chNext == '/') { sc.ForwardSetState(SCE_4GL_DEFAULT | sentenceStartState); } */ break; case SCE_4GL_STRING: if (sc.ch == '\"') { sc.ForwardSetState(SCE_4GL_DEFAULT | mask); } break; case SCE_4GL_CHARACTER: if (sc.ch == '\'') { sc.ForwardSetState(SCE_4GL_DEFAULT | mask); } break; default: if ((sc.state & 0xf) >= SCE_4GL_COMMENT1) { if (sc.ch == '*' && sc.chNext == '/') { sc.Forward(); if ((sc.state & 0xf) == SCE_4GL_COMMENT1) { sc.ForwardSetState(SCE_4GL_DEFAULT | mask); } else sc.SetState((sc.state & 0x1f) - 1); } else if (sc.ch == '/' && sc.chNext == '*') { sc.Forward(); sc.SetState((sc.state & 0x1f) + 1); } } } // Determine if a new state should be entered. mask = sc.state & 0x10; if ((sc.state & 0xf) == SCE_4GL_DEFAULT) { if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_4GL_NUMBER | ResetSentenceStart); } else if (IsAWordStart(sc.ch) || (sc.ch == '@')) { sc.SetState(SCE_4GL_IDENTIFIER | mask); } else if (sc.ch == '/' && sc.chNext == '*') { sc.SetState(SCE_4GL_COMMENT1 | mask); sc.Forward(); } else if (sc.ch == '\"') { sc.SetState(SCE_4GL_STRING | ResetSentenceStart); } else if (sc.ch == '\'') { sc.SetState(SCE_4GL_CHARACTER | ResetSentenceStart); } else if (sc.ch == '&' && visibleChars == 0 && ((sc.state & 0x10) == 0)) { sc.SetState(SCE_4GL_PREPROCESSOR | ResetSentenceStart); // Skip whitespace between & and preprocessor word do { sc.Forward(); } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More()); // Handle syntactical line termination } else if ((sc.ch == '.' || sc.ch == ':' || sc.ch == '}') && (sc.chNext == ' ' || sc.chNext == '\t' || sc.chNext == '\n' || sc.chNext == '\r')) { sc.SetState(sc.state & SetSentenceStart); } else if (isoperator(static_cast<char>(sc.ch))) { /* This code allows highlight of handles. Alas, it would cause the phrase "last-event:function" to be recognized as a BlockBegin */ if (sc.ch == ':') sc.SetState(SCE_4GL_OPERATOR & SetSentenceStart); /* else */ sc.SetState(SCE_4GL_OPERATOR | ResetSentenceStart); } } if (!IsASpace(sc.ch)) { visibleChars++; } } sc.Complete(); } static bool IsStreamCommentStyle(int style) { return (style & 0xf) >= SCE_4GL_COMMENT1 ; } // Store both the current line's fold level and the next lines in the // level store to make it easy to pick up with each increment // and to make it possible to fiddle the current level for "} else {". static void FoldNoBox4glDoc(unsigned int startPos, int length, int initStyle, Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelMinCurrent = levelCurrent; int levelNext = levelCurrent; char chNext = static_cast<char>(tolower(styler[startPos])); int styleNext = styler.StyleAt(startPos); int style = initStyle; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1))); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment && IsStreamCommentStyle(style)) { if (!IsStreamCommentStyle(stylePrev)) { levelNext++; } else if (!IsStreamCommentStyle(styleNext)) { // && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelNext--; } } else if ((style & 0xf) == SCE_4GL_BLOCK && !isalnum(chNext)) { levelNext++; } else if ((style & 0xf) == SCE_4GL_END && (ch == 'e' || ch == 'f')) { levelNext--; } if (atEOL) { int levelUse = levelCurrent; if (foldAtElse) { levelUse = levelMinCurrent; } int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelCurrent = levelNext; levelMinCurrent = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } } static void Fold4glDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { FoldNoBox4glDoc(startPos, length, initStyle, styler); } static const char * const FglWordLists[] = { "Primary keywords and identifiers", "Secondary keywords and identifiers", "Documentation comment keywords", "Unused", "Global classes and typedefs", 0, }; LexerModule lmProgress(SCLEX_PROGRESS, Colourise4glDoc, "progress", Fold4glDoc, FglWordLists); |
Added lexers/LexPython.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 |
// Scintilla source code edit control /** @file LexPython.cxx ** Lexer for Python. **/ // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif /* kwCDef, kwCTypeName only used for Cython */ enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName, kwCPDef }; static const int indicatorWhitespace = 1; static bool IsPyComment(Accessor &styler, int pos, int len) { return len > 0 && styler[pos] == '#'; } enum literalsAllowed { litNone=0, litU=1, litB=2}; static bool IsPyStringTypeChar(int ch, literalsAllowed allowed) { return ((allowed & litB) && (ch == 'b' || ch == 'B')) || ((allowed & litU) && (ch == 'u' || ch == 'U')); } static bool IsPyStringStart(int ch, int chNext, int chNext2, literalsAllowed allowed) { if (ch == '\'' || ch == '"') return true; if (IsPyStringTypeChar(ch, allowed)) { if (chNext == '"' || chNext == '\'') return true; if ((chNext == 'r' || chNext == 'R') && (chNext2 == '"' || chNext2 == '\'')) return true; } if ((ch == 'r' || ch == 'R') && (chNext == '"' || chNext == '\'')) return true; return false; } /* Return the state to use for the string starting at i; *nextIndex will be set to the first index following the quote(s) */ static int GetPyStringState(Accessor &styler, int i, unsigned int *nextIndex, literalsAllowed allowed) { char ch = styler.SafeGetCharAt(i); char chNext = styler.SafeGetCharAt(i + 1); // Advance beyond r, u, or ur prefix (or r, b, or br in Python 3.0), but bail if there are any unexpected chars if (ch == 'r' || ch == 'R') { i++; ch = styler.SafeGetCharAt(i); chNext = styler.SafeGetCharAt(i + 1); } else if (IsPyStringTypeChar(ch, allowed)) { if (chNext == 'r' || chNext == 'R') i += 2; else i += 1; ch = styler.SafeGetCharAt(i); chNext = styler.SafeGetCharAt(i + 1); } if (ch != '"' && ch != '\'') { *nextIndex = i + 1; return SCE_P_DEFAULT; } if (ch == chNext && ch == styler.SafeGetCharAt(i + 2)) { *nextIndex = i + 3; if (ch == '"') return SCE_P_TRIPLEDOUBLE; else return SCE_P_TRIPLE; } else { *nextIndex = i + 1; if (ch == '"') return SCE_P_STRING; else return SCE_P_CHARACTER; } } static inline bool IsAWordChar(int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_'); } static inline bool IsAWordStart(int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_'); } static void ColourisePyDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { int endPos = startPos + length; // Backtrack to previous line in case need to fix its tab whinging int lineCurrent = styler.GetLine(startPos); if (startPos > 0) { if (lineCurrent > 0) { lineCurrent--; // Look for backslash-continued lines while (lineCurrent > 0) { int eolPos = styler.LineStart(lineCurrent) - 1; int eolStyle = styler.StyleAt(eolPos); if (eolStyle == SCE_P_STRING || eolStyle == SCE_P_CHARACTER || eolStyle == SCE_P_STRINGEOL) { lineCurrent -= 1; } else { break; } } startPos = styler.LineStart(lineCurrent); } initStyle = startPos == 0 ? SCE_P_DEFAULT : styler.StyleAt(startPos - 1); } WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; // property tab.timmy.whinge.level // For Python code, checks whether indenting is consistent. // The default, 0 turns off indentation checking, // 1 checks whether each line is potentially inconsistent with the previous line, // 2 checks whether any space characters occur before a tab character in the indentation, // 3 checks whether any spaces are in the indentation, and // 4 checks for any tab characters in the indentation. // 1 is a good level to use. const int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level"); // property lexer.python.literals.binary // Set to 0 to not recognise Python 3 binary and octal literals: 0b1011 0o712. bool base2or8Literals = styler.GetPropertyInt("lexer.python.literals.binary", 1) != 0; // property lexer.python.strings.u // Set to 0 to not recognise Python Unicode literals u"x" as used before Python 3. literalsAllowed allowedLiterals = (styler.GetPropertyInt("lexer.python.strings.u", 1)) ? litU : litNone; // property lexer.python.strings.b // Set to 0 to not recognise Python 3 bytes literals b"x". if (styler.GetPropertyInt("lexer.python.strings.b", 1)) allowedLiterals = static_cast<literalsAllowed>(allowedLiterals | litB); // property lexer.python.strings.over.newline // Set to 1 to allow strings to span newline characters. bool stringsOverNewline = styler.GetPropertyInt("lexer.python.strings.over.newline") != 0; // property lexer.python.keywords2.no.sub.identifiers // When enabled, it will not style keywords2 items that are used as a sub-identifier. // Example: when set, will not highlight "foo.open" when "open" is a keywords2 item. const bool keywords2NoSubIdentifiers = styler.GetPropertyInt("lexer.python.keywords2.no.sub.identifiers") != 0; initStyle = initStyle & 31; if (initStyle == SCE_P_STRINGEOL) { initStyle = SCE_P_DEFAULT; } kwType kwLast = kwOther; int spaceFlags = 0; styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment); bool base_n_number = false; StyleContext sc(startPos, endPos - startPos, initStyle, styler); bool indentGood = true; int startIndicator = sc.currentPos; bool inContinuedString = false; for (; sc.More(); sc.Forward()) { if (sc.atLineStart) { styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment); indentGood = true; if (whingeLevel == 1) { indentGood = (spaceFlags & wsInconsistent) == 0; } else if (whingeLevel == 2) { indentGood = (spaceFlags & wsSpaceTab) == 0; } else if (whingeLevel == 3) { indentGood = (spaceFlags & wsSpace) == 0; } else if (whingeLevel == 4) { indentGood = (spaceFlags & wsTab) == 0; } if (!indentGood) { styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0); startIndicator = sc.currentPos; } } if (sc.atLineEnd) { if ((sc.state == SCE_P_DEFAULT) || (sc.state == SCE_P_TRIPLE) || (sc.state == SCE_P_TRIPLEDOUBLE)) { // Perform colourisation of white space and triple quoted strings at end of each line to allow // tab marking to work inside white space and triple quoted strings sc.SetState(sc.state); } lineCurrent++; if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) { if (inContinuedString || stringsOverNewline) { inContinuedString = false; } else { sc.ChangeState(SCE_P_STRINGEOL); sc.ForwardSetState(SCE_P_DEFAULT); } } if (!sc.More()) break; } bool needEOLCheck = false; // Check for a state end if (sc.state == SCE_P_OPERATOR) { kwLast = kwOther; sc.SetState(SCE_P_DEFAULT); } else if (sc.state == SCE_P_NUMBER) { if (!IsAWordChar(sc.ch) && !(!base_n_number && ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) { sc.SetState(SCE_P_DEFAULT); } } else if (sc.state == SCE_P_IDENTIFIER) { if ((sc.ch == '.') || (!IsAWordChar(sc.ch))) { char s[100]; sc.GetCurrent(s, sizeof(s)); int style = SCE_P_IDENTIFIER; if ((kwLast == kwImport) && (strcmp(s, "as") == 0)) { style = SCE_P_WORD; } else if (keywords.InList(s)) { style = SCE_P_WORD; } else if (kwLast == kwClass) { style = SCE_P_CLASSNAME; } else if (kwLast == kwDef) { style = SCE_P_DEFNAME; } else if (kwLast == kwCDef || kwLast == kwCPDef) { int pos = sc.currentPos; unsigned char ch = styler.SafeGetCharAt(pos, '\0'); while (ch != '\0') { if (ch == '(') { style = SCE_P_DEFNAME; break; } else if (ch == ':') { style = SCE_P_CLASSNAME; break; } else if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') { pos++; ch = styler.SafeGetCharAt(pos, '\0'); } else { break; } } } else if (keywords2.InList(s)) { if (keywords2NoSubIdentifiers) { // We don't want to highlight keywords2 // that are used as a sub-identifier, // i.e. not open in "foo.open". int pos = styler.GetStartSegment() - 1; if (pos < 0 || (styler.SafeGetCharAt(pos, '\0') != '.')) style = SCE_P_WORD2; } else { style = SCE_P_WORD2; } } sc.ChangeState(style); sc.SetState(SCE_P_DEFAULT); if (style == SCE_P_WORD) { if (0 == strcmp(s, "class")) kwLast = kwClass; else if (0 == strcmp(s, "def")) kwLast = kwDef; else if (0 == strcmp(s, "import")) kwLast = kwImport; else if (0 == strcmp(s, "cdef")) kwLast = kwCDef; else if (0 == strcmp(s, "cpdef")) kwLast = kwCPDef; else if (0 == strcmp(s, "cimport")) kwLast = kwImport; else if (kwLast != kwCDef && kwLast != kwCPDef) kwLast = kwOther; } else if (kwLast != kwCDef && kwLast != kwCPDef) { kwLast = kwOther; } } } else if ((sc.state == SCE_P_COMMENTLINE) || (sc.state == SCE_P_COMMENTBLOCK)) { if (sc.ch == '\r' || sc.ch == '\n') { sc.SetState(SCE_P_DEFAULT); } } else if (sc.state == SCE_P_DECORATOR) { if (!IsAWordChar(sc.ch)) { sc.SetState(SCE_P_DEFAULT); } } else if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) { if (sc.ch == '\\') { if ((sc.chNext == '\r') && (sc.GetRelative(2) == '\n')) { sc.Forward(); } if (sc.chNext == '\n' || sc.chNext == '\r') { inContinuedString = true; } else { // Don't roll over the newline. sc.Forward(); } } else if ((sc.state == SCE_P_STRING) && (sc.ch == '\"')) { sc.ForwardSetState(SCE_P_DEFAULT); needEOLCheck = true; } else if ((sc.state == SCE_P_CHARACTER) && (sc.ch == '\'')) { sc.ForwardSetState(SCE_P_DEFAULT); needEOLCheck = true; } } else if (sc.state == SCE_P_TRIPLE) { if (sc.ch == '\\') { sc.Forward(); } else if (sc.Match("\'\'\'")) { sc.Forward(); sc.Forward(); sc.ForwardSetState(SCE_P_DEFAULT); needEOLCheck = true; } } else if (sc.state == SCE_P_TRIPLEDOUBLE) { if (sc.ch == '\\') { sc.Forward(); } else if (sc.Match("\"\"\"")) { sc.Forward(); sc.Forward(); sc.ForwardSetState(SCE_P_DEFAULT); needEOLCheck = true; } } if (!indentGood && !IsASpaceOrTab(sc.ch)) { styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 1); startIndicator = sc.currentPos; indentGood = true; } // One cdef or cpdef line, clear kwLast only at end of line if ((kwLast == kwCDef || kwLast == kwCPDef) && sc.atLineEnd) { kwLast = kwOther; } // State exit code may have moved on to end of line if (needEOLCheck && sc.atLineEnd) { lineCurrent++; styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment); if (!sc.More()) break; } // Check for a new state starting character if (sc.state == SCE_P_DEFAULT) { if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { if (sc.ch == '0' && (sc.chNext == 'x' || sc.chNext == 'X')) { base_n_number = true; sc.SetState(SCE_P_NUMBER); } else if (sc.ch == '0' && (sc.chNext == 'o' || sc.chNext == 'O' || sc.chNext == 'b' || sc.chNext == 'B')) { if (base2or8Literals) { base_n_number = true; sc.SetState(SCE_P_NUMBER); } else { sc.SetState(SCE_P_NUMBER); sc.ForwardSetState(SCE_P_IDENTIFIER); } } else { base_n_number = false; sc.SetState(SCE_P_NUMBER); } } else if ((isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) || sc.ch == '`') { sc.SetState(SCE_P_OPERATOR); } else if (sc.ch == '#') { sc.SetState(sc.chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE); } else if (sc.ch == '@') { sc.SetState(SCE_P_DECORATOR); } else if (IsPyStringStart(sc.ch, sc.chNext, sc.GetRelative(2), allowedLiterals)) { unsigned int nextIndex = 0; sc.SetState(GetPyStringState(styler, sc.currentPos, &nextIndex, allowedLiterals)); while (nextIndex > (sc.currentPos + 1) && sc.More()) { sc.Forward(); } } else if (IsAWordStart(sc.ch)) { sc.SetState(SCE_P_IDENTIFIER); } } } styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0); sc.Complete(); } static bool IsCommentLine(int line, Accessor &styler) { int pos = styler.LineStart(line); int eol_pos = styler.LineStart(line + 1) - 1; for (int i = pos; i < eol_pos; i++) { char ch = styler[i]; if (ch == '#') return true; else if (ch != ' ' && ch != '\t') return false; } return false; } static bool IsQuoteLine(int line, Accessor &styler) { int style = styler.StyleAt(styler.LineStart(line)) & 31; return ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE)); } static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unused*/, WordList *[], Accessor &styler) { const int maxPos = startPos + length; const int maxLines = (maxPos == styler.Length()) ? styler.GetLine(maxPos) : styler.GetLine(maxPos - 1); // Requested last line const int docLines = styler.GetLine(styler.Length()); // Available last line // property fold.quotes.python // This option enables folding multi-line quoted strings when using the Python lexer. const bool foldQuotes = styler.GetPropertyInt("fold.quotes.python") != 0; const bool foldCompact = styler.GetPropertyInt("fold.compact") != 0; // Backtrack to previous non-blank line so we can determine indent level // for any white space lines (needed esp. within triple quoted strings) // and so we can fix any preceding fold level (which is why we go back // at least one line in all cases) int spaceFlags = 0; int lineCurrent = styler.GetLine(startPos); int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL); while (lineCurrent > 0) { lineCurrent--; indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL); if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) && (!IsCommentLine(lineCurrent, styler)) && (!IsQuoteLine(lineCurrent, styler))) break; } int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK; // Set up initial loop state startPos = styler.LineStart(lineCurrent); int prev_state = SCE_P_DEFAULT & 31; if (lineCurrent >= 1) prev_state = styler.StyleAt(startPos - 1) & 31; int prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) || (prev_state == SCE_P_TRIPLEDOUBLE)); // Process all characters to end of requested range or end of any triple quote //that hangs over the end of the range. Cap processing in all cases // to end of document (in case of unclosed quote at end). while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevQuote)) { // Gather info int lev = indentCurrent; int lineNext = lineCurrent + 1; int indentNext = indentCurrent; int quote = false; if (lineNext <= docLines) { // Information about next line is only available if not at end of document indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); int lookAtPos = (styler.LineStart(lineNext) == styler.Length()) ? styler.Length() - 1 : styler.LineStart(lineNext); int style = styler.StyleAt(lookAtPos) & 31; quote = foldQuotes && ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE)); } const int quote_start = (quote && !prevQuote); const int quote_continue = (quote && prevQuote); if (!quote || !prevQuote) indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK; if (quote) indentNext = indentCurrentLevel; if (indentNext & SC_FOLDLEVELWHITEFLAG) indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel; if (quote_start) { // Place fold point at start of triple quoted string lev |= SC_FOLDLEVELHEADERFLAG; } else if (quote_continue || prevQuote) { // Add level to rest of lines in the string lev = lev + 1; } // Skip past any blank lines for next indent level info; we skip also // comments (all comments, not just those starting in column 0) // which effectively folds them into surrounding code rather // than screwing up folding. while (!quote && (lineNext < docLines) && ((indentNext & SC_FOLDLEVELWHITEFLAG) || (lineNext <= docLines && IsCommentLine(lineNext, styler)))) { lineNext++; indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); } const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK; const int levelBeforeComments = Maximum(indentCurrentLevel,levelAfterComments); // Now set all the indent levels on the lines we skipped // Do this from end to start. Once we encounter one line // which is indented more than the line after the end of // the comment-block, use the level of the block before int skipLine = lineNext; int skipLevel = levelAfterComments; while (--skipLine > lineCurrent) { int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL); if (foldCompact) { if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments) skipLevel = levelBeforeComments; int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG; styler.SetLevel(skipLine, skipLevel | whiteFlag); } else { if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments && !(skipLineIndent & SC_FOLDLEVELWHITEFLAG) && !IsCommentLine(skipLine, styler)) skipLevel = levelBeforeComments; styler.SetLevel(skipLine, skipLevel); } } // Set fold header on non-quote line if (!quote && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) lev |= SC_FOLDLEVELHEADERFLAG; } // Keep track of triple quote state of previous line prevQuote = quote; // Set fold level for this line and move to next line styler.SetLevel(lineCurrent, foldCompact ? lev : lev & ~SC_FOLDLEVELWHITEFLAG); indentCurrent = indentNext; lineCurrent = lineNext; } // NOTE: Cannot set level of last line here because indentCurrent doesn't have // header flag set; the loop above is crafted to take care of this case! //styler.SetLevel(lineCurrent, indentCurrent); } static const char *const pythonWordListDesc[] = { "Keywords", "Highlighted identifiers", 0 }; LexerModule lmPython(SCLEX_PYTHON, ColourisePyDoc, "python", FoldPyDoc, pythonWordListDesc); |
Added lexers/LexR.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
// Scintilla source code edit control /** @file Lexr.cxx ** Lexer for R, S, SPlus Statistics Program (Heavily derived from CPP Lexer). ** **/ // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_'); } static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_'); } static inline bool IsAnOperator(const int ch) { if (isascii(ch) && isalnum(ch)) return false; // '.' left out as it is used to make up numbers if (ch == '-' || ch == '+' || ch == '!' || ch == '~' || ch == '?' || ch == ':' || ch == '*' || ch == '/' || ch == '^' || ch == '<' || ch == '>' || ch == '=' || ch == '&' || ch == '|' || ch == '$' || ch == '(' || ch == ')' || ch == '}' || ch == '{' || ch == '[' || ch == ']') return true; return false; } static void ColouriseRDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; // Do not leak onto next line if (initStyle == SCE_R_INFIXEOL) initStyle = SCE_R_DEFAULT; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.atLineStart && (sc.state == SCE_R_STRING)) { // Prevent SCE_R_STRINGEOL from leaking back to previous line sc.SetState(SCE_R_STRING); } // Determine if the current state should terminate. if (sc.state == SCE_R_OPERATOR) { sc.SetState(SCE_R_DEFAULT); } else if (sc.state == SCE_R_NUMBER) { if (!IsADigit(sc.ch) && !(sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_R_DEFAULT); } } else if (sc.state == SCE_R_IDENTIFIER) { if (!IsAWordChar(sc.ch)) { char s[100]; sc.GetCurrent(s, sizeof(s)); if (keywords.InList(s)) { sc.ChangeState(SCE_R_KWORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_R_BASEKWORD); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_R_OTHERKWORD); } sc.SetState(SCE_R_DEFAULT); } } else if (sc.state == SCE_R_COMMENT) { if (sc.ch == '\r' || sc.ch == '\n') { sc.SetState(SCE_R_DEFAULT); } } else if (sc.state == SCE_R_STRING) { if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_R_DEFAULT); } } else if (sc.state == SCE_R_INFIX) { if (sc.ch == '%') { sc.ForwardSetState(SCE_R_DEFAULT); } else if (sc.atLineEnd) { sc.ChangeState(SCE_R_INFIXEOL); sc.ForwardSetState(SCE_R_DEFAULT); } }else if (sc.state == SCE_R_STRING2) { if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\'') { sc.ForwardSetState(SCE_R_DEFAULT); } } // Determine if a new state should be entered. if (sc.state == SCE_R_DEFAULT) { if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_R_NUMBER); } else if (IsAWordStart(sc.ch) ) { sc.SetState(SCE_R_IDENTIFIER); } else if (sc.Match('#')) { sc.SetState(SCE_R_COMMENT); } else if (sc.ch == '\"') { sc.SetState(SCE_R_STRING); } else if (sc.ch == '%') { sc.SetState(SCE_R_INFIX); } else if (sc.ch == '\'') { sc.SetState(SCE_R_STRING2); } else if (IsAnOperator(sc.ch)) { sc.SetState(SCE_R_OPERATOR); } } } sc.Complete(); } // Store both the current line's fold level and the next lines in the // level store to make it easy to pick up with each increment // and to make it possible to fiddle the current level for "} else {". static void FoldRDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelMinCurrent = levelCurrent; int levelNext = levelCurrent; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (style == SCE_R_OPERATOR) { if (ch == '{') { // Measure the minimum before a '{' to allow // folding on "} else {" if (levelMinCurrent > levelNext) { levelMinCurrent = levelNext; } levelNext++; } else if (ch == '}') { levelNext--; } } if (atEOL) { int levelUse = levelCurrent; if (foldAtElse) { levelUse = levelMinCurrent; } int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelCurrent = levelNext; levelMinCurrent = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } } static const char * const RWordLists[] = { "Language Keywords", "Base / Default package function", "Other Package Functions", "Unused", "Unused", 0, }; LexerModule lmR(SCLEX_R, ColouriseRDoc, "r", FoldRDoc, RWordLists); |
Added lexers/LexRebol.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
// Scintilla source code edit control /** @file LexRebol.cxx ** Lexer for REBOL. ** Written by Pascal Hurni, inspired from LexLua by Paul Winwood & Marcos E. Wurzius & Philippe Lhoste ** ** History: ** 2005-04-07 First release. ** 2005-04-10 Closing parens and brackets go now in default style ** String and comment nesting should be more safe **/ // Copyright 2005 by Pascal Hurni <pascal_hurni@fastmail.fm> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(const int ch) { return (isalnum(ch) || ch == '?' || ch == '!' || ch == '.' || ch == '\'' || ch == '+' || ch == '-' || ch == '*' || ch == '&' || ch == '|' || ch == '=' || ch == '_' || ch == '~'); } static inline bool IsAWordStart(const int ch, const int ch2) { return ((ch == '+' || ch == '-' || ch == '.') && !isdigit(ch2)) || (isalpha(ch) || ch == '?' || ch == '!' || ch == '\'' || ch == '*' || ch == '&' || ch == '|' || ch == '=' || ch == '_' || ch == '~'); } static inline bool IsAnOperator(const int ch, const int ch2, const int ch3) { // One char operators if (IsASpaceOrTab(ch2)) { return ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '<' || ch == '>' || ch == '=' || ch == '?'; } // Two char operators if (IsASpaceOrTab(ch3)) { return (ch == '*' && ch2 == '*') || (ch == '/' && ch2 == '/') || (ch == '<' && (ch2 == '=' || ch2 == '>')) || (ch == '>' && ch2 == '=') || (ch == '=' && (ch2 == '=' || ch2 == '?')) || (ch == '?' && ch2 == '?'); } return false; } static inline bool IsBinaryStart(const int ch, const int ch2, const int ch3, const int ch4) { return (ch == '#' && ch2 == '{') || (IsADigit(ch) && ch2 == '#' && ch3 == '{' ) || (IsADigit(ch) && IsADigit(ch2) && ch3 == '#' && ch4 == '{' ); } static void ColouriseRebolDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; WordList &keywords5 = *keywordlists[4]; WordList &keywords6 = *keywordlists[5]; WordList &keywords7 = *keywordlists[6]; WordList &keywords8 = *keywordlists[7]; int currentLine = styler.GetLine(startPos); // Initialize the braced string {.. { ... } ..} nesting level, if we are inside such a string. int stringLevel = 0; if (initStyle == SCE_REBOL_BRACEDSTRING || initStyle == SCE_REBOL_COMMENTBLOCK) { stringLevel = styler.GetLineState(currentLine - 1); } bool blockComment = initStyle == SCE_REBOL_COMMENTBLOCK; int dotCount = 0; // Do not leak onto next line if (initStyle == SCE_REBOL_COMMENTLINE) { initStyle = SCE_REBOL_DEFAULT; } StyleContext sc(startPos, length, initStyle, styler); if (startPos == 0) { sc.SetState(SCE_REBOL_PREFACE); } for (; sc.More(); sc.Forward()) { //--- What to do at line end ? if (sc.atLineEnd) { // Can be either inside a {} string or simply at eol if (sc.state != SCE_REBOL_BRACEDSTRING && sc.state != SCE_REBOL_COMMENTBLOCK && sc.state != SCE_REBOL_BINARY && sc.state != SCE_REBOL_PREFACE) sc.SetState(SCE_REBOL_DEFAULT); // Update the line state, so it can be seen by next line currentLine = styler.GetLine(sc.currentPos); switch (sc.state) { case SCE_REBOL_BRACEDSTRING: case SCE_REBOL_COMMENTBLOCK: // Inside a braced string, we set the line state styler.SetLineState(currentLine, stringLevel); break; default: // Reset the line state styler.SetLineState(currentLine, 0); break; } // continue with next char continue; } //--- What to do on white-space ? if (IsASpaceOrTab(sc.ch)) { // Return to default if any of these states if (sc.state == SCE_REBOL_OPERATOR || sc.state == SCE_REBOL_CHARACTER || sc.state == SCE_REBOL_NUMBER || sc.state == SCE_REBOL_PAIR || sc.state == SCE_REBOL_TUPLE || sc.state == SCE_REBOL_FILE || sc.state == SCE_REBOL_DATE || sc.state == SCE_REBOL_TIME || sc.state == SCE_REBOL_MONEY || sc.state == SCE_REBOL_ISSUE || sc.state == SCE_REBOL_URL || sc.state == SCE_REBOL_EMAIL) { sc.SetState(SCE_REBOL_DEFAULT); } } //--- Specialize state ? // URL, Email look like identifier if (sc.state == SCE_REBOL_IDENTIFIER) { if (sc.ch == ':' && !IsASpace(sc.chNext)) { sc.ChangeState(SCE_REBOL_URL); } else if (sc.ch == '@') { sc.ChangeState(SCE_REBOL_EMAIL); } else if (sc.ch == '$') { sc.ChangeState(SCE_REBOL_MONEY); } } // Words look like identifiers if (sc.state == SCE_REBOL_IDENTIFIER || (sc.state >= SCE_REBOL_WORD && sc.state <= SCE_REBOL_WORD8)) { // Keywords ? if (!IsAWordChar(sc.ch) || sc.Match('/')) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); blockComment = strcmp(s, "comment") == 0; if (keywords8.InList(s)) { sc.ChangeState(SCE_REBOL_WORD8); } else if (keywords7.InList(s)) { sc.ChangeState(SCE_REBOL_WORD7); } else if (keywords6.InList(s)) { sc.ChangeState(SCE_REBOL_WORD6); } else if (keywords5.InList(s)) { sc.ChangeState(SCE_REBOL_WORD5); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_REBOL_WORD4); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_REBOL_WORD3); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_REBOL_WORD2); } else if (keywords.InList(s)) { sc.ChangeState(SCE_REBOL_WORD); } // Keep same style if there are refinements if (!sc.Match('/')) { sc.SetState(SCE_REBOL_DEFAULT); } } // special numbers } else if (sc.state == SCE_REBOL_NUMBER) { switch (sc.ch) { case 'x': sc.ChangeState(SCE_REBOL_PAIR); break; case ':': sc.ChangeState(SCE_REBOL_TIME); break; case '-': case '/': sc.ChangeState(SCE_REBOL_DATE); break; case '.': if (++dotCount >= 2) sc.ChangeState(SCE_REBOL_TUPLE); break; } } //--- Determine if the current state should terminate if (sc.state == SCE_REBOL_QUOTEDSTRING || sc.state == SCE_REBOL_CHARACTER) { if (sc.ch == '^' && sc.chNext == '\"') { sc.Forward(); } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_REBOL_DEFAULT); } } else if (sc.state == SCE_REBOL_BRACEDSTRING || sc.state == SCE_REBOL_COMMENTBLOCK) { if (sc.ch == '}') { if (--stringLevel == 0) { sc.ForwardSetState(SCE_REBOL_DEFAULT); } } else if (sc.ch == '{') { stringLevel++; } } else if (sc.state == SCE_REBOL_BINARY) { if (sc.ch == '}') { sc.ForwardSetState(SCE_REBOL_DEFAULT); } } else if (sc.state == SCE_REBOL_TAG) { if (sc.ch == '>') { sc.ForwardSetState(SCE_REBOL_DEFAULT); } } else if (sc.state == SCE_REBOL_PREFACE) { if (sc.MatchIgnoreCase("rebol")) { int i; for (i=5; IsASpaceOrTab(styler.SafeGetCharAt(sc.currentPos+i, 0)); i++); if (sc.GetRelative(i) == '[') sc.SetState(SCE_REBOL_DEFAULT); } } //--- Parens and bracket changes to default style when the current is a number if (sc.state == SCE_REBOL_NUMBER || sc.state == SCE_REBOL_PAIR || sc.state == SCE_REBOL_TUPLE || sc.state == SCE_REBOL_MONEY || sc.state == SCE_REBOL_ISSUE || sc.state == SCE_REBOL_EMAIL || sc.state == SCE_REBOL_URL || sc.state == SCE_REBOL_DATE || sc.state == SCE_REBOL_TIME) { if (sc.ch == '(' || sc.ch == '[' || sc.ch == ')' || sc.ch == ']') { sc.SetState(SCE_REBOL_DEFAULT); } } //--- Determine if a new state should be entered. if (sc.state == SCE_REBOL_DEFAULT) { if (IsAnOperator(sc.ch, sc.chNext, sc.GetRelative(2))) { sc.SetState(SCE_REBOL_OPERATOR); } else if (IsBinaryStart(sc.ch, sc.chNext, sc.GetRelative(2), sc.GetRelative(3))) { sc.SetState(SCE_REBOL_BINARY); } else if (IsAWordStart(sc.ch, sc.chNext)) { sc.SetState(SCE_REBOL_IDENTIFIER); } else if (IsADigit(sc.ch) || sc.ch == '+' || sc.ch == '-' || /*Decimal*/ sc.ch == '.' || sc.ch == ',') { dotCount = 0; sc.SetState(SCE_REBOL_NUMBER); } else if (sc.ch == '\"') { sc.SetState(SCE_REBOL_QUOTEDSTRING); } else if (sc.ch == '{') { sc.SetState(blockComment ? SCE_REBOL_COMMENTBLOCK : SCE_REBOL_BRACEDSTRING); ++stringLevel; } else if (sc.ch == ';') { sc.SetState(SCE_REBOL_COMMENTLINE); } else if (sc.ch == '$') { sc.SetState(SCE_REBOL_MONEY); } else if (sc.ch == '%') { sc.SetState(SCE_REBOL_FILE); } else if (sc.ch == '<') { sc.SetState(SCE_REBOL_TAG); } else if (sc.ch == '#' && sc.chNext == '"') { sc.SetState(SCE_REBOL_CHARACTER); sc.Forward(); } else if (sc.ch == '#' && sc.chNext != '"' && sc.chNext != '{' ) { sc.SetState(SCE_REBOL_ISSUE); } } } sc.Complete(); } static void FoldRebolDoc(unsigned int startPos, int length, int /* initStyle */, WordList *[], Accessor &styler) { unsigned int lengthDoc = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (style == SCE_REBOL_DEFAULT) { if (ch == '[') { levelCurrent++; } else if (ch == ']') { levelCurrent--; } } if (atEOL) { int lev = levelPrev; if (visibleChars == 0) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char * const rebolWordListDesc[] = { "Keywords", 0 }; LexerModule lmREBOL(SCLEX_REBOL, ColouriseRebolDoc, "rebol", FoldRebolDoc, rebolWordListDesc); |
Added lexers/LexRuby.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 |
// Scintilla source code edit control /** @file LexRuby.cxx ** Lexer for Ruby. **/ // Copyright 2001- by Clemens Wyss <wys@helbling.ch> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif //XXX Identical to Perl, put in common area static inline bool isEOLChar(char ch) { return (ch == '\r') || (ch == '\n'); } #define isSafeASCII(ch) ((unsigned int)(ch) <= 127) // This one's redundant, but makes for more readable code #define isHighBitChar(ch) ((unsigned int)(ch) > 127) static inline bool isSafeAlpha(char ch) { return (isSafeASCII(ch) && isalpha(ch)) || ch == '_'; } static inline bool isSafeAlnum(char ch) { return (isSafeASCII(ch) && isalnum(ch)) || ch == '_'; } static inline bool isSafeAlnumOrHigh(char ch) { return isHighBitChar(ch) || isalnum(ch) || ch == '_'; } static inline bool isSafeDigit(char ch) { return isSafeASCII(ch) && isdigit(ch); } static inline bool isSafeWordcharOrHigh(char ch) { // Error: scintilla's KeyWords.h includes '.' as a word-char // we want to separate things that can take methods from the // methods. return isHighBitChar(ch) || isalnum(ch) || ch == '_'; } static bool inline iswhitespace(char ch) { return ch == ' ' || ch == '\t'; } #define MAX_KEYWORD_LENGTH 200 #define STYLE_MASK 63 #define actual_style(style) (style & STYLE_MASK) static bool followsDot(unsigned int pos, Accessor &styler) { styler.Flush(); for (; pos >= 1; --pos) { int style = actual_style(styler.StyleAt(pos)); char ch; switch (style) { case SCE_RB_DEFAULT: ch = styler[pos]; if (ch == ' ' || ch == '\t') { //continue } else { return false; } break; case SCE_RB_OPERATOR: return styler[pos] == '.'; default: return false; } } return false; } // Forward declarations static bool keywordIsAmbiguous(const char *prevWord); static bool keywordDoStartsLoop(int pos, Accessor &styler); static bool keywordIsModifier(const char *word, int pos, Accessor &styler); static int ClassifyWordRb(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) { char s[MAX_KEYWORD_LENGTH]; unsigned int i, j; unsigned int lim = end - start + 1; // num chars to copy if (lim >= MAX_KEYWORD_LENGTH) { lim = MAX_KEYWORD_LENGTH - 1; } for (i = start, j = 0; j < lim; i++, j++) { s[j] = styler[i]; } s[j] = '\0'; int chAttr; if (0 == strcmp(prevWord, "class")) chAttr = SCE_RB_CLASSNAME; else if (0 == strcmp(prevWord, "module")) chAttr = SCE_RB_MODULE_NAME; else if (0 == strcmp(prevWord, "def")) chAttr = SCE_RB_DEFNAME; else if (keywords.InList(s) && !followsDot(start - 1, styler)) { if (keywordIsAmbiguous(s) && keywordIsModifier(s, start, styler)) { // Demoted keywords are colored as keywords, // but do not affect changes in indentation. // // Consider the word 'if': // 1. <<if test ...>> : normal // 2. <<stmt if test>> : demoted // 3. <<lhs = if ...>> : normal: start a new indent level // 4. <<obj.if = 10>> : color as identifer, since it follows '.' chAttr = SCE_RB_WORD_DEMOTED; } else { chAttr = SCE_RB_WORD; } } else chAttr = SCE_RB_IDENTIFIER; styler.ColourTo(end, chAttr); if (chAttr == SCE_RB_WORD) { strcpy(prevWord, s); } else { prevWord[0] = 0; } return chAttr; } //XXX Identical to Perl, put in common area static bool isMatch(Accessor &styler, int lengthDoc, int pos, const char *val) { if ((pos + static_cast<int>(strlen(val))) >= lengthDoc) { return false; } while (*val) { if (*val != styler[pos++]) { return false; } val++; } return true; } // Do Ruby better -- find the end of the line, work back, // and then check for leading white space // Precondition: the here-doc target can be indented static bool lookingAtHereDocDelim(Accessor &styler, int pos, int lengthDoc, const char *HereDocDelim) { if (!isMatch(styler, lengthDoc, pos, HereDocDelim)) { return false; } while (--pos > 0) { char ch = styler[pos]; if (isEOLChar(ch)) { return true; } else if (ch != ' ' && ch != '\t') { return false; } } return false; } //XXX Identical to Perl, put in common area static char opposite(char ch) { if (ch == '(') return ')'; if (ch == '[') return ']'; if (ch == '{') return '}'; if (ch == '<') return '>'; return ch; } // Null transitions when we see we've reached the end // and need to relex the curr char. static void redo_char(int &i, char &ch, char &chNext, char &chNext2, int &state) { i--; chNext2 = chNext; chNext = ch; state = SCE_RB_DEFAULT; } static void advance_char(int &i, char &ch, char &chNext, char &chNext2) { i++; ch = chNext; chNext = chNext2; } // precondition: startPos points to one after the EOL char static bool currLineContainsHereDelims(int& startPos, Accessor &styler) { if (startPos <= 1) return false; int pos; for (pos = startPos - 1; pos > 0; pos--) { char ch = styler.SafeGetCharAt(pos); if (isEOLChar(ch)) { // Leave the pointers where they are -- there are no // here doc delims on the current line, even if // the EOL isn't default style return false; } else { styler.Flush(); if (actual_style(styler.StyleAt(pos)) == SCE_RB_HERE_DELIM) { break; } } } if (pos == 0) { return false; } // Update the pointers so we don't have to re-analyze the string startPos = pos; return true; } // This class is used by the enter and exit methods, so it needs // to be hoisted out of the function. class QuoteCls { public: int Count; char Up; char Down; QuoteCls() { this->New(); } void New() { Count = 0; Up = '\0'; Down = '\0'; } void Open(char u) { Count++; Up = u; Down = opposite(Up); } QuoteCls(const QuoteCls& q) { // copy constructor -- use this for copying in Count = q.Count; Up = q.Up; Down = q.Down; } QuoteCls& operator=(const QuoteCls& q) { // assignment constructor if (this != &q) { Count = q.Count; Up = q.Up; Down = q.Down; } return *this; } }; static void enterInnerExpression(int *p_inner_string_types, int *p_inner_expn_brace_counts, QuoteCls *p_inner_quotes, int& inner_string_count, int& state, int& brace_counts, QuoteCls curr_quote ) { p_inner_string_types[inner_string_count] = state; state = SCE_RB_DEFAULT; p_inner_expn_brace_counts[inner_string_count] = brace_counts; brace_counts = 0; p_inner_quotes[inner_string_count] = curr_quote; ++inner_string_count; } static void exitInnerExpression(int *p_inner_string_types, int *p_inner_expn_brace_counts, QuoteCls *p_inner_quotes, int& inner_string_count, int& state, int& brace_counts, QuoteCls& curr_quote ) { --inner_string_count; state = p_inner_string_types[inner_string_count]; brace_counts = p_inner_expn_brace_counts[inner_string_count]; curr_quote = p_inner_quotes[inner_string_count]; } static bool isEmptyLine(int pos, Accessor &styler) { int spaceFlags = 0; int lineCurrent = styler.GetLine(pos); int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL); return (indentCurrent & SC_FOLDLEVELWHITEFLAG) != 0; } static bool RE_CanFollowKeyword(const char *keyword) { if (!strcmp(keyword, "and") || !strcmp(keyword, "begin") || !strcmp(keyword, "break") || !strcmp(keyword, "case") || !strcmp(keyword, "do") || !strcmp(keyword, "else") || !strcmp(keyword, "elsif") || !strcmp(keyword, "if") || !strcmp(keyword, "next") || !strcmp(keyword, "return") || !strcmp(keyword, "when") || !strcmp(keyword, "unless") || !strcmp(keyword, "until") || !strcmp(keyword, "not") || !strcmp(keyword, "or")) { return true; } return false; } // Look at chars up to but not including endPos // Don't look at styles in case we're looking forward static int skipWhitespace(int startPos, int endPos, Accessor &styler) { for (int i = startPos; i < endPos; i++) { if (!iswhitespace(styler[i])) { return i; } } return endPos; } // This routine looks for false positives like // undef foo, << // There aren't too many. // // iPrev points to the start of << static bool sureThisIsHeredoc(int iPrev, Accessor &styler, char *prevWord) { // Not so fast, since Ruby's so dynamic. Check the context // to make sure we're OK. int prevStyle; int lineStart = styler.GetLine(iPrev); int lineStartPosn = styler.LineStart(lineStart); styler.Flush(); // Find the first word after some whitespace int firstWordPosn = skipWhitespace(lineStartPosn, iPrev, styler); if (firstWordPosn >= iPrev) { // Have something like {^ <<} //XXX Look at the first previous non-comment non-white line // to establish the context. Not too likely though. return true; } else { switch (prevStyle = styler.StyleAt(firstWordPosn)) { case SCE_RB_WORD: case SCE_RB_WORD_DEMOTED: case SCE_RB_IDENTIFIER: break; default: return true; } } int firstWordEndPosn = firstWordPosn; char *dst = prevWord; for (;;) { if (firstWordEndPosn >= iPrev || styler.StyleAt(firstWordEndPosn) != prevStyle) { *dst = 0; break; } *dst++ = styler[firstWordEndPosn]; firstWordEndPosn += 1; } //XXX Write a style-aware thing to regex scintilla buffer objects if (!strcmp(prevWord, "undef") || !strcmp(prevWord, "def") || !strcmp(prevWord, "alias")) { // These keywords are what we were looking for return false; } return true; } // Routine that saves us from allocating a buffer for the here-doc target // targetEndPos points one past the end of the current target static bool haveTargetMatch(int currPos, int lengthDoc, int targetStartPos, int targetEndPos, Accessor &styler) { if (lengthDoc - currPos < targetEndPos - targetStartPos) { return false; } int i, j; for (i = targetStartPos, j = currPos; i < targetEndPos && j < lengthDoc; i++, j++) { if (styler[i] != styler[j]) { return false; } } return true; } // We need a check because the form // [identifier] <<[target] // is ambiguous. The Ruby lexer/parser resolves it by // looking to see if [identifier] names a variable or a // function. If it's the first, it's the start of a here-doc. // If it's a var, it's an operator. This lexer doesn't // maintain a symbol table, so it looks ahead to see what's // going on, in cases where we have // ^[white-space]*[identifier([.|::]identifier)*][white-space]*<<[target] // // If there's no occurrence of [target] on a line, assume we don't. // return true == yes, we have no heredocs static bool sureThisIsNotHeredoc(int lt2StartPos, Accessor &styler) { int prevStyle; // Use full document, not just part we're styling int lengthDoc = styler.Length(); int lineStart = styler.GetLine(lt2StartPos); int lineStartPosn = styler.LineStart(lineStart); styler.Flush(); const bool definitely_not_a_here_doc = true; const bool looks_like_a_here_doc = false; // Find the first word after some whitespace int firstWordPosn = skipWhitespace(lineStartPosn, lt2StartPos, styler); if (firstWordPosn >= lt2StartPos) { return definitely_not_a_here_doc; } prevStyle = styler.StyleAt(firstWordPosn); // If we have '<<' following a keyword, it's not a heredoc if (prevStyle != SCE_RB_IDENTIFIER && prevStyle != SCE_RB_INSTANCE_VAR && prevStyle != SCE_RB_CLASS_VAR) { return definitely_not_a_here_doc; } int newStyle = prevStyle; // Some compilers incorrectly warn about uninit newStyle for (firstWordPosn += 1; firstWordPosn <= lt2StartPos; firstWordPosn += 1) { // Inner loop looks at the name for (; firstWordPosn <= lt2StartPos; firstWordPosn += 1) { newStyle = styler.StyleAt(firstWordPosn); if (newStyle != prevStyle) { break; } } // Do we have '::' or '.'? if (firstWordPosn < lt2StartPos && newStyle == SCE_RB_OPERATOR) { char ch = styler[firstWordPosn]; if (ch == '.') { // yes } else if (ch == ':') { if (styler.StyleAt(++firstWordPosn) != SCE_RB_OPERATOR) { return definitely_not_a_here_doc; } else if (styler[firstWordPosn] != ':') { return definitely_not_a_here_doc; } } else { break; } } else { break; } // on second and next passes, only identifiers may appear since // class and instance variable are private prevStyle = SCE_RB_IDENTIFIER; } // Skip next batch of white-space firstWordPosn = skipWhitespace(firstWordPosn, lt2StartPos, styler); if (firstWordPosn != lt2StartPos) { // Have [[^ws[identifier]ws[*something_else*]ws<< return definitely_not_a_here_doc; } // OK, now 'j' will point to the current spot moving ahead int j = firstWordPosn + 1; if (styler.StyleAt(j) != SCE_RB_OPERATOR || styler[j] != '<') { // This shouldn't happen return definitely_not_a_here_doc; } int nextLineStartPosn = styler.LineStart(lineStart + 1); if (nextLineStartPosn >= lengthDoc) { return definitely_not_a_here_doc; } j = skipWhitespace(j + 1, nextLineStartPosn, styler); if (j >= lengthDoc) { return definitely_not_a_here_doc; } bool allow_indent; int target_start, target_end; // From this point on no more styling, since we're looking ahead if (styler[j] == '-') { allow_indent = true; j++; } else { allow_indent = false; } // Allow for quoted targets. char target_quote = 0; switch (styler[j]) { case '\'': case '"': case '`': target_quote = styler[j]; j += 1; } if (isSafeAlnum(styler[j])) { // Init target_end because some compilers think it won't // be initialized by the time it's used target_start = target_end = j; j++; } else { return definitely_not_a_here_doc; } for (; j < lengthDoc; j++) { if (!isSafeAlnum(styler[j])) { if (target_quote && styler[j] != target_quote) { // unquoted end return definitely_not_a_here_doc; } // And for now make sure that it's a newline // don't handle arbitrary expressions yet target_end = j; if (target_quote) { // Now we can move to the character after the string delimiter. j += 1; } j = skipWhitespace(j, lengthDoc, styler); if (j >= lengthDoc) { return definitely_not_a_here_doc; } else { char ch = styler[j]; if (ch == '#' || isEOLChar(ch)) { // This is OK, so break and continue; break; } else { return definitely_not_a_here_doc; } } } } // Just look at the start of each line int last_line = styler.GetLine(lengthDoc - 1); // But don't go too far if (last_line > lineStart + 50) { last_line = lineStart + 50; } for (int line_num = lineStart + 1; line_num <= last_line; line_num++) { if (allow_indent) { j = skipWhitespace(styler.LineStart(line_num), lengthDoc, styler); } else { j = styler.LineStart(line_num); } // target_end is one past the end if (haveTargetMatch(j, lengthDoc, target_start, target_end, styler)) { // We got it return looks_like_a_here_doc; } } return definitely_not_a_here_doc; } //todo: if we aren't looking at a stdio character, // move to the start of the first line that is not in a // multi-line construct static void synchronizeDocStart(unsigned int& startPos, int &length, int &initStyle, Accessor &styler, bool skipWhiteSpace=false) { styler.Flush(); int style = actual_style(styler.StyleAt(startPos)); switch (style) { case SCE_RB_STDIN: case SCE_RB_STDOUT: case SCE_RB_STDERR: // Don't do anything else with these. return; } int pos = startPos; // Quick way to characterize each line int lineStart; for (lineStart = styler.GetLine(pos); lineStart > 0; lineStart--) { // Now look at the style before the previous line's EOL pos = styler.LineStart(lineStart) - 1; if (pos <= 10) { lineStart = 0; break; } char ch = styler.SafeGetCharAt(pos); char chPrev = styler.SafeGetCharAt(pos - 1); if (ch == '\n' && chPrev == '\r') { pos--; } if (styler.SafeGetCharAt(pos - 1) == '\\') { // Continuation line -- keep going } else if (actual_style(styler.StyleAt(pos)) != SCE_RB_DEFAULT) { // Part of multi-line construct -- keep going } else if (currLineContainsHereDelims(pos, styler)) { // Keep going, with pos and length now pointing // at the end of the here-doc delimiter } else if (skipWhiteSpace && isEmptyLine(pos, styler)) { // Keep going } else { break; } } pos = styler.LineStart(lineStart); length += (startPos - pos); startPos = pos; initStyle = SCE_RB_DEFAULT; } static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { // Lexer for Ruby often has to backtrack to start of current style to determine // which characters are being used as quotes, how deeply nested is the // start position and what the termination string is for here documents WordList &keywords = *keywordlists[0]; class HereDocCls { public: int State; // States // 0: '<<' encountered // 1: collect the delimiter // 1b: text between the end of the delimiter and the EOL // 2: here doc text (lines after the delimiter) char Quote; // the char after '<<' bool Quoted; // true if Quote in ('\'','"','`') int DelimiterLength; // strlen(Delimiter) char Delimiter[256]; // the Delimiter, limit of 256: from Perl bool CanBeIndented; HereDocCls() { State = 0; DelimiterLength = 0; Delimiter[0] = '\0'; CanBeIndented = false; } }; HereDocCls HereDoc; QuoteCls Quote; int numDots = 0; // For numbers -- // Don't start lexing in the middle of a num synchronizeDocStart(startPos, length, initStyle, styler, // ref args false); bool preferRE = true; int state = initStyle; int lengthDoc = startPos + length; char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero prevWord[0] = '\0'; if (length == 0) return; char chPrev = styler.SafeGetCharAt(startPos - 1); char chNext = styler.SafeGetCharAt(startPos); bool is_real_number = true; // Differentiate between constants and ?-sequences. // Ruby uses a different mask because bad indentation is marked by oring with 32 styler.StartAt(startPos, 127); styler.StartSegment(startPos); static int q_states[] = {SCE_RB_STRING_Q, SCE_RB_STRING_QQ, SCE_RB_STRING_QR, SCE_RB_STRING_QW, SCE_RB_STRING_QW, SCE_RB_STRING_QX}; static const char* q_chars = "qQrwWx"; // In most cases a value of 2 should be ample for the code in the // Ruby library, and the code the user is likely to enter. // For example, // fu_output_message "mkdir #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}" // if options[:verbose] // from fileutils.rb nests to a level of 2 // If the user actually hits a 6th occurrence of '#{' in a double-quoted // string (including regex'es, %Q, %<sym>, %w, and other strings // that interpolate), it will stay as a string. The problem with this // is that quotes might flip, a 7th '#{' will look like a comment, // and code-folding might be wrong. // If anyone runs into this problem, I recommend raising this // value slightly higher to replacing the fixed array with a linked // list. Keep in mind this code will be called everytime the lexer // is invoked. #define INNER_STRINGS_MAX_COUNT 5 // These vars track our instances of "...#{,,,%Q<..#{,,,}...>,,,}..." int inner_string_types[INNER_STRINGS_MAX_COUNT]; // Track # braces when we push a new #{ thing int inner_expn_brace_counts[INNER_STRINGS_MAX_COUNT]; QuoteCls inner_quotes[INNER_STRINGS_MAX_COUNT]; int inner_string_count = 0; int brace_counts = 0; // Number of #{ ... } things within an expression int i; for (i = 0; i < INNER_STRINGS_MAX_COUNT; i++) { inner_string_types[i] = 0; inner_expn_brace_counts[i] = 0; } for (i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); char chNext2 = styler.SafeGetCharAt(i + 2); if (styler.IsLeadByte(ch)) { chNext = chNext2; chPrev = ' '; i += 1; continue; } // skip on DOS/Windows //No, don't, because some things will get tagged on, // so we won't recognize keywords, for example #if 0 if (ch == '\r' && chNext == '\n') { continue; } #endif if (HereDoc.State == 1 && isEOLChar(ch)) { // Begin of here-doc (the line after the here-doc delimiter): HereDoc.State = 2; styler.ColourTo(i-1, state); // Don't check for a missing quote, just jump into // the here-doc state state = SCE_RB_HERE_Q; } // Regular transitions if (state == SCE_RB_DEFAULT) { if (isSafeDigit(ch)) { styler.ColourTo(i - 1, state); state = SCE_RB_NUMBER; is_real_number = true; numDots = 0; } else if (isHighBitChar(ch) || iswordstart(ch)) { styler.ColourTo(i - 1, state); state = SCE_RB_WORD; } else if (ch == '#') { styler.ColourTo(i - 1, state); state = SCE_RB_COMMENTLINE; } else if (ch == '=') { // =begin indicates the start of a comment (doc) block if ((i == 0 || isEOLChar(chPrev)) && chNext == 'b' && styler.SafeGetCharAt(i + 2) == 'e' && styler.SafeGetCharAt(i + 3) == 'g' && styler.SafeGetCharAt(i + 4) == 'i' && styler.SafeGetCharAt(i + 5) == 'n' && !isSafeWordcharOrHigh(styler.SafeGetCharAt(i + 6))) { styler.ColourTo(i - 1, state); state = SCE_RB_POD; } else { styler.ColourTo(i - 1, state); styler.ColourTo(i, SCE_RB_OPERATOR); preferRE = true; } } else if (ch == '"') { styler.ColourTo(i - 1, state); state = SCE_RB_STRING; Quote.New(); Quote.Open(ch); } else if (ch == '\'') { styler.ColourTo(i - 1, state); state = SCE_RB_CHARACTER; Quote.New(); Quote.Open(ch); } else if (ch == '`') { styler.ColourTo(i - 1, state); state = SCE_RB_BACKTICKS; Quote.New(); Quote.Open(ch); } else if (ch == '@') { // Instance or class var styler.ColourTo(i - 1, state); if (chNext == '@') { state = SCE_RB_CLASS_VAR; advance_char(i, ch, chNext, chNext2); // pass by ref } else { state = SCE_RB_INSTANCE_VAR; } } else if (ch == '$') { // Check for a builtin global styler.ColourTo(i - 1, state); // Recognize it bit by bit state = SCE_RB_GLOBAL; } else if (ch == '/' && preferRE) { // Ambigous operator styler.ColourTo(i - 1, state); state = SCE_RB_REGEX; Quote.New(); Quote.Open(ch); } else if (ch == '<' && chNext == '<' && chNext2 != '=') { // Recognise the '<<' symbol - either a here document or a binary op styler.ColourTo(i - 1, state); i++; chNext = chNext2; styler.ColourTo(i, SCE_RB_OPERATOR); if (! (strchr("\"\'`_-", chNext2) || isSafeAlpha(chNext2))) { // It's definitely not a here-doc, // based on Ruby's lexer/parser in the // heredoc_identifier routine. // Nothing else to do. } else if (preferRE) { if (sureThisIsHeredoc(i - 1, styler, prevWord)) { state = SCE_RB_HERE_DELIM; HereDoc.State = 0; } // else leave it in default state } else { if (sureThisIsNotHeredoc(i - 1, styler)) { // leave state as default // We don't have all the heuristics Perl has for indications // of a here-doc, because '<<' is overloadable and used // for so many other classes. } else { state = SCE_RB_HERE_DELIM; HereDoc.State = 0; } } preferRE = (state != SCE_RB_HERE_DELIM); } else if (ch == ':') { styler.ColourTo(i - 1, state); if (chNext == ':') { // Mark "::" as an operator, not symbol start styler.ColourTo(i + 1, SCE_RB_OPERATOR); advance_char(i, ch, chNext, chNext2); // pass by ref state = SCE_RB_DEFAULT; preferRE = false; } else if (isSafeWordcharOrHigh(chNext)) { state = SCE_RB_SYMBOL; } else if (strchr("[*!~+-*/%=<>&^|", chNext)) { // Do the operator analysis in-line, looking ahead // Based on the table in pickaxe 2nd ed., page 339 bool doColoring = true; switch (chNext) { case '[': if (chNext2 == ']' ) { char ch_tmp = styler.SafeGetCharAt(i + 3); if (ch_tmp == '=') { i += 3; ch = ch_tmp; chNext = styler.SafeGetCharAt(i + 1); } else { i += 2; ch = chNext2; chNext = ch_tmp; } } else { doColoring = false; } break; case '*': if (chNext2 == '*') { i += 2; ch = chNext2; chNext = styler.SafeGetCharAt(i + 1); } else { advance_char(i, ch, chNext, chNext2); } break; case '!': if (chNext2 == '=' || chNext2 == '~') { i += 2; ch = chNext2; chNext = styler.SafeGetCharAt(i + 1); } else { advance_char(i, ch, chNext, chNext2); } break; case '<': if (chNext2 == '<') { i += 2; ch = chNext2; chNext = styler.SafeGetCharAt(i + 1); } else if (chNext2 == '=') { char ch_tmp = styler.SafeGetCharAt(i + 3); if (ch_tmp == '>') { // <=> operator i += 3; ch = ch_tmp; chNext = styler.SafeGetCharAt(i + 1); } else { i += 2; ch = chNext2; chNext = ch_tmp; } } else { advance_char(i, ch, chNext, chNext2); } break; default: // Simple one-character operators advance_char(i, ch, chNext, chNext2); break; } if (doColoring) { styler.ColourTo(i, SCE_RB_SYMBOL); state = SCE_RB_DEFAULT; } } else if (!preferRE) { // Don't color symbol strings (yet) // Just color the ":" and color rest as string styler.ColourTo(i, SCE_RB_SYMBOL); state = SCE_RB_DEFAULT; } else { styler.ColourTo(i, SCE_RB_OPERATOR); state = SCE_RB_DEFAULT; preferRE = true; } } else if (ch == '%') { styler.ColourTo(i - 1, state); bool have_string = false; if (strchr(q_chars, chNext) && !isSafeWordcharOrHigh(chNext2)) { Quote.New(); const char *hit = strchr(q_chars, chNext); if (hit != NULL) { state = q_states[hit - q_chars]; Quote.Open(chNext2); i += 2; ch = chNext2; chNext = styler.SafeGetCharAt(i + 1); have_string = true; } } else if (preferRE && !isSafeWordcharOrHigh(chNext)) { // Ruby doesn't allow high bit chars here, // but the editor host might Quote.New(); state = SCE_RB_STRING_QQ; Quote.Open(chNext); advance_char(i, ch, chNext, chNext2); // pass by ref have_string = true; } else if (!isSafeWordcharOrHigh(chNext) && !iswhitespace(chNext) && !isEOLChar(chNext)) { // Ruby doesn't allow high bit chars here, // but the editor host might Quote.New(); state = SCE_RB_STRING_QQ; Quote.Open(chNext); advance_char(i, ch, chNext, chNext2); // pass by ref have_string = true; } if (!have_string) { styler.ColourTo(i, SCE_RB_OPERATOR); // stay in default preferRE = true; } } else if (ch == '?') { styler.ColourTo(i - 1, state); if (iswhitespace(chNext) || chNext == '\n' || chNext == '\r') { styler.ColourTo(i, SCE_RB_OPERATOR); } else { // It's the start of a character code escape sequence // Color it as a number. state = SCE_RB_NUMBER; is_real_number = false; } } else if (isoperator(ch) || ch == '.') { styler.ColourTo(i - 1, state); styler.ColourTo(i, SCE_RB_OPERATOR); // If we're ending an expression or block, // assume it ends an object, and the ambivalent // constructs are binary operators // // So if we don't have one of these chars, // we aren't ending an object exp'n, and ops // like : << / are unary operators. if (ch == '{') { ++brace_counts; preferRE = true; } else if (ch == '}' && --brace_counts < 0 && inner_string_count > 0) { styler.ColourTo(i, SCE_RB_OPERATOR); exitInnerExpression(inner_string_types, inner_expn_brace_counts, inner_quotes, inner_string_count, state, brace_counts, Quote); } else { preferRE = (strchr(")}].", ch) == NULL); } // Stay in default state } else if (isEOLChar(ch)) { // Make sure it's a true line-end, with no backslash if ((ch == '\r' || (ch == '\n' && chPrev != '\r')) && chPrev != '\\') { // Assume we've hit the end of the statement. preferRE = true; } } } else if (state == SCE_RB_WORD) { if (ch == '.' || !isSafeWordcharOrHigh(ch)) { // Words include x? in all contexts, // and <letters>= after either 'def' or a dot // Move along until a complete word is on our left // Default accessor treats '.' as word-chars, // but we don't for now. if (ch == '=' && isSafeWordcharOrHigh(chPrev) && (chNext == '(' || strchr(" \t\n\r", chNext) != NULL) && (!strcmp(prevWord, "def") || followsDot(styler.GetStartSegment(), styler))) { // <name>= is a name only when being def'd -- Get it the next time // This means that <name>=<name> is always lexed as // <name>, (op, =), <name> } else if ((ch == '?' || ch == '!') && isSafeWordcharOrHigh(chPrev) && !isSafeWordcharOrHigh(chNext)) { // <name>? is a name -- Get it the next time // But <name>?<name> is always lexed as // <name>, (op, ?), <name> // Same with <name>! to indicate a method that // modifies its target } else if (isEOLChar(ch) && isMatch(styler, lengthDoc, i - 7, "__END__")) { styler.ColourTo(i, SCE_RB_DATASECTION); state = SCE_RB_DATASECTION; // No need to handle this state -- we'll just move to the end preferRE = false; } else { int wordStartPos = styler.GetStartSegment(); int word_style = ClassifyWordRb(wordStartPos, i - 1, keywords, styler, prevWord); switch (word_style) { case SCE_RB_WORD: preferRE = RE_CanFollowKeyword(prevWord); break; case SCE_RB_WORD_DEMOTED: preferRE = true; break; case SCE_RB_IDENTIFIER: if (isMatch(styler, lengthDoc, wordStartPos, "print")) { preferRE = true; } else if (isEOLChar(ch)) { preferRE = true; } else { preferRE = false; } break; default: preferRE = false; } if (ch == '.') { // We might be redefining an operator-method preferRE = false; } // And if it's the first redo_char(i, ch, chNext, chNext2, state); // pass by ref } } } else if (state == SCE_RB_NUMBER) { if (!is_real_number) { if (ch != '\\') { styler.ColourTo(i, state); state = SCE_RB_DEFAULT; preferRE = false; } else if (strchr("\\ntrfvaebs", chNext)) { // Terminal escape sequence -- handle it next time // Nothing more to do this time through the loop } else if (chNext == 'C' || chNext == 'M') { if (chNext2 != '-') { // \C or \M ends the sequence -- handle it next time } else { // Move from abc?\C-x // ^ // to // ^ i += 2; ch = chNext2; chNext = styler.SafeGetCharAt(i + 1); } } else if (chNext == 'c') { // Stay here, \c is a combining sequence advance_char(i, ch, chNext, chNext2); // pass by ref } else { // ?\x, including ?\\ is final. styler.ColourTo(i + 1, state); state = SCE_RB_DEFAULT; preferRE = false; advance_char(i, ch, chNext, chNext2); } } else if (isSafeAlnumOrHigh(ch) || ch == '_') { // Keep going } else if (ch == '.' && chNext == '.') { ++numDots; styler.ColourTo(i - 1, state); redo_char(i, ch, chNext, chNext2, state); // pass by ref } else if (ch == '.' && ++numDots == 1) { // Keep going } else { styler.ColourTo(i - 1, state); redo_char(i, ch, chNext, chNext2, state); // pass by ref preferRE = false; } } else if (state == SCE_RB_COMMENTLINE) { if (isEOLChar(ch)) { styler.ColourTo(i - 1, state); state = SCE_RB_DEFAULT; // Use whatever setting we had going into the comment } } else if (state == SCE_RB_HERE_DELIM) { // See the comment for SCE_RB_HERE_DELIM in LexPerl.cxx // Slightly different: if we find an immediate '-', // the target can appear indented. if (HereDoc.State == 0) { // '<<' encountered HereDoc.State = 1; HereDoc.DelimiterLength = 0; if (ch == '-') { HereDoc.CanBeIndented = true; advance_char(i, ch, chNext, chNext2); // pass by ref } else { HereDoc.CanBeIndented = false; } if (isEOLChar(ch)) { // Bail out of doing a here doc if there's no target state = SCE_RB_DEFAULT; preferRE = false; } else { HereDoc.Quote = ch; if (ch == '\'' || ch == '"' || ch == '`') { HereDoc.Quoted = true; HereDoc.Delimiter[0] = '\0'; } else { HereDoc.Quoted = false; HereDoc.Delimiter[0] = ch; HereDoc.Delimiter[1] = '\0'; HereDoc.DelimiterLength = 1; } } } else if (HereDoc.State == 1) { // collect the delimiter if (isEOLChar(ch)) { // End the quote now, and go back for more styler.ColourTo(i - 1, state); state = SCE_RB_DEFAULT; i--; chNext = ch; preferRE = false; } else if (HereDoc.Quoted) { if (ch == HereDoc.Quote) { // closing quote => end of delimiter styler.ColourTo(i, state); state = SCE_RB_DEFAULT; preferRE = false; } else { if (ch == '\\' && !isEOLChar(chNext)) { advance_char(i, ch, chNext, chNext2); } HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch; HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0'; } } else { // an unquoted here-doc delimiter if (isSafeAlnumOrHigh(ch) || ch == '_') { HereDoc.Delimiter[HereDoc.DelimiterLength++] = ch; HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0'; } else { styler.ColourTo(i - 1, state); redo_char(i, ch, chNext, chNext2, state); preferRE = false; } } if (HereDoc.DelimiterLength >= static_cast<int>(sizeof(HereDoc.Delimiter)) - 1) { styler.ColourTo(i - 1, state); state = SCE_RB_ERROR; preferRE = false; } } } else if (state == SCE_RB_HERE_Q) { // Not needed: HereDoc.State == 2 // Indentable here docs: look backwards // Non-indentable: look forwards, like in Perl // // Why: so we can quickly resolve things like <<-" abc" if (!HereDoc.CanBeIndented) { if (isEOLChar(chPrev) && isMatch(styler, lengthDoc, i, HereDoc.Delimiter)) { styler.ColourTo(i - 1, state); i += HereDoc.DelimiterLength - 1; chNext = styler.SafeGetCharAt(i + 1); if (isEOLChar(chNext)) { styler.ColourTo(i, SCE_RB_HERE_DELIM); state = SCE_RB_DEFAULT; HereDoc.State = 0; preferRE = false; } // Otherwise we skipped through the here doc faster. } } else if (isEOLChar(chNext) && lookingAtHereDocDelim(styler, i - HereDoc.DelimiterLength + 1, lengthDoc, HereDoc.Delimiter)) { styler.ColourTo(i - 1 - HereDoc.DelimiterLength, state); styler.ColourTo(i, SCE_RB_HERE_DELIM); state = SCE_RB_DEFAULT; preferRE = false; HereDoc.State = 0; } } else if (state == SCE_RB_CLASS_VAR || state == SCE_RB_INSTANCE_VAR || state == SCE_RB_SYMBOL) { if (!isSafeWordcharOrHigh(ch)) { styler.ColourTo(i - 1, state); redo_char(i, ch, chNext, chNext2, state); // pass by ref preferRE = false; } } else if (state == SCE_RB_GLOBAL) { if (!isSafeWordcharOrHigh(ch)) { // handle special globals here as well if (chPrev == '$') { if (ch == '-') { // Include the next char, like $-a advance_char(i, ch, chNext, chNext2); } styler.ColourTo(i, state); state = SCE_RB_DEFAULT; } else { styler.ColourTo(i - 1, state); redo_char(i, ch, chNext, chNext2, state); // pass by ref } preferRE = false; } } else if (state == SCE_RB_POD) { // PODs end with ^=end\s, -- any whitespace can follow =end if (strchr(" \t\n\r", ch) != NULL && i > 5 && isEOLChar(styler[i - 5]) && isMatch(styler, lengthDoc, i - 4, "=end")) { styler.ColourTo(i - 1, state); state = SCE_RB_DEFAULT; preferRE = false; } } else if (state == SCE_RB_REGEX || state == SCE_RB_STRING_QR) { if (ch == '\\' && Quote.Up != '\\') { // Skip one advance_char(i, ch, chNext, chNext2); } else if (ch == Quote.Down) { Quote.Count--; if (Quote.Count == 0) { // Include the options while (isSafeAlpha(chNext)) { i++; ch = chNext; chNext = styler.SafeGetCharAt(i + 1); } styler.ColourTo(i, state); state = SCE_RB_DEFAULT; preferRE = false; } } else if (ch == Quote.Up) { // Only if close quoter != open quoter Quote.Count++; } else if (ch == '#' ) { if (chNext == '{' && inner_string_count < INNER_STRINGS_MAX_COUNT) { // process #{ ... } styler.ColourTo(i - 1, state); styler.ColourTo(i + 1, SCE_RB_OPERATOR); enterInnerExpression(inner_string_types, inner_expn_brace_counts, inner_quotes, inner_string_count, state, brace_counts, Quote); preferRE = true; // Skip one advance_char(i, ch, chNext, chNext2); } else { //todo: distinguish comments from pound chars // for now, handle as comment styler.ColourTo(i - 1, state); bool inEscape = false; while (++i < lengthDoc) { ch = styler.SafeGetCharAt(i); if (ch == '\\') { inEscape = true; } else if (isEOLChar(ch)) { // Comment inside a regex styler.ColourTo(i - 1, SCE_RB_COMMENTLINE); break; } else if (inEscape) { inEscape = false; // don't look at char } else if (ch == Quote.Down) { // Have the regular handler deal with this // to get trailing modifiers. i--; ch = styler[i]; break; } } chNext = styler.SafeGetCharAt(i + 1); } } // Quotes of all kinds... } else if (state == SCE_RB_STRING_Q || state == SCE_RB_STRING_QQ || state == SCE_RB_STRING_QX || state == SCE_RB_STRING_QW || state == SCE_RB_STRING || state == SCE_RB_CHARACTER || state == SCE_RB_BACKTICKS) { if (!Quote.Down && !isspacechar(ch)) { Quote.Open(ch); } else if (ch == '\\' && Quote.Up != '\\') { //Riddle me this: Is it safe to skip *every* escaped char? advance_char(i, ch, chNext, chNext2); } else if (ch == Quote.Down) { Quote.Count--; if (Quote.Count == 0) { styler.ColourTo(i, state); state = SCE_RB_DEFAULT; preferRE = false; } } else if (ch == Quote.Up) { Quote.Count++; } else if (ch == '#' && chNext == '{' && inner_string_count < INNER_STRINGS_MAX_COUNT && state != SCE_RB_CHARACTER && state != SCE_RB_STRING_Q) { // process #{ ... } styler.ColourTo(i - 1, state); styler.ColourTo(i + 1, SCE_RB_OPERATOR); enterInnerExpression(inner_string_types, inner_expn_brace_counts, inner_quotes, inner_string_count, state, brace_counts, Quote); preferRE = true; // Skip one advance_char(i, ch, chNext, chNext2); } } if (state == SCE_RB_ERROR) { break; } chPrev = ch; } if (state == SCE_RB_WORD) { // We've ended on a word, possibly at EOF, and need to // classify it. (void) ClassifyWordRb(styler.GetStartSegment(), lengthDoc - 1, keywords, styler, prevWord); } else { styler.ColourTo(lengthDoc - 1, state); } } // Helper functions for folding, disambiguation keywords // Assert that there are no high-bit chars static void getPrevWord(int pos, char *prevWord, Accessor &styler, int word_state) { int i; styler.Flush(); for (i = pos - 1; i > 0; i--) { if (actual_style(styler.StyleAt(i)) != word_state) { i++; break; } } if (i < pos - MAX_KEYWORD_LENGTH) // overflow i = pos - MAX_KEYWORD_LENGTH; char *dst = prevWord; for (; i <= pos; i++) { *dst++ = styler[i]; } *dst = 0; } static bool keywordIsAmbiguous(const char *prevWord) { // Order from most likely used to least likely // Lots of ways to do a loop in Ruby besides 'while/until' if (!strcmp(prevWord, "if") || !strcmp(prevWord, "do") || !strcmp(prevWord, "while") || !strcmp(prevWord, "unless") || !strcmp(prevWord, "until") || !strcmp(prevWord, "for")) { return true; } else { return false; } } // Demote keywords in the following conditions: // if, while, unless, until modify a statement // do after a while or until, as a noise word (like then after if) static bool keywordIsModifier(const char *word, int pos, Accessor &styler) { if (word[0] == 'd' && word[1] == 'o' && !word[2]) { return keywordDoStartsLoop(pos, styler); } char ch, chPrev, chPrev2; int style = SCE_RB_DEFAULT; int lineStart = styler.GetLine(pos); int lineStartPosn = styler.LineStart(lineStart); // We want to step backwards until we don't care about the current // position. But first move lineStartPosn back behind any // continuations immediately above word. while (lineStartPosn > 0) { ch = styler[lineStartPosn-1]; if (ch == '\n' || ch == '\r') { chPrev = styler.SafeGetCharAt(lineStartPosn-2); chPrev2 = styler.SafeGetCharAt(lineStartPosn-3); lineStart = styler.GetLine(lineStartPosn-1); // If we find a continuation line, include it in our analysis. if (chPrev == '\\') { lineStartPosn = styler.LineStart(lineStart); } else if (ch == '\n' && chPrev == '\r' && chPrev2 == '\\') { lineStartPosn = styler.LineStart(lineStart); } else { break; } } else { break; } } styler.Flush(); while (--pos >= lineStartPosn) { style = actual_style(styler.StyleAt(pos)); if (style == SCE_RB_DEFAULT) { if (iswhitespace(ch = styler[pos])) { //continue } else if (ch == '\r' || ch == '\n') { // Scintilla's LineStart() and GetLine() routines aren't // platform-independent, so if we have text prepared with // a different system we can't rely on it. // Also, lineStartPosn may have been moved to more than one // line above word's line while pushing past continuations. chPrev = styler.SafeGetCharAt(pos - 1); chPrev2 = styler.SafeGetCharAt(pos - 2); if (chPrev == '\\') { pos-=1; // gloss over the "\\" //continue } else if (ch == '\n' && chPrev == '\r' && chPrev2 == '\\') { pos-=2; // gloss over the "\\\r" //continue } else { return false; } } } else { break; } } if (pos < lineStartPosn) { return false; } // First things where the action is unambiguous switch (style) { case SCE_RB_DEFAULT: case SCE_RB_COMMENTLINE: case SCE_RB_POD: case SCE_RB_CLASSNAME: case SCE_RB_DEFNAME: case SCE_RB_MODULE_NAME: return false; case SCE_RB_OPERATOR: break; case SCE_RB_WORD: // Watch out for uses of 'else if' //XXX: Make a list of other keywords where 'if' isn't a modifier // and can appear legitimately // Formulate this to avoid warnings from most compilers if (strcmp(word, "if") == 0) { char prevWord[MAX_KEYWORD_LENGTH + 1]; getPrevWord(pos, prevWord, styler, SCE_RB_WORD); return strcmp(prevWord, "else") != 0; } return true; default: return true; } // Assume that if the keyword follows an operator, // usually it's a block assignment, like // a << if x then y else z ch = styler[pos]; switch (ch) { case ')': case ']': case '}': return true; default: return false; } } #define WHILE_BACKWARDS "elihw" #define UNTIL_BACKWARDS "litnu" #define FOR_BACKWARDS "rof" // Nothing fancy -- look to see if we follow a while/until somewhere // on the current line static bool keywordDoStartsLoop(int pos, Accessor &styler) { char ch; int style; int lineStart = styler.GetLine(pos); int lineStartPosn = styler.LineStart(lineStart); styler.Flush(); while (--pos >= lineStartPosn) { style = actual_style(styler.StyleAt(pos)); if (style == SCE_RB_DEFAULT) { if ((ch = styler[pos]) == '\r' || ch == '\n') { // Scintilla's LineStart() and GetLine() routines aren't // platform-independent, so if we have text prepared with // a different system we can't rely on it. return false; } } else if (style == SCE_RB_WORD) { // Check for while or until, but write the word in backwards char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero char *dst = prevWord; int wordLen = 0; int start_word; for (start_word = pos; start_word >= lineStartPosn && actual_style(styler.StyleAt(start_word)) == SCE_RB_WORD; start_word--) { if (++wordLen < MAX_KEYWORD_LENGTH) { *dst++ = styler[start_word]; } } *dst = 0; // Did we see our keyword? if (!strcmp(prevWord, WHILE_BACKWARDS) || !strcmp(prevWord, UNTIL_BACKWARDS) || !strcmp(prevWord, FOR_BACKWARDS)) { return true; } // We can move pos to the beginning of the keyword, and then // accept another decrement, as we can never have two contiguous // keywords: // word1 word2 // ^ // <- move to start_word // ^ // <- loop decrement // ^ # pointing to end of word1 is fine pos = start_word; } } return false; } /* * Folding Ruby * * The language is quite complex to analyze without a full parse. * For example, this line shouldn't affect fold level: * * print "hello" if feeling_friendly? * * Neither should this: * * print "hello" \ * if feeling_friendly? * * * But this should: * * if feeling_friendly? #++ * print "hello" \ * print "goodbye" * end #-- * * So we cheat, by actually looking at the existing indentation * levels for each line, and just echoing it back. Like Python. * Then if we get better at it, we'll take braces into consideration, * which always affect folding levels. * How the keywords should work: * No effect: * __FILE__ __LINE__ BEGIN END alias and * defined? false in nil not or self super then * true undef * Always increment: * begin class def do for module when { * * Always decrement: * end } * * Increment if these start a statement * if unless until while -- do nothing if they're modifiers * These end a block if there's no modifier, but don't bother * break next redo retry return yield * * These temporarily de-indent, but re-indent * case else elsif ensure rescue * * This means that the folder reflects indentation rather * than setting it. The language-service updates indentation * when users type return and finishes entering de-denters. * * Later offer to fold POD, here-docs, strings, and blocks of comments */ static void FoldRbDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldComment = styler.GetPropertyInt("fold.comment") != 0; synchronizeDocStart(startPos, length, initStyle, styler, // ref args false); unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = startPos == 0 ? 0 : (styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK & ~SC_FOLDLEVELBASE); int levelCurrent = levelPrev; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int stylePrev = startPos <= 1 ? SCE_RB_DEFAULT : styler.StyleAt(startPos - 1); bool buffer_ends_with_eol = false; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (style == SCE_RB_COMMENTLINE) { if (foldComment && stylePrev != SCE_RB_COMMENTLINE) { if (chNext == '{') { levelCurrent++; } else if (chNext == '}' && levelCurrent > 0) { levelCurrent--; } } } else if (style == SCE_RB_OPERATOR) { if (strchr("[{(", ch)) { levelCurrent++; } else if (strchr(")}]", ch)) { // Don't decrement below 0 if (levelCurrent > 0) levelCurrent--; } } else if (style == SCE_RB_WORD && styleNext != SCE_RB_WORD) { // Look at the keyword on the left and decide what to do char prevWord[MAX_KEYWORD_LENGTH + 1]; // 1 byte for zero prevWord[0] = 0; getPrevWord(i, prevWord, styler, SCE_RB_WORD); if (!strcmp(prevWord, "end")) { // Don't decrement below 0 if (levelCurrent > 0) levelCurrent--; } else if ( !strcmp(prevWord, "if") || !strcmp(prevWord, "def") || !strcmp(prevWord, "class") || !strcmp(prevWord, "module") || !strcmp(prevWord, "begin") || !strcmp(prevWord, "case") || !strcmp(prevWord, "do") || !strcmp(prevWord, "while") || !strcmp(prevWord, "unless") || !strcmp(prevWord, "until") || !strcmp(prevWord, "for") ) { levelCurrent++; } } else if (style == SCE_RB_HERE_DELIM) { if (styler.SafeGetCharAt(i-2) == '<' && styler.SafeGetCharAt(i-1) == '<') { levelCurrent++; } else if (styleNext == SCE_RB_DEFAULT) { levelCurrent--; } } if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; styler.SetLevel(lineCurrent, lev|SC_FOLDLEVELBASE); lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; buffer_ends_with_eol = true; } else if (!isspacechar(ch)) { visibleChars++; buffer_ends_with_eol = false; } stylePrev = style; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later if (!buffer_ends_with_eol) { lineCurrent++; int new_lev = levelCurrent; if (visibleChars == 0 && foldCompact) new_lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) new_lev |= SC_FOLDLEVELHEADERFLAG; levelCurrent = new_lev; } styler.SetLevel(lineCurrent, levelCurrent|SC_FOLDLEVELBASE); } static const char * const rubyWordListDesc[] = { "Keywords", 0 }; LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc, 6); |
Added lexers/LexSML.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
// Scintilla source code edit control /** @file LexSML.cxx ** Lexer for SML. **/ // Copyright 2009 by James Moffatt and Yuzhou Xin // Modified from LexCaml.cxx by Robert Roessler <robertr@rftp.com> Copyright 2005 // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" inline int issml(int c) {return isalnum(c) || c == '_';} inline int issmlf(int c) {return isalpha(c) || c == '_';} inline int issmld(int c) {return isdigit(c) || c == '_';} #ifdef SCI_NAMESPACE using namespace Scintilla; #endif void ColouriseSMLDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { StyleContext sc(startPos, length, initStyle, styler); int nesting = 0; if (sc.state < SCE_SML_STRING) sc.state = SCE_SML_DEFAULT; if (sc.state >= SCE_SML_COMMENT) nesting = (sc.state & 0x0f) - SCE_SML_COMMENT; int chBase = 0, chToken = 0, chLit = 0; WordList& keywords = *keywordlists[0]; WordList& keywords2 = *keywordlists[1]; WordList& keywords3 = *keywordlists[2]; const int useMagic = styler.GetPropertyInt("lexer.caml.magic", 0); while (sc.More()) { int state2 = -1; int chColor = sc.currentPos - 1; bool advance = true; switch (sc.state & 0x0f) { case SCE_SML_DEFAULT: chToken = sc.currentPos; if (issmlf(sc.ch)) state2 = SCE_SML_IDENTIFIER; else if (sc.Match('`') && issmlf(sc.chNext)) state2 = SCE_SML_TAGNAME; else if (sc.Match('#')&&isdigit(sc.chNext)) state2 = SCE_SML_LINENUM; else if (sc.Match('#','\"')){ state2 = SCE_SML_CHAR,chLit = 0; sc.Forward(); } else if (isdigit(sc.ch)) { state2 = SCE_SML_NUMBER, chBase = 10; if (sc.Match('0') && strchr("xX", sc.chNext)) chBase = 16, sc.Forward();} else if (sc.Match('\"')&&sc.chPrev!='#') state2 = SCE_SML_STRING; else if (sc.Match('(', '*')){ state2 = SCE_SML_COMMENT, sc.ch = ' ', sc.Forward();} else if (strchr("!~" "=<>@^+-*/" "()[];,:.#", sc.ch)) state2 = SCE_SML_OPERATOR; break; case SCE_SML_IDENTIFIER: if (!(issml(sc.ch) || sc.Match('\''))) { const int n = sc.currentPos - chToken; if (n < 24) { char t[24]; for (int i = -n; i < 0; i++) t[n + i] = static_cast<char>(sc.GetRelative(i)); t[n] = '\0'; if ((n == 1 && sc.chPrev == '_') || keywords.InList(t)) sc.ChangeState(SCE_SML_KEYWORD); else if (keywords2.InList(t)) sc.ChangeState(SCE_SML_KEYWORD2); else if (keywords3.InList(t)) sc.ChangeState(SCE_SML_KEYWORD3); } state2 = SCE_SML_DEFAULT, advance = false; } break; case SCE_SML_TAGNAME: if (!(issml(sc.ch) || sc.Match('\''))) state2 = SCE_SML_DEFAULT, advance = false; break; case SCE_SML_LINENUM: if (!isdigit(sc.ch)) state2 = SCE_SML_DEFAULT, advance = false; break; case SCE_SML_OPERATOR: { const char* o = 0; if (issml(sc.ch) || isspace(sc.ch) || (o = strchr(")]};,\'\"`#", sc.ch),o) || !strchr("!$%&*+-./:<=>?@^|~", sc.ch)) { if (o && strchr(")]};,", sc.ch)) { if ((sc.Match(')') && sc.chPrev == '(') || (sc.Match(']') && sc.chPrev == '[')) sc.ChangeState(SCE_SML_KEYWORD); chColor++; } else advance = false; state2 = SCE_SML_DEFAULT; } break; } case SCE_SML_NUMBER: if (issmld(sc.ch) || IsADigit(sc.ch, chBase)) break; if ((sc.Match('l') || sc.Match('L') || sc.Match('n')) && (issmld(sc.chPrev) || IsADigit(sc.chPrev, chBase))) break; if (chBase == 10) { if (sc.Match('.') && issmld(sc.chPrev)) break; if ((sc.Match('e') || sc.Match('E')) && (issmld(sc.chPrev) || sc.chPrev == '.')) break; if ((sc.Match('+') || sc.Match('-')) && (sc.chPrev == 'e' || sc.chPrev == 'E')) break; } state2 = SCE_SML_DEFAULT, advance = false; break; case SCE_SML_CHAR: if (sc.Match('\\')) { chLit = 1; if (sc.chPrev == '\\') sc.ch = ' '; } else if ((sc.Match('\"') && sc.chPrev != '\\') || sc.atLineEnd) { state2 = SCE_SML_DEFAULT; chLit = 1; if (sc.Match('\"')) chColor++; else sc.ChangeState(SCE_SML_IDENTIFIER); } else if (chLit < 1 && sc.currentPos - chToken >= 3) sc.ChangeState(SCE_SML_IDENTIFIER), advance = false; break; case SCE_SML_STRING: if (sc.Match('\\') && sc.chPrev == '\\') sc.ch = ' '; else if (sc.Match('\"') && sc.chPrev != '\\') state2 = SCE_SML_DEFAULT, chColor++; break; case SCE_SML_COMMENT: case SCE_SML_COMMENT1: case SCE_SML_COMMENT2: case SCE_SML_COMMENT3: if (sc.Match('(', '*')) state2 = sc.state + 1, chToken = sc.currentPos, sc.ch = ' ', sc.Forward(), nesting++; else if (sc.Match(')') && sc.chPrev == '*') { if (nesting) state2 = (sc.state & 0x0f) - 1, chToken = 0, nesting--; else state2 = SCE_SML_DEFAULT; chColor++; } else if (useMagic && sc.currentPos - chToken == 4 && sc.Match('c') && sc.chPrev == 'r' && sc.GetRelative(-2) == '@') sc.state |= 0x10; break; } if (state2 >= 0) styler.ColourTo(chColor, sc.state), sc.ChangeState(state2); if (advance) sc.Forward(); } sc.Complete(); } void FoldSMLDoc( unsigned int, int, int, WordList *[], Accessor &) { } static const char * const SMLWordListDesc[] = { "Keywords", "Keywords2", "Keywords3", 0 }; LexerModule lmSML(SCLEX_SML, ColouriseSMLDoc, "SML", FoldSMLDoc, SMLWordListDesc); |
Added lexers/LexSQL.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 |
//-*- coding: utf-8 -*- // Scintilla source code edit control /** @file LexSQL.cxx ** Lexer for SQL, including PL/SQL and SQL*Plus. ** Improved by Jérôme LAFORGE <jerome.laforge_AT_gmail_DOT_com> from 2010 to 2012. **/ // Copyright 1998-2012 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include <string> #include <vector> #include <map> #include <algorithm> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #include "OptionSet.h" #include "SparseState.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(int ch, bool sqlAllowDottedWord) { if (!sqlAllowDottedWord) return (ch < 0x80) && (isalnum(ch) || ch == '_'); else return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.'); } static inline bool IsAWordStart(int ch) { return (ch < 0x80) && (isalpha(ch) || ch == '_'); } static inline bool IsADoxygenChar(int ch) { return (islower(ch) || ch == '$' || ch == '@' || ch == '\\' || ch == '&' || ch == '<' || ch == '>' || ch == '#' || ch == '{' || ch == '}' || ch == '[' || ch == ']'); } static inline bool IsANumberChar(int ch) { // Not exactly following number definition (several dots are seen as OK, etc.) // but probably enough in most cases. return (ch < 0x80) && (isdigit(ch) || toupper(ch) == 'E' || ch == '.' || ch == '-' || ch == '+'); } class SQLStates { public : void Set(int lineNumber, unsigned short int sqlStatesLine) { sqlStatement.Set(lineNumber, sqlStatesLine); } unsigned short int IgnoreWhen (unsigned short int sqlStatesLine, bool enable) { if (enable) sqlStatesLine |= MASK_IGNORE_WHEN; else sqlStatesLine &= ~MASK_IGNORE_WHEN; return sqlStatesLine; } unsigned short int IntoCondition (unsigned short int sqlStatesLine, bool enable) { if (enable) sqlStatesLine |= MASK_INTO_CONDITION; else sqlStatesLine &= ~MASK_INTO_CONDITION; return sqlStatesLine; } unsigned short int IntoExceptionBlock (unsigned short int sqlStatesLine, bool enable) { if (enable) sqlStatesLine |= MASK_INTO_EXCEPTION; else sqlStatesLine &= ~MASK_INTO_EXCEPTION; return sqlStatesLine; } unsigned short int IntoDeclareBlock (unsigned short int sqlStatesLine, bool enable) { if (enable) sqlStatesLine |= MASK_INTO_DECLARE; else sqlStatesLine &= ~MASK_INTO_DECLARE; return sqlStatesLine; } unsigned short int IntoMergeStatement (unsigned short int sqlStatesLine, bool enable) { if (enable) sqlStatesLine |= MASK_MERGE_STATEMENT; else sqlStatesLine &= ~MASK_MERGE_STATEMENT; return sqlStatesLine; } unsigned short int CaseMergeWithoutWhenFound (unsigned short int sqlStatesLine, bool found) { if (found) sqlStatesLine |= MASK_CASE_MERGE_WITHOUT_WHEN_FOUND; else sqlStatesLine &= ~MASK_CASE_MERGE_WITHOUT_WHEN_FOUND; return sqlStatesLine; } unsigned short int IntoSelectStatementOrAssignment (unsigned short int sqlStatesLine, bool found) { if (found) sqlStatesLine |= MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT; else sqlStatesLine &= ~MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT; return sqlStatesLine; } unsigned short int BeginCaseBlock (unsigned short int sqlStatesLine) { if ((sqlStatesLine & MASK_NESTED_CASES) < MASK_NESTED_CASES) { sqlStatesLine++; } return sqlStatesLine; } unsigned short int EndCaseBlock (unsigned short int sqlStatesLine) { if ((sqlStatesLine & MASK_NESTED_CASES) > 0) { sqlStatesLine--; } return sqlStatesLine; } bool IsIgnoreWhen (unsigned short int sqlStatesLine) { return (sqlStatesLine & MASK_IGNORE_WHEN) != 0; } bool IsIntoCondition (unsigned short int sqlStatesLine) { return (sqlStatesLine & MASK_INTO_CONDITION) != 0; } bool IsIntoCaseBlock (unsigned short int sqlStatesLine) { return (sqlStatesLine & MASK_NESTED_CASES) != 0; } bool IsIntoExceptionBlock (unsigned short int sqlStatesLine) { return (sqlStatesLine & MASK_INTO_EXCEPTION) != 0; } bool IsIntoSelectStatementOrAssignment (unsigned short int sqlStatesLine) { return (sqlStatesLine & MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT) != 0; } bool IsCaseMergeWithoutWhenFound (unsigned short int sqlStatesLine) { return (sqlStatesLine & MASK_CASE_MERGE_WITHOUT_WHEN_FOUND) != 0; } bool IsIntoDeclareBlock (unsigned short int sqlStatesLine) { return (sqlStatesLine & MASK_INTO_DECLARE) != 0; } bool IsIntoMergeStatement (unsigned short int sqlStatesLine) { return (sqlStatesLine & MASK_MERGE_STATEMENT) != 0; } unsigned short int ForLine(int lineNumber) { return sqlStatement.ValueAt(lineNumber); } SQLStates() {} private : SparseState <unsigned short int> sqlStatement; enum { MASK_NESTED_CASES = 0x01FF, MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT = 0x0200, MASK_CASE_MERGE_WITHOUT_WHEN_FOUND = 0x0400, MASK_MERGE_STATEMENT = 0x0800, MASK_INTO_DECLARE = 0x1000, MASK_INTO_EXCEPTION = 0x2000, MASK_INTO_CONDITION = 0x4000, MASK_IGNORE_WHEN = 0x8000 }; }; // Options used for LexerSQL struct OptionsSQL { bool fold; bool foldAtElse; bool foldComment; bool foldCompact; bool foldOnlyBegin; bool sqlBackticksIdentifier; bool sqlNumbersignComment; bool sqlBackslashEscapes; bool sqlAllowDottedWord; OptionsSQL() { fold = false; foldAtElse = false; foldComment = false; foldCompact = false; foldOnlyBegin = false; sqlBackticksIdentifier = false; sqlNumbersignComment = false; sqlBackslashEscapes = false; sqlAllowDottedWord = false; } }; static const char * const sqlWordListDesc[] = { "Keywords", "Database Objects", "PLDoc", "SQL*Plus", "User Keywords 1", "User Keywords 2", "User Keywords 3", "User Keywords 4", 0 }; struct OptionSetSQL : public OptionSet<OptionsSQL> { OptionSetSQL() { DefineProperty("fold", &OptionsSQL::fold); DefineProperty("fold.sql.at.else", &OptionsSQL::foldAtElse, "This option enables SQL folding on a \"ELSE\" and \"ELSIF\" line of an IF statement."); DefineProperty("fold.comment", &OptionsSQL::foldComment); DefineProperty("fold.compact", &OptionsSQL::foldCompact); DefineProperty("fold.sql.only.begin", &OptionsSQL::foldOnlyBegin); DefineProperty("lexer.sql.backticks.identifier", &OptionsSQL::sqlBackticksIdentifier); DefineProperty("lexer.sql.numbersign.comment", &OptionsSQL::sqlNumbersignComment, "If \"lexer.sql.numbersign.comment\" property is set to 0 a line beginning with '#' will not be a comment."); DefineProperty("sql.backslash.escapes", &OptionsSQL::sqlBackslashEscapes, "Enables backslash as an escape character in SQL."); DefineProperty("lexer.sql.allow.dotted.word", &OptionsSQL::sqlAllowDottedWord, "Set to 1 to colourise recognized words with dots " "(recommended for Oracle PL/SQL objects)."); DefineWordListSets(sqlWordListDesc); } }; class LexerSQL : public ILexer { public : LexerSQL() {} virtual ~LexerSQL() {} int SCI_METHOD Version () const { return lvOriginal; } void SCI_METHOD Release() { delete this; } const char * SCI_METHOD PropertyNames() { return osSQL.PropertyNames(); } int SCI_METHOD PropertyType(const char *name) { return osSQL.PropertyType(name); } const char * SCI_METHOD DescribeProperty(const char *name) { return osSQL.DescribeProperty(name); } int SCI_METHOD PropertySet(const char *key, const char *val) { if (osSQL.PropertySet(&options, key, val)) { return 0; } return -1; } const char * SCI_METHOD DescribeWordListSets() { return osSQL.DescribeWordListSets(); } int SCI_METHOD WordListSet(int n, const char *wl); void SCI_METHOD Lex (unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess); void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess); void * SCI_METHOD PrivateCall(int, void *) { return 0; } static ILexer *LexerFactorySQL() { return new LexerSQL(); } private: bool IsStreamCommentStyle(int style) { return style == SCE_SQL_COMMENT || style == SCE_SQL_COMMENTDOC || style == SCE_SQL_COMMENTDOCKEYWORD || style == SCE_SQL_COMMENTDOCKEYWORDERROR; } bool IsCommentStyle (int style) { switch (style) { case SCE_SQL_COMMENT : case SCE_SQL_COMMENTDOC : case SCE_SQL_COMMENTLINE : case SCE_SQL_COMMENTLINEDOC : case SCE_SQL_COMMENTDOCKEYWORD : case SCE_SQL_COMMENTDOCKEYWORDERROR : return true; default : return false; } } bool IsCommentLine (int line, LexAccessor &styler) { int pos = styler.LineStart(line); int eol_pos = styler.LineStart(line + 1) - 1; for (int i = pos; i + 1 < eol_pos; i++) { int style = styler.StyleAt(i); // MySQL needs -- comments to be followed by space or control char if (style == SCE_SQL_COMMENTLINE && styler.Match(i, "--")) return true; else if (!IsASpaceOrTab(styler[i])) return false; } return false; } OptionsSQL options; OptionSetSQL osSQL; SQLStates sqlStates; WordList keywords1; WordList keywords2; WordList kw_pldoc; WordList kw_sqlplus; WordList kw_user1; WordList kw_user2; WordList kw_user3; WordList kw_user4; }; int SCI_METHOD LexerSQL::WordListSet(int n, const char *wl) { WordList *wordListN = 0; switch (n) { case 0: wordListN = &keywords1; break; case 1: wordListN = &keywords2; break; case 2: wordListN = &kw_pldoc; break; case 3: wordListN = &kw_sqlplus; break; case 4: wordListN = &kw_user1; break; case 5: wordListN = &kw_user2; break; case 6: wordListN = &kw_user3; break; case 7: wordListN = &kw_user4; } int firstModification = -1; if (wordListN) { WordList wlNew; wlNew.Set(wl); if (*wordListN != wlNew) { wordListN->Set(wl); firstModification = 0; } } return firstModification; } void SCI_METHOD LexerSQL::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { LexAccessor styler(pAccess); StyleContext sc(startPos, length, initStyle, styler); int styleBeforeDCKeyword = SCE_SQL_DEFAULT; int offset = 0; for (; sc.More(); sc.Forward(), offset++) { // Determine if the current state should terminate. switch (sc.state) { case SCE_SQL_OPERATOR: sc.SetState(SCE_SQL_DEFAULT); break; case SCE_SQL_NUMBER: // We stop the number definition on non-numerical non-dot non-eE non-sign char if (!IsANumberChar(sc.ch)) { sc.SetState(SCE_SQL_DEFAULT); } break; case SCE_SQL_IDENTIFIER: if (!IsAWordChar(sc.ch, options.sqlAllowDottedWord)) { int nextState = SCE_SQL_DEFAULT; char s[1000]; sc.GetCurrentLowered(s, sizeof(s)); if (keywords1.InList(s)) { sc.ChangeState(SCE_SQL_WORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_SQL_WORD2); } else if (kw_sqlplus.InListAbbreviated(s, '~')) { sc.ChangeState(SCE_SQL_SQLPLUS); if (strncmp(s, "rem", 3) == 0) { nextState = SCE_SQL_SQLPLUS_COMMENT; } else if (strncmp(s, "pro", 3) == 0) { nextState = SCE_SQL_SQLPLUS_PROMPT; } } else if (kw_user1.InList(s)) { sc.ChangeState(SCE_SQL_USER1); } else if (kw_user2.InList(s)) { sc.ChangeState(SCE_SQL_USER2); } else if (kw_user3.InList(s)) { sc.ChangeState(SCE_SQL_USER3); } else if (kw_user4.InList(s)) { sc.ChangeState(SCE_SQL_USER4); } sc.SetState(nextState); } break; case SCE_SQL_QUOTEDIDENTIFIER: if (sc.ch == 0x60) { if (sc.chNext == 0x60) { sc.Forward(); // Ignore it } else { sc.ForwardSetState(SCE_SQL_DEFAULT); } } break; case SCE_SQL_COMMENT: if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_SQL_DEFAULT); } break; case SCE_SQL_COMMENTDOC: if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_SQL_DEFAULT); } else if (sc.ch == '@' || sc.ch == '\\') { // Doxygen support // Verify that we have the conditions to mark a comment-doc-keyword if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) { styleBeforeDCKeyword = SCE_SQL_COMMENTDOC; sc.SetState(SCE_SQL_COMMENTDOCKEYWORD); } } break; case SCE_SQL_COMMENTLINE: case SCE_SQL_COMMENTLINEDOC: case SCE_SQL_SQLPLUS_COMMENT: case SCE_SQL_SQLPLUS_PROMPT: if (sc.atLineStart) { sc.SetState(SCE_SQL_DEFAULT); } break; case SCE_SQL_COMMENTDOCKEYWORD: if ((styleBeforeDCKeyword == SCE_SQL_COMMENTDOC) && sc.Match('*', '/')) { sc.ChangeState(SCE_SQL_COMMENTDOCKEYWORDERROR); sc.Forward(); sc.ForwardSetState(SCE_SQL_DEFAULT); } else if (!IsADoxygenChar(sc.ch)) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (!isspace(sc.ch) || !kw_pldoc.InList(s + 1)) { sc.ChangeState(SCE_SQL_COMMENTDOCKEYWORDERROR); } sc.SetState(styleBeforeDCKeyword); } break; case SCE_SQL_CHARACTER: if (options.sqlBackslashEscapes && sc.ch == '\\') { sc.Forward(); } else if (sc.ch == '\'') { if (sc.chNext == '\"') { sc.Forward(); } else { sc.ForwardSetState(SCE_SQL_DEFAULT); } } break; case SCE_SQL_STRING: if (sc.ch == '\\') { // Escape sequence sc.Forward(); } else if (sc.ch == '\"') { if (sc.chNext == '\"') { sc.Forward(); } else { sc.ForwardSetState(SCE_SQL_DEFAULT); } } break; } // Determine if a new state should be entered. if (sc.state == SCE_SQL_DEFAULT) { if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_SQL_NUMBER); } else if (IsAWordStart(sc.ch)) { sc.SetState(SCE_SQL_IDENTIFIER); } else if (sc.ch == 0x60 && options.sqlBackticksIdentifier) { sc.SetState(SCE_SQL_QUOTEDIDENTIFIER); } else if (sc.Match('/', '*')) { if (sc.Match("/**") || sc.Match("/*!")) { // Support of Doxygen doc. style sc.SetState(SCE_SQL_COMMENTDOC); } else { sc.SetState(SCE_SQL_COMMENT); } sc.Forward(); // Eat the * so it isn't used for the end of the comment } else if (sc.Match('-', '-')) { // MySQL requires a space or control char after -- // http://dev.mysql.com/doc/mysql/en/ansi-diff-comments.html // Perhaps we should enforce that with proper property: //~ } else if (sc.Match("-- ")) { sc.SetState(SCE_SQL_COMMENTLINE); } else if (sc.ch == '#' && options.sqlNumbersignComment) { sc.SetState(SCE_SQL_COMMENTLINEDOC); } else if (sc.ch == '\'') { sc.SetState(SCE_SQL_CHARACTER); } else if (sc.ch == '\"') { sc.SetState(SCE_SQL_STRING); } else if (isoperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_SQL_OPERATOR); } } } sc.Complete(); } void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { if (!options.fold) return; LexAccessor styler(pAccess); unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) { // Backtrack to previous line in case need to fix its fold status for folding block of single-line comments (i.e. '--'). lineCurrent -= 1; startPos = styler.LineStart(lineCurrent); if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16; } int levelNext = levelCurrent; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; bool endFound = false; bool isUnfoldingIgnored = false; // this statementFound flag avoids to fold when the statement is on only one line by ignoring ELSE or ELSIF // eg. "IF condition1 THEN ... ELSIF condition2 THEN ... ELSE ... END IF;" bool statementFound = false; unsigned short int sqlStatesCurrentLine = 0; if (!options.foldOnlyBegin) { sqlStatesCurrentLine = sqlStates.ForLine(lineCurrent); } for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (atEOL || (!IsCommentStyle(style) && ch == ';')) { if (endFound) { //Maybe this is the end of "EXCEPTION" BLOCK (eg. "BEGIN ... EXCEPTION ... END;") sqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, false); } // set endFound and isUnfoldingIgnored to false if EOL is reached or ';' is found endFound = false; isUnfoldingIgnored = false; } if ((!IsCommentStyle(style) && ch == ';')) { if (sqlStates.IsIntoMergeStatement(sqlStatesCurrentLine)) { // This is the end of "MERGE" statement. if (!sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine)) levelNext--; sqlStatesCurrentLine = sqlStates.IntoMergeStatement(sqlStatesCurrentLine, false); levelNext--; } if (sqlStates.IsIntoSelectStatementOrAssignment(sqlStatesCurrentLine)) sqlStatesCurrentLine = sqlStates.IntoSelectStatementOrAssignment(sqlStatesCurrentLine, false); } if (ch == ':' && chNext == '=' && !IsCommentStyle(style)) sqlStatesCurrentLine = sqlStates.IntoSelectStatementOrAssignment(sqlStatesCurrentLine, true); if (options.foldComment && IsStreamCommentStyle(style)) { if (!IsStreamCommentStyle(stylePrev)) { levelNext++; } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelNext--; } } if (options.foldComment && (style == SCE_SQL_COMMENTLINE)) { // MySQL needs -- comments to be followed by space or control char if ((ch == '-') && (chNext == '-')) { char chNext2 = styler.SafeGetCharAt(i + 2); char chNext3 = styler.SafeGetCharAt(i + 3); if (chNext2 == '{' || chNext3 == '{') { levelNext++; } else if (chNext2 == '}' || chNext3 == '}') { levelNext--; } } } // Fold block of single-line comments (i.e. '--'). if (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler)) { if (!IsCommentLine(lineCurrent - 1, styler) && IsCommentLine(lineCurrent + 1, styler)) levelNext++; else if (IsCommentLine(lineCurrent - 1, styler) && !IsCommentLine(lineCurrent + 1, styler)) levelNext--; } if (style == SCE_SQL_OPERATOR) { if (ch == '(') { if (levelCurrent > levelNext) levelCurrent--; levelNext++; } else if (ch == ')') { levelNext--; } else if ((!options.foldOnlyBegin) && ch == ';') { sqlStatesCurrentLine = sqlStates.IgnoreWhen(sqlStatesCurrentLine, false); } } // If new keyword (cannot trigger on elseif or nullif, does less tests) if (style == SCE_SQL_WORD && stylePrev != SCE_SQL_WORD) { const int MAX_KW_LEN = 9; // Maximum length of folding keywords char s[MAX_KW_LEN + 2]; unsigned int j = 0; for (; j < MAX_KW_LEN + 1; j++) { if (!iswordchar(styler[i + j])) { break; } s[j] = static_cast<char>(tolower(styler[i + j])); } if (j == MAX_KW_LEN + 1) { // Keyword too long, don't test it s[0] = '\0'; } else { s[j] = '\0'; } if (!options.foldOnlyBegin && strcmp(s, "select") == 0) { sqlStatesCurrentLine = sqlStates.IntoSelectStatementOrAssignment(sqlStatesCurrentLine, true); } else if (strcmp(s, "if") == 0) { if (endFound) { endFound = false; if (options.foldOnlyBegin && !isUnfoldingIgnored) { // this end isn't for begin block, but for if block ("end if;") // so ignore previous "end" by increment levelNext. levelNext++; } } else { if (!options.foldOnlyBegin) sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true); if (levelCurrent > levelNext) { // doesn't include this line into the folding block // because doesn't hide IF (eg "END; IF") levelCurrent = levelNext; } } } else if (!options.foldOnlyBegin && strcmp(s, "then") == 0 && sqlStates.IsIntoCondition(sqlStatesCurrentLine)) { sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, false); if (!options.foldOnlyBegin) { if (levelCurrent > levelNext) { levelCurrent = levelNext; } if (!statementFound) levelNext++; statementFound = true; } else if (levelCurrent > levelNext) { // doesn't include this line into the folding block // because doesn't hide LOOP or CASE (eg "END; LOOP" or "END; CASE") levelCurrent = levelNext; } } else if (strcmp(s, "loop") == 0 || strcmp(s, "case") == 0) { if (endFound) { endFound = false; if (options.foldOnlyBegin && !isUnfoldingIgnored) { // this end isn't for begin block, but for loop block ("end loop;") or case block ("end case;") // so ignore previous "end" by increment levelNext. levelNext++; } if ((!options.foldOnlyBegin) && strcmp(s, "case") == 0) { sqlStatesCurrentLine = sqlStates.EndCaseBlock(sqlStatesCurrentLine); if (!sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine)) levelNext--; //again for the "end case;" and block when } } else if (!options.foldOnlyBegin) { if (strcmp(s, "case") == 0) { sqlStatesCurrentLine = sqlStates.BeginCaseBlock(sqlStatesCurrentLine); sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, true); } if (levelCurrent > levelNext) levelCurrent = levelNext; if (!statementFound) levelNext++; statementFound = true; } else if (levelCurrent > levelNext) { // doesn't include this line into the folding block // because doesn't hide LOOP or CASE (eg "END; LOOP" or "END; CASE") levelCurrent = levelNext; } } else if ((!options.foldOnlyBegin) && ( // folding for ELSE and ELSIF block only if foldAtElse is set // and IF or CASE aren't on only one line with ELSE or ELSIF (with flag statementFound) options.foldAtElse && !statementFound) && strcmp(s, "elsif") == 0) { sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true); levelCurrent--; levelNext--; } else if ((!options.foldOnlyBegin) && ( // folding for ELSE and ELSIF block only if foldAtElse is set // and IF or CASE aren't on only one line with ELSE or ELSIF (with flag statementFound) options.foldAtElse && !statementFound) && strcmp(s, "else") == 0) { // prevent also ELSE is on the same line (eg. "ELSE ... END IF;") statementFound = true; if (sqlStates.IsIntoCaseBlock(sqlStatesCurrentLine) && sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine)) { sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, false); levelNext++; } else { // we are in same case "} ELSE {" in C language levelCurrent--; } } else if (strcmp(s, "begin") == 0) { levelNext++; sqlStatesCurrentLine = sqlStates.IntoDeclareBlock(sqlStatesCurrentLine, false); } else if ((strcmp(s, "end") == 0) || // SQL Anywhere permits IF ... ELSE ... ENDIF // will only be active if "endif" appears in the // keyword list. (strcmp(s, "endif") == 0)) { endFound = true; levelNext--; if (sqlStates.IsIntoSelectStatementOrAssignment(sqlStatesCurrentLine) && !sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine)) levelNext--; if (levelNext < SC_FOLDLEVELBASE) { levelNext = SC_FOLDLEVELBASE; isUnfoldingIgnored = true; } } else if ((!options.foldOnlyBegin) && strcmp(s, "when") == 0 && !sqlStates.IsIgnoreWhen(sqlStatesCurrentLine) && !sqlStates.IsIntoExceptionBlock(sqlStatesCurrentLine) && ( sqlStates.IsIntoCaseBlock(sqlStatesCurrentLine) || sqlStates.IsIntoMergeStatement(sqlStatesCurrentLine) ) ) { sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true); // Don't foldind when CASE and WHEN are on the same line (with flag statementFound) (eg. "CASE selector WHEN expression1 THEN sequence_of_statements1;\n") // and same way for MERGE statement. if (!statementFound) { if (!sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine)) { levelCurrent--; levelNext--; } sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, false); } } else if ((!options.foldOnlyBegin) && strcmp(s, "exit") == 0) { sqlStatesCurrentLine = sqlStates.IgnoreWhen(sqlStatesCurrentLine, true); } else if ((!options.foldOnlyBegin) && !sqlStates.IsIntoDeclareBlock(sqlStatesCurrentLine) && strcmp(s, "exception") == 0) { sqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, true); } else if ((!options.foldOnlyBegin) && (strcmp(s, "declare") == 0 || strcmp(s, "function") == 0 || strcmp(s, "procedure") == 0 || strcmp(s, "package") == 0)) { sqlStatesCurrentLine = sqlStates.IntoDeclareBlock(sqlStatesCurrentLine, true); } else if ((!options.foldOnlyBegin) && strcmp(s, "merge") == 0) { sqlStatesCurrentLine = sqlStates.IntoMergeStatement(sqlStatesCurrentLine, true); sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, true); levelNext++; statementFound = true; } } if (atEOL) { int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; if (visibleChars == 0 && options.foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelCurrent = levelNext; visibleChars = 0; statementFound = false; if (!options.foldOnlyBegin) sqlStates.Set(lineCurrent, sqlStatesCurrentLine); } if (!isspacechar(ch)) { visibleChars++; } } } LexerModule lmSQL(SCLEX_SQL, LexerSQL::LexerFactorySQL, "sql", sqlWordListDesc); |
Added lexers/LexScriptol.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 |
// Scintilla source code edit control /** @file LexScriptol.cxx ** Lexer for Scriptol. **/ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static void ClassifyWordSol(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord) { char s[100]; bool wordIsNumber = isdigit(styler[start]) != 0; for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) { s[i] = styler[start + i]; s[i + 1] = '\0'; } char chAttr = SCE_SCRIPTOL_IDENTIFIER; if (0 == strcmp(prevWord, "class")) chAttr = SCE_SCRIPTOL_CLASSNAME; else if (wordIsNumber) chAttr = SCE_SCRIPTOL_NUMBER; else if (keywords.InList(s)) chAttr = SCE_SCRIPTOL_KEYWORD; else for (unsigned int i = 0; i < end - start + 1; i++) // test dotted idents { if (styler[start + i] == '.') { styler.ColourTo(start + i - 1, chAttr); styler.ColourTo(start + i, SCE_SCRIPTOL_OPERATOR); } } styler.ColourTo(end, chAttr); strcpy(prevWord, s); } static bool IsSolComment(Accessor &styler, int pos, int len) { if(len > 0) { char c = styler[pos]; if(c == '`') return true; if(len > 1) { if(c == '/') { c = styler[pos + 1]; if(c == '/') return true; if(c == '*') return true; } } } return false; } static bool IsSolStringStart(char ch) { if (ch == '\'' || ch == '"') return true; return false; } static bool IsSolWordStart(char ch) { return (iswordchar(ch) && !IsSolStringStart(ch)); } static int GetSolStringState(Accessor &styler, int i, int *nextIndex) { char ch = styler.SafeGetCharAt(i); char chNext = styler.SafeGetCharAt(i + 1); if (ch != '\"' && ch != '\'') { *nextIndex = i + 1; return SCE_SCRIPTOL_DEFAULT; } // ch is either single or double quotes in string // code below seem non-sense but is here for future extensions if (ch == chNext && ch == styler.SafeGetCharAt(i + 2)) { *nextIndex = i + 3; if(ch == '\"') return SCE_SCRIPTOL_TRIPLE; if(ch == '\'') return SCE_SCRIPTOL_TRIPLE; return SCE_SCRIPTOL_STRING; } else { *nextIndex = i + 1; if (ch == '"') return SCE_SCRIPTOL_STRING; else return SCE_SCRIPTOL_STRING; } } static void ColouriseSolDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { int lengthDoc = startPos + length; char stringType = '\"'; if (startPos > 0) { int lineCurrent = styler.GetLine(startPos); if (lineCurrent > 0) { startPos = styler.LineStart(lineCurrent-1); if (startPos == 0) initStyle = SCE_SCRIPTOL_DEFAULT; else initStyle = styler.StyleAt(startPos-1); } } styler.StartAt(startPos, 127); WordList &keywords = *keywordlists[0]; int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level"); char prevWord[200]; prevWord[0] = '\0'; if (length == 0) return; int state = initStyle & 31; int nextIndex = 0; char chPrev = ' '; char chPrev2 = ' '; char chNext = styler[startPos]; styler.StartSegment(startPos); bool atStartLine = true; int spaceFlags = 0; for (int i = startPos; i < lengthDoc; i++) { if (atStartLine) { char chBad = static_cast<char>(64); char chGood = static_cast<char>(0); char chFlags = chGood; if (whingeLevel == 1) { chFlags = (spaceFlags & wsInconsistent) ? chBad : chGood; } else if (whingeLevel == 2) { chFlags = (spaceFlags & wsSpaceTab) ? chBad : chGood; } else if (whingeLevel == 3) { chFlags = (spaceFlags & wsSpace) ? chBad : chGood; } else if (whingeLevel == 4) { chFlags = (spaceFlags & wsTab) ? chBad : chGood; } styler.SetFlags(chFlags, static_cast<char>(state)); atStartLine = false; } char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) { if ((state == SCE_SCRIPTOL_DEFAULT) || (state == SCE_SCRIPTOL_TRIPLE) || (state == SCE_SCRIPTOL_COMMENTBLOCK)) { styler.ColourTo(i, state); } atStartLine = true; } if (styler.IsLeadByte(ch)) { chNext = styler.SafeGetCharAt(i + 2); chPrev = ' '; chPrev2 = ' '; i += 1; continue; } if (state == SCE_SCRIPTOL_STRINGEOL) { if (ch != '\r' && ch != '\n') { styler.ColourTo(i - 1, state); state = SCE_SCRIPTOL_DEFAULT; } } if (state == SCE_SCRIPTOL_DEFAULT) { if (IsSolWordStart(ch)) { styler.ColourTo(i - 1, state); state = SCE_SCRIPTOL_KEYWORD; } else if (ch == '`') { styler.ColourTo(i - 1, state); state = SCE_SCRIPTOL_COMMENTLINE; } else if (ch == '/') { styler.ColourTo(i - 1, state); if(chNext == '/') state = SCE_SCRIPTOL_CSTYLE; if(chNext == '*') state = SCE_SCRIPTOL_COMMENTBLOCK; } else if (IsSolStringStart(ch)) { styler.ColourTo(i - 1, state); state = GetSolStringState(styler, i, &nextIndex); if(state == SCE_SCRIPTOL_STRING) { stringType = ch; } if (nextIndex != i + 1) { i = nextIndex - 1; ch = ' '; chPrev = ' '; chNext = styler.SafeGetCharAt(i + 1); } } else if (isoperator(ch)) { styler.ColourTo(i - 1, state); styler.ColourTo(i, SCE_SCRIPTOL_OPERATOR); } } else if (state == SCE_SCRIPTOL_KEYWORD) { if (!iswordchar(ch)) { ClassifyWordSol(styler.GetStartSegment(), i - 1, keywords, styler, prevWord); state = SCE_SCRIPTOL_DEFAULT; if (ch == '`') { state = chNext == '`' ? SCE_SCRIPTOL_PERSISTENT : SCE_SCRIPTOL_COMMENTLINE; } else if (IsSolStringStart(ch)) { styler.ColourTo(i - 1, state); state = GetSolStringState(styler, i, &nextIndex); if (nextIndex != i + 1) { i = nextIndex - 1; ch = ' '; chPrev = ' '; chNext = styler.SafeGetCharAt(i + 1); } } else if (isoperator(ch)) { styler.ColourTo(i, SCE_SCRIPTOL_OPERATOR); } } } else { if (state == SCE_SCRIPTOL_COMMENTLINE || state == SCE_SCRIPTOL_PERSISTENT || state == SCE_SCRIPTOL_CSTYLE) { if (ch == '\r' || ch == '\n') { styler.ColourTo(i - 1, state); state = SCE_SCRIPTOL_DEFAULT; } } else if(state == SCE_SCRIPTOL_COMMENTBLOCK) { if(chPrev == '*' && ch == '/') { styler.ColourTo(i, state); state = SCE_SCRIPTOL_DEFAULT; } } else if ((state == SCE_SCRIPTOL_STRING) || (state == SCE_SCRIPTOL_CHARACTER)) { if ((ch == '\r' || ch == '\n') && (chPrev != '\\')) { styler.ColourTo(i - 1, state); state = SCE_SCRIPTOL_STRINGEOL; } else if (ch == '\\') { if (chNext == '\"' || chNext == '\'' || chNext == '\\') { i++; ch = chNext; chNext = styler.SafeGetCharAt(i + 1); } } else if ((ch == '\"') || (ch == '\'')) { // must match the entered quote type if(ch == stringType) { styler.ColourTo(i, state); state = SCE_SCRIPTOL_DEFAULT; } } } else if (state == SCE_SCRIPTOL_TRIPLE) { if ((ch == '\'' && chPrev == '\'' && chPrev2 == '\'') || (ch == '\"' && chPrev == '\"' && chPrev2 == '\"')) { styler.ColourTo(i, state); state = SCE_SCRIPTOL_DEFAULT; } } } chPrev2 = chPrev; chPrev = ch; } if (state == SCE_SCRIPTOL_KEYWORD) { ClassifyWordSol(styler.GetStartSegment(), lengthDoc-1, keywords, styler, prevWord); } else { styler.ColourTo(lengthDoc-1, state); } } static void FoldSolDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { int lengthDoc = startPos + length; int lineCurrent = styler.GetLine(startPos); if (startPos > 0) { if (lineCurrent > 0) { lineCurrent--; startPos = styler.LineStart(lineCurrent); if (startPos == 0) initStyle = SCE_SCRIPTOL_DEFAULT; else initStyle = styler.StyleAt(startPos-1); } } int state = initStyle & 31; int spaceFlags = 0; int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsSolComment); if (state == SCE_SCRIPTOL_TRIPLE) indentCurrent |= SC_FOLDLEVELWHITEFLAG; char chNext = styler[startPos]; for (int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int style = styler.StyleAt(i) & 31; if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == lengthDoc)) { int lev = indentCurrent; int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsSolComment); if (style == SCE_SCRIPTOL_TRIPLE) indentNext |= SC_FOLDLEVELWHITEFLAG; if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { // Only non whitespace lines can be headers if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) { lev |= SC_FOLDLEVELHEADERFLAG; } else if (indentNext & SC_FOLDLEVELWHITEFLAG) { // Line after is blank so check the next - maybe should continue further? int spaceFlags2 = 0; int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsSolComment); if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) { lev |= SC_FOLDLEVELHEADERFLAG; } } } indentCurrent = indentNext; styler.SetLevel(lineCurrent, lev); lineCurrent++; } } } LexerModule lmScriptol(SCLEX_SCRIPTOL, ColouriseSolDoc, "scriptol", FoldSolDoc); |
Added lexers/LexSmalltalk.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 |
// Scintilla source code edit control /** @file LexSmalltalk.cxx ** Lexer for Smalltalk language. ** Written by Sergey Philippov, sphilippov-at-gmail-dot-com **/ // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif /* | lexTable classificationBlock charClasses | charClasses := #(#DecDigit #Letter #Special #Upper #BinSel). lexTable := ByteArray new: 128. classificationBlock := [ :charClass :chars | | flag | flag := 1 bitShift: (charClasses indexOf: charClass) - 1. chars do: [ :char | lexTable at: char codePoint + 1 put: ((lexTable at: char codePoint + 1) bitOr: flag)]]. classificationBlock value: #DecDigit value: '0123456789'; value: #Letter value: '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; value: #Special value: '()[]{};.^:'; value: #BinSel value: '~@%&*-+=|\/,<>?!'; value: #Upper value: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'. ((String new: 500) streamContents: [ :stream | stream crLf; nextPutAll: 'static int ClassificationTable[256] = {'. lexTable keysAndValuesDo: [ :index :value | ((index - 1) rem: 16) == 0 ifTrue: [ stream crLf; tab] ifFalse: [ stream space]. stream print: value. index ~= 256 ifTrue: [ stream nextPut: $,]]. stream crLf; nextPutAll: '};'; crLf. charClasses keysAndValuesDo: [ :index :name | stream crLf; nextPutAll: ( ('static inline bool is<1s>(int ch) {return (ch > 0) && (ch %< 0x80) && ((ClassificationTable[ch] & <2p>) != 0);}') expandMacrosWith: name with: (1 bitShift: (index - 1))) ]]) edit */ // autogenerated {{{{ static int ClassificationTable[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 16, 0, 4, 4, 16, 16, 16, 16, 4, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 16, 16, 16, 16, 16, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 4, 16, 4, 4, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 16, 4, 16, 0, }; static inline bool isDecDigit(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 1) != 0);} static inline bool isLetter(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 2) != 0);} static inline bool isSpecial(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 4) != 0);} static inline bool isUpper(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 8) != 0);} static inline bool isBinSel(int ch) {return (ch > 0) && (ch < 0x80) && ((ClassificationTable[ch] & 16) != 0);} // autogenerated }}}} static inline bool isAlphaNumeric(int ch) { return isDecDigit(ch) || isLetter(ch); } static inline bool isDigitOfRadix(int ch, int radix) { if (isDecDigit(ch)) return (ch - '0') < radix; else if (!isUpper(ch)) return false; else return (ch - 'A' + 10) < radix; } static inline void skipComment(StyleContext& sc) { while (sc.More() && sc.ch != '\"') sc.Forward(); } static inline void skipString(StyleContext& sc) { while (sc.More()) { if (sc.ch == '\'') { if (sc.chNext != '\'') return; sc.Forward(); } sc.Forward(); } } static void handleHash(StyleContext& sc) { if (isSpecial(sc.chNext)) { sc.SetState(SCE_ST_SPECIAL); return; } sc.SetState(SCE_ST_SYMBOL); sc.Forward(); if (sc.ch == '\'') { sc.Forward(); skipString(sc); } else { if (isLetter(sc.ch)) { while (isAlphaNumeric(sc.chNext) || sc.chNext == ':') sc.Forward(); } else if (isBinSel(sc.ch)) { while (isBinSel(sc.chNext)) sc.Forward(); } } } static inline void handleSpecial(StyleContext& sc) { if (sc.ch == ':' && sc.chNext == '=') { sc.SetState(SCE_ST_ASSIGN); sc.Forward(); } else { if (sc.ch == '^') sc.SetState(SCE_ST_RETURN); else sc.SetState(SCE_ST_SPECIAL); } } static inline void skipInt(StyleContext& sc, int radix) { while (isDigitOfRadix(sc.chNext, radix)) sc.Forward(); } static void handleNumeric(StyleContext& sc) { char num[256]; int nl; int radix; sc.SetState(SCE_ST_NUMBER); num[0] = static_cast<char>(sc.ch); nl = 1; while (isDecDigit(sc.chNext)) { num[nl++] = static_cast<char>(sc.chNext); sc.Forward(); if (nl+1 == sizeof(num)/sizeof(num[0])) // overrun check break; } if (sc.chNext == 'r') { num[nl] = 0; if (num[0] == '-') radix = atoi(num + 1); else radix = atoi(num); sc.Forward(); if (sc.chNext == '-') sc.Forward(); skipInt(sc, radix); } else radix = 10; if (sc.chNext != '.' || !isDigitOfRadix(sc.GetRelative(2), radix)) return; sc.Forward(); skipInt(sc, radix); if (sc.chNext == 's') { // ScaledDecimal sc.Forward(); while (isDecDigit(sc.chNext)) sc.Forward(); return; } else if (sc.chNext != 'e' && sc.chNext != 'd' && sc.chNext != 'q') return; sc.Forward(); if (sc.chNext == '+' || sc.chNext == '-') sc.Forward(); skipInt(sc, radix); } static inline void handleBinSel(StyleContext& sc) { sc.SetState(SCE_ST_BINARY); while (isBinSel(sc.chNext)) sc.Forward(); } static void handleLetter(StyleContext& sc, WordList* specialSelectorList) { char ident[256]; int il; int state; bool doubleColonPresent; sc.SetState(SCE_ST_DEFAULT); ident[0] = static_cast<char>(sc.ch); il = 1; while (isAlphaNumeric(sc.chNext)) { ident[il++] = static_cast<char>(sc.chNext); sc.Forward(); if (il+2 == sizeof(ident)/sizeof(ident[0])) // overrun check break; } if (sc.chNext == ':') { doubleColonPresent = true; ident[il++] = ':'; sc.Forward(); } else doubleColonPresent = false; ident[il] = 0; if (specialSelectorList->InList(ident)) state = SCE_ST_SPEC_SEL; else if (doubleColonPresent) state = SCE_ST_KWSEND; else if (isUpper(ident[0])) state = SCE_ST_GLOBAL; else { if (!strcmp(ident, "self")) state = SCE_ST_SELF; else if (!strcmp(ident, "super")) state = SCE_ST_SUPER; else if (!strcmp(ident, "nil")) state = SCE_ST_NIL; else if (!strcmp(ident, "true") || !strcmp(ident, "false")) state = SCE_ST_BOOL; else state = SCE_ST_DEFAULT; } sc.ChangeState(state); } static void colorizeSmalltalkDoc(unsigned int startPos, int length, int initStyle, WordList *wordLists[], Accessor &styler) { StyleContext sc(startPos, length, initStyle, styler); if (initStyle == SCE_ST_COMMENT) { skipComment(sc); if (sc.More()) sc.Forward(); } else if (initStyle == SCE_ST_STRING) { skipString(sc); if (sc.More()) sc.Forward(); } for (; sc.More(); sc.Forward()) { int ch; ch = sc.ch; if (ch == '\"') { sc.SetState(SCE_ST_COMMENT); sc.Forward(); skipComment(sc); } else if (ch == '\'') { sc.SetState(SCE_ST_STRING); sc.Forward(); skipString(sc); } else if (ch == '#') handleHash(sc); else if (ch == '$') { sc.SetState(SCE_ST_CHARACTER); sc.Forward(); } else if (isSpecial(ch)) handleSpecial(sc); else if (isDecDigit(ch)) handleNumeric(sc); else if (isLetter(ch)) handleLetter(sc, wordLists[0]); else if (isBinSel(ch)) { if (ch == '-' && isDecDigit(sc.chNext)) handleNumeric(sc); else handleBinSel(sc); } else sc.SetState(SCE_ST_DEFAULT); } sc.Complete(); } static const char* const smalltalkWordListDesc[] = { "Special selectors", 0 }; LexerModule lmSmalltalk(SCLEX_SMALLTALK, colorizeSmalltalkDoc, "smalltalk", NULL, smalltalkWordListDesc); |
Added lexers/LexSorcus.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
// Scintilla source code edit control /** @file LexSorcus.cxx ** Lexer for SORCUS installation files ** Written by Eugen Bitter and Christoph Baumann at SORCUS Computer, Heidelberg Germany ** Based on the ASM Lexer by The Black Horus **/ // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif //each character a..z and A..Z + '_' can be part of a keyword //additionally numbers that follow 'M' can be contained in a keyword static inline bool IsSWordStart(const int ch, const int prev_ch) { if (isalpha(ch) || (ch == '_') || ((isdigit(ch)) && (prev_ch == 'M'))) return true; return false; } //only digits that are not preceded by 'M' count as a number static inline bool IsSorcusNumber(const int ch, const int prev_ch) { if ((isdigit(ch)) && (prev_ch != 'M')) return true; return false; } //only = is a valid operator static inline bool IsSorcusOperator(const int ch) { if (ch == '=') return true; return false; } static void ColouriseSorcusDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &Command = *keywordlists[0]; WordList &Parameter = *keywordlists[1]; WordList &Constant = *keywordlists[2]; // Do not leak onto next line if (initStyle == SCE_SORCUS_STRINGEOL) initStyle = SCE_SORCUS_DEFAULT; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { // Prevent SCE_SORCUS_STRINGEOL from leaking back to previous line if (sc.atLineStart && (sc.state == SCE_SORCUS_STRING)) { sc.SetState(SCE_SORCUS_STRING); } // Determine if the current state should terminate. if (sc.state == SCE_SORCUS_OPERATOR) { if (!IsSorcusOperator(sc.ch)) { sc.SetState(SCE_SORCUS_DEFAULT); } } else if(sc.state == SCE_SORCUS_NUMBER) { if(!IsSorcusNumber(sc.ch, sc.chPrev)) { sc.SetState(SCE_SORCUS_DEFAULT); } } else if (sc.state == SCE_SORCUS_IDENTIFIER) { if (!IsSWordStart(sc.ch, sc.chPrev)) { char s[100]; sc.GetCurrent(s, sizeof(s)); if (Command.InList(s)) { sc.ChangeState(SCE_SORCUS_COMMAND); } else if (Parameter.InList(s)) { sc.ChangeState(SCE_SORCUS_PARAMETER); } else if (Constant.InList(s)) { sc.ChangeState(SCE_SORCUS_CONSTANT); } sc.SetState(SCE_SORCUS_DEFAULT); } } else if (sc.state == SCE_SORCUS_COMMENTLINE ) { if (sc.atLineEnd) { sc.SetState(SCE_SORCUS_DEFAULT); } } else if (sc.state == SCE_SORCUS_STRING) { if (sc.ch == '\"') { sc.ForwardSetState(SCE_SORCUS_DEFAULT); } else if (sc.atLineEnd) { sc.ChangeState(SCE_SORCUS_STRINGEOL); sc.ForwardSetState(SCE_SORCUS_DEFAULT); } } // Determine if a new state should be entered. if (sc.state == SCE_SORCUS_DEFAULT) { if ((sc.ch == ';') || (sc.ch == '\'')) { sc.SetState(SCE_SORCUS_COMMENTLINE); } else if (IsSWordStart(sc.ch, sc.chPrev)) { sc.SetState(SCE_SORCUS_IDENTIFIER); } else if (sc.ch == '\"') { sc.SetState(SCE_SORCUS_STRING); } else if (IsSorcusOperator(sc.ch)) { sc.SetState(SCE_SORCUS_OPERATOR); } else if (IsSorcusNumber(sc.ch, sc.chPrev)) { sc.SetState(SCE_SORCUS_NUMBER); } } } sc.Complete(); } static const char* const SorcusWordListDesc[] = {"Command","Parameter", "Constant", 0}; LexerModule lmSorc(SCLEX_SORCUS, ColouriseSorcusDoc, "sorcins", 0, SorcusWordListDesc); |
Added lexers/LexSpecman.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
// Scintilla source code edit control /** @file LexSpecman.cxx ** Lexer for Specman E language. ** Written by Avi Yegudin, based on C++ lexer by Neil Hodgson **/ // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\''); } static inline bool IsANumberChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '\''); } static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '`'); } static void ColouriseSpecmanDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler, bool caseSensitive) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; // Do not leak onto next line if (initStyle == SCE_SN_STRINGEOL) initStyle = SCE_SN_CODE; int visibleChars = 0; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.atLineStart && (sc.state == SCE_SN_STRING)) { // Prevent SCE_SN_STRINGEOL from leaking back to previous line sc.SetState(SCE_SN_STRING); } // Handle line continuation generically. if (sc.ch == '\\') { if (sc.chNext == '\n' || sc.chNext == '\r') { sc.Forward(); if (sc.ch == '\r' && sc.chNext == '\n') { sc.Forward(); } continue; } } // Determine if the current state should terminate. if (sc.state == SCE_SN_OPERATOR) { sc.SetState(SCE_SN_CODE); } else if (sc.state == SCE_SN_NUMBER) { if (!IsANumberChar(sc.ch)) { sc.SetState(SCE_SN_CODE); } } else if (sc.state == SCE_SN_IDENTIFIER) { if (!IsAWordChar(sc.ch) || (sc.ch == '.')) { char s[100]; if (caseSensitive) { sc.GetCurrent(s, sizeof(s)); } else { sc.GetCurrentLowered(s, sizeof(s)); } if (keywords.InList(s)) { sc.ChangeState(SCE_SN_WORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_SN_WORD2); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_SN_WORD3); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_SN_USER); } sc.SetState(SCE_SN_CODE); } } else if (sc.state == SCE_SN_PREPROCESSOR) { if (IsASpace(sc.ch)) { sc.SetState(SCE_SN_CODE); } } else if (sc.state == SCE_SN_DEFAULT) { if (sc.Match('<', '\'')) { sc.Forward(); sc.ForwardSetState(SCE_SN_CODE); } } else if (sc.state == SCE_SN_COMMENTLINE || sc.state == SCE_SN_COMMENTLINEBANG) { if (sc.atLineEnd) { sc.SetState(SCE_SN_CODE); visibleChars = 0; } } else if (sc.state == SCE_SN_STRING) { if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_SN_CODE); } else if (sc.atLineEnd) { sc.ChangeState(SCE_SN_STRINGEOL); sc.ForwardSetState(SCE_SN_CODE); visibleChars = 0; } } else if (sc.state == SCE_SN_SIGNAL) { if (sc.atLineEnd) { sc.ChangeState(SCE_SN_STRINGEOL); sc.ForwardSetState(SCE_SN_CODE); visibleChars = 0; } else if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\'') { sc.ForwardSetState(SCE_SN_CODE); } } else if (sc.state == SCE_SN_REGEXTAG) { if (!IsADigit(sc.ch)) { sc.SetState(SCE_SN_CODE); } } // Determine if a new state should be entered. if (sc.state == SCE_SN_CODE) { if (sc.ch == '$' && IsADigit(sc.chNext)) { sc.SetState(SCE_SN_REGEXTAG); sc.Forward(); } else if (IsADigit(sc.ch)) { sc.SetState(SCE_SN_NUMBER); } else if (IsAWordStart(sc.ch)) { sc.SetState(SCE_SN_IDENTIFIER); } else if (sc.Match('\'', '>')) { sc.SetState(SCE_SN_DEFAULT); sc.Forward(); // Eat the * so it isn't used for the end of the comment } else if (sc.Match('/', '/')) { if (sc.Match("//!")) // Nice to have a different comment style sc.SetState(SCE_SN_COMMENTLINEBANG); else sc.SetState(SCE_SN_COMMENTLINE); } else if (sc.Match('-', '-')) { if (sc.Match("--!")) // Nice to have a different comment style sc.SetState(SCE_SN_COMMENTLINEBANG); else sc.SetState(SCE_SN_COMMENTLINE); } else if (sc.ch == '\"') { sc.SetState(SCE_SN_STRING); } else if (sc.ch == '\'') { sc.SetState(SCE_SN_SIGNAL); } else if (sc.ch == '#' && visibleChars == 0) { // Preprocessor commands are alone on their line sc.SetState(SCE_SN_PREPROCESSOR); // Skip whitespace between # and preprocessor word do { sc.Forward(); } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More()); if (sc.atLineEnd) { sc.SetState(SCE_SN_CODE); } } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@') { sc.SetState(SCE_SN_OPERATOR); } } if (sc.atLineEnd) { // Reset states to begining of colourise so no surprises // if different sets of lines lexed. visibleChars = 0; } if (!IsASpace(sc.ch)) { visibleChars++; } } sc.Complete(); } // Store both the current line's fold level and the next lines in the // level store to make it easy to pick up with each increment // and to make it possible to fiddle the current level for "} else {". static void FoldNoBoxSpecmanDoc(unsigned int startPos, int length, int, Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelMinCurrent = levelCurrent; int levelNext = levelCurrent; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); //int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment && (style == SCE_SN_COMMENTLINE)) { if (((ch == '/') && (chNext == '/')) || ((ch == '-') && (chNext == '-'))) { char chNext2 = styler.SafeGetCharAt(i + 2); if (chNext2 == '{') { levelNext++; } else if (chNext2 == '}') { levelNext--; } } } if (style == SCE_SN_OPERATOR) { if (ch == '{') { // Measure the minimum before a '{' to allow // folding on "} else {" if (levelMinCurrent > levelNext) { levelMinCurrent = levelNext; } levelNext++; } else if (ch == '}') { levelNext--; } } if (atEOL) { int levelUse = levelCurrent; if (foldAtElse) { levelUse = levelMinCurrent; } int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelCurrent = levelNext; levelMinCurrent = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } } static void FoldSpecmanDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { FoldNoBoxSpecmanDoc(startPos, length, initStyle, styler); } static const char * const specmanWordLists[] = { "Primary keywords and identifiers", "Secondary keywords and identifiers", "Sequence keywords and identifiers", "User defined keywords and identifiers", "Unused", 0, }; static void ColouriseSpecmanDocSensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { ColouriseSpecmanDoc(startPos, length, initStyle, keywordlists, styler, true); } LexerModule lmSpecman(SCLEX_SPECMAN, ColouriseSpecmanDocSensitive, "specman", FoldSpecmanDoc, specmanWordLists); |
Added lexers/LexSpice.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
// Scintilla source code edit control /** @file LexSpice.cxx ** Lexer for Spice **/ // Copyright 2006 by Fabien Proriol // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include <string> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif /* * Interface */ static void ColouriseDocument( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler); static const char * const spiceWordListDesc[] = { "Keywords", // SPICE command "Keywords2", // SPICE functions "Keywords3", // SPICE params 0 }; LexerModule lmSpice(SCLEX_SPICE, ColouriseDocument, "spice", NULL, spiceWordListDesc); /* * Implementation */ static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute); static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute); static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute); static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute); static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute); static inline bool IsDelimiterCharacter(int ch); static inline bool IsNumberStartCharacter(int ch); static inline bool IsNumberCharacter(int ch); static inline bool IsSeparatorOrDelimiterCharacter(int ch); static inline bool IsWordStartCharacter(int ch); static inline bool IsWordCharacter(int ch); static void ColouriseComment(StyleContext& sc, bool&) { sc.SetState(SCE_SPICE_COMMENTLINE); while (!sc.atLineEnd) { sc.Forward(); } } static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) { apostropheStartsAttribute = sc.Match (')'); sc.SetState(SCE_SPICE_DELIMITER); sc.ForwardSetState(SCE_SPICE_DEFAULT); } static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) { apostropheStartsAttribute = true; std::string number; sc.SetState(SCE_SPICE_NUMBER); // Get all characters up to a delimiter or a separator, including points, but excluding // double points (ranges). while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) { number += static_cast<char>(sc.ch); sc.Forward(); } // Special case: exponent with sign if ((sc.chPrev == 'e' || sc.chPrev == 'E') && (sc.ch == '+' || sc.ch == '-')) { number += static_cast<char>(sc.ch); sc.Forward (); while (!IsSeparatorOrDelimiterCharacter(sc.ch)) { number += static_cast<char>(sc.ch); sc.Forward(); } } sc.SetState(SCE_SPICE_DEFAULT); } static void ColouriseWhiteSpace(StyleContext& sc, bool& ) { sc.SetState(SCE_SPICE_DEFAULT); sc.ForwardSetState(SCE_SPICE_DEFAULT); } static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute) { apostropheStartsAttribute = true; sc.SetState(SCE_SPICE_IDENTIFIER); std::string word; while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) { word += static_cast<char>(tolower(sc.ch)); sc.Forward(); } if (keywords.InList(word.c_str())) { sc.ChangeState(SCE_SPICE_KEYWORD); if (word != "all") { apostropheStartsAttribute = false; } } else if (keywords2.InList(word.c_str())) { sc.ChangeState(SCE_SPICE_KEYWORD2); if (word != "all") { apostropheStartsAttribute = false; } } else if (keywords3.InList(word.c_str())) { sc.ChangeState(SCE_SPICE_KEYWORD3); if (word != "all") { apostropheStartsAttribute = false; } } sc.SetState(SCE_SPICE_DEFAULT); } // // ColouriseDocument // static void ColouriseDocument( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; StyleContext sc(startPos, length, initStyle, styler); int lineCurrent = styler.GetLine(startPos); bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0; while (sc.More()) { if (sc.atLineEnd) { // Go to the next line sc.Forward(); lineCurrent++; // Remember the line state for future incremental lexing styler.SetLineState(lineCurrent, apostropheStartsAttribute); // Don't continue any styles on the next line sc.SetState(SCE_SPICE_DEFAULT); } // Comments if ((sc.Match('*') && sc.atLineStart) || sc.Match('*','~')) { ColouriseComment(sc, apostropheStartsAttribute); // Whitespace } else if (IsASpace(sc.ch)) { ColouriseWhiteSpace(sc, apostropheStartsAttribute); // Delimiters } else if (IsDelimiterCharacter(sc.ch)) { ColouriseDelimiter(sc, apostropheStartsAttribute); // Numbers } else if (IsADigit(sc.ch) || sc.ch == '#') { ColouriseNumber(sc, apostropheStartsAttribute); // Keywords or identifiers } else { ColouriseWord(sc, keywords, keywords2, keywords3, apostropheStartsAttribute); } } sc.Complete(); } static inline bool IsDelimiterCharacter(int ch) { switch (ch) { case '&': case '\'': case '(': case ')': case '*': case '+': case ',': case '-': case '.': case '/': case ':': case ';': case '<': case '=': case '>': case '|': return true; default: return false; } } static inline bool IsNumberCharacter(int ch) { return IsNumberStartCharacter(ch) || ch == '_' || ch == '.' || ch == '#' || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'); } static inline bool IsNumberStartCharacter(int ch) { return IsADigit(ch); } static inline bool IsSeparatorOrDelimiterCharacter(int ch) { return IsASpace(ch) || IsDelimiterCharacter(ch); } static inline bool IsWordCharacter(int ch) { return IsWordStartCharacter(ch) || IsADigit(ch); } static inline bool IsWordStartCharacter(int ch) { return (isascii(ch) && isalpha(ch)) || ch == '_'; } |
Added lexers/LexTACL.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 |
// Scintilla source code edit control /** @file LexTAL.cxx ** Lexer for TAL ** Based on LexPascal.cxx ** Written by Laurent le Tynevez ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002 ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments) ** Updated by Rod Falck, Aug 2006 Converted to TACL **/ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif inline bool isTACLoperator(char ch) { return ch == '\'' || isoperator(ch); } inline bool isTACLwordchar(char ch) { return ch == '#' || ch == '^' || ch == '|' || ch == '_' || iswordchar(ch); } inline bool isTACLwordstart(char ch) { return ch == '#' || ch == '|' || ch == '_' || iswordstart(ch); } static void getRange(unsigned int start, unsigned int end, Accessor &styler, char *s, unsigned int len) { unsigned int i = 0; while ((i < end - start + 1) && (i < len-1)) { s[i] = static_cast<char>(tolower(styler[start + i])); i++; } s[i] = '\0'; } static bool IsStreamCommentStyle(int style) { return style == SCE_C_COMMENT || style == SCE_C_COMMENTDOC || style == SCE_C_COMMENTDOCKEYWORD || style == SCE_C_COMMENTDOCKEYWORDERROR; } static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr, bool bInAsm) { if ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) { styler.ColourTo(end, SCE_C_REGEX); } else styler.ColourTo(end, attr); } // returns 1 if the item starts a class definition, and -1 if the word is "end", and 2 if the word is "asm" static int classifyWordTACL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInAsm) { int ret = 0; WordList& keywords = *keywordlists[0]; WordList& builtins = *keywordlists[1]; WordList& commands = *keywordlists[2]; char s[100]; getRange(start, end, styler, s, sizeof(s)); char chAttr = SCE_C_IDENTIFIER; if (isdigit(s[0]) || (s[0] == '.')) { chAttr = SCE_C_NUMBER; } else { if (s[0] == '#' || keywords.InList(s)) { chAttr = SCE_C_WORD; if (strcmp(s, "asm") == 0) { ret = 2; } else if (strcmp(s, "end") == 0) { ret = -1; } } else if (s[0] == '|' || builtins.InList(s)) { chAttr = SCE_C_WORD2; } else if (commands.InList(s)) { chAttr = SCE_C_UUID; } else if (strcmp(s, "comment") == 0) { chAttr = SCE_C_COMMENTLINE; ret = 3; } } ColourTo(styler, end, chAttr, (bInAsm && ret != -1)); return ret; } static int classifyFoldPointTACL(const char* s) { int lev = 0; if (s[0] == '[') lev=1; else if (s[0] == ']') lev=-1; return lev; } static void ColouriseTACLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { styler.StartAt(startPos); int state = initStyle; if (state == SCE_C_CHARACTER) // Does not leak onto next line state = SCE_C_DEFAULT; char chPrev = ' '; char chNext = styler[startPos]; unsigned int lengthDoc = startPos + length; bool bInClassDefinition; int currentLine = styler.GetLine(startPos); if (currentLine > 0) { styler.SetLineState(currentLine, styler.GetLineState(currentLine-1)); bInClassDefinition = (styler.GetLineState(currentLine) == 1); } else { styler.SetLineState(currentLine, 0); bInClassDefinition = false; } bool bInAsm = (state == SCE_C_REGEX); if (bInAsm) state = SCE_C_DEFAULT; styler.StartSegment(startPos); int visibleChars = 0; unsigned int i; for (i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) // Avoid triggering two times on Dos/Win // End of line if (state == SCE_C_CHARACTER) { ColourTo(styler, i, state, bInAsm); state = SCE_C_DEFAULT; } visibleChars = 0; currentLine++; styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0)); } if (styler.IsLeadByte(ch)) { chNext = styler.SafeGetCharAt(i + 2); chPrev = ' '; i += 1; continue; } if (state == SCE_C_DEFAULT) { if (isTACLwordstart(ch)) { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_IDENTIFIER; } else if (ch == '{') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_COMMENT; } else if (ch == '{' && chNext == '*') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_COMMENTDOC; } else if (ch == '=' && chNext == '=') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_COMMENTLINE; } else if (ch == '"') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_STRING; } else if (ch == '?' && visibleChars == 0) { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_PREPROCESSOR; } else if (isTACLoperator(ch)) { ColourTo(styler, i-1, state, bInAsm); ColourTo(styler, i, SCE_C_OPERATOR, bInAsm); } } else if (state == SCE_C_IDENTIFIER) { if (!isTACLwordchar(ch)) { int lStateChange = classifyWordTACL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm); if(lStateChange == 1) { styler.SetLineState(currentLine, 1); bInClassDefinition = true; } else if(lStateChange == 2) { bInAsm = true; } else if(lStateChange == -1) { styler.SetLineState(currentLine, 0); bInClassDefinition = false; bInAsm = false; } if (lStateChange == 3) { state = SCE_C_COMMENTLINE; } else { state = SCE_C_DEFAULT; chNext = styler.SafeGetCharAt(i + 1); if (ch == '{') { state = SCE_C_COMMENT; } else if (ch == '{' && chNext == '*') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_COMMENTDOC; } else if (ch == '=' && chNext == '=') { state = SCE_C_COMMENTLINE; } else if (ch == '"') { state = SCE_C_STRING; } else if (isTACLoperator(ch)) { ColourTo(styler, i, SCE_C_OPERATOR, bInAsm); } } } } else { if (state == SCE_C_PREPROCESSOR) { if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_DEFAULT; } } else if (state == SCE_C_COMMENT) { if (ch == '}' || (ch == '\r' || ch == '\n') ) { ColourTo(styler, i, state, bInAsm); state = SCE_C_DEFAULT; } } else if (state == SCE_C_COMMENTDOC) { if (ch == '}' || (ch == '\r' || ch == '\n')) { if (((i > styler.GetStartSegment() + 2) || ( (initStyle == SCE_C_COMMENTDOC) && (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) { ColourTo(styler, i, state, bInAsm); state = SCE_C_DEFAULT; } } } else if (state == SCE_C_COMMENTLINE) { if (ch == '\r' || ch == '\n') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_DEFAULT; } } else if (state == SCE_C_STRING) { if (ch == '"' || ch == '\r' || ch == '\n') { ColourTo(styler, i, state, bInAsm); state = SCE_C_DEFAULT; } } } if (!isspacechar(ch)) visibleChars++; chPrev = ch; } // Process to end of document if (state == SCE_C_IDENTIFIER) { classifyWordTACL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm); } else ColourTo(styler, lengthDoc - 1, state, bInAsm); } static void FoldTACLDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; bool section = false; int lastStart = 0; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (stylePrev == SCE_C_DEFAULT && (style == SCE_C_WORD || style == SCE_C_PREPROCESSOR)) { // Store last word start point. lastStart = i; } if (stylePrev == SCE_C_WORD || stylePrev == SCE_C_PREPROCESSOR) { if(isTACLwordchar(ch) && !isTACLwordchar(chNext)) { char s[100]; getRange(lastStart, i, styler, s, sizeof(s)); if (stylePrev == SCE_C_PREPROCESSOR && strcmp(s, "?section") == 0) { section = true; levelCurrent = 1; levelPrev = 0; } else if (stylePrev == SCE_C_WORD) levelCurrent += classifyFoldPointTACL(s); } } if (style == SCE_C_OPERATOR) { if (ch == '[') { levelCurrent++; } else if (ch == ']') { levelCurrent--; } } if (foldComment && (style == SCE_C_COMMENTLINE)) { if ((ch == '/') && (chNext == '/')) { char chNext2 = styler.SafeGetCharAt(i + 2); if (chNext2 == '{') { levelCurrent++; } else if (chNext2 == '}') { levelCurrent--; } } } if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) { if (ch == '{' && chNext == '$') { unsigned int j=i+2; // skip {$ while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { j++; } if (styler.Match(j, "region") || styler.Match(j, "if")) { levelCurrent++; } else if (styler.Match(j, "end")) { levelCurrent--; } } } if (foldComment && IsStreamCommentStyle(style)) { if (!IsStreamCommentStyle(stylePrev)) { levelCurrent++; } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelCurrent--; } } if (atEOL) { int lev = levelPrev | SC_FOLDLEVELBASE; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev || section) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; section = false; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char * const TACLWordListDesc[] = { "Builtins", "Labels", "Commands", 0 }; LexerModule lmTACL(SCLEX_TACL, ColouriseTACLDoc, "TACL", FoldTACLDoc, TACLWordListDesc); |
Added lexers/LexTADS3.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 |
// Scintilla source code edit control /** @file LexTADS3.cxx ** Lexer for TADS3. **/ // Copyright 1998-2006 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. /* * TADS3 is a language designed by Michael J. Roberts for the writing of text * based games. TADS comes from Text Adventure Development System. It has good * support for the processing and outputting of formatted text and much of a * TADS program listing consists of strings. * * TADS has two types of strings, those enclosed in single quotes (') and those * enclosed in double quotes ("). These strings have different symantics and * can be given different highlighting if desired. * * There can be embedded within both types of strings html tags * ( <tag key=value> ), library directives ( <.directive> ), and message * parameters ( {The doctor's/his} ). * * Double quoted strings can also contain interpolated expressions * ( << rug.moved ? ' and a hole in the floor. ' : nil >> ). These expressions * may themselves contain single or double quoted strings, although the double * quoted strings may not contain interpolated expressions. * * These embedded constructs influence the output and formatting and are an * important part of a program and require highlighting. * * LINKS * http://www.tads.org/ */ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static const int T3_SINGLE_QUOTE = 1; static const int T3_INT_EXPRESSION = 2; static const int T3_INT_EXPRESSION_IN_TAG = 4; static const int T3_HTML_SQUOTE = 8; static inline bool IsEOL(const int ch, const int chNext) { return (ch == '\r' && chNext != '\n') || (ch == '\n'); } /* * Test the current character to see if it's the START of an EOL sequence; * if so, skip ahead to the last character of the sequence and return true, * and if not just return false. There are a few places where we want to * check to see if a newline sequence occurs at a particular point, but * where a caller expects a subroutine to stop only upon reaching the END * of a newline sequence (in particular, CR-LF on Windows). That's why * IsEOL() above only returns true on CR if the CR isn't followed by an LF * - it doesn't want to admit that there's a newline until reaching the END * of the sequence. We meet both needs by saying that there's a newline * when we see the CR in a CR-LF, but skipping the CR before returning so * that the caller's caller will see that we've stopped at the LF. */ static inline bool IsEOLSkip(StyleContext &sc) { /* test for CR-LF */ if (sc.ch == '\r' && sc.chNext == '\n') { /* got CR-LF - skip the CR and indicate that we're at a newline */ sc.Forward(); return true; } /* * in other cases, we have at most a 1-character newline, so do the * normal IsEOL test */ return IsEOL(sc.ch, sc.chNext); } static inline bool IsATADS3Operator(const int ch) { return ch == '=' || ch == '{' || ch == '}' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == ',' || ch == ':' || ch == ';' || ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%' || ch == '?' || ch == '!' || ch == '<' || ch == '>' || ch == '|' || ch == '@' || ch == '&' || ch == '~'; } static inline bool IsAWordChar(const int ch) { return isalnum(ch) || ch == '_'; } static inline bool IsAWordStart(const int ch) { return isalpha(ch) || ch == '_'; } static inline bool IsAHexDigit(const int ch) { int lch = tolower(ch); return isdigit(lch) || lch == 'a' || lch == 'b' || lch == 'c' || lch == 'd' || lch == 'e' || lch == 'f'; } static inline bool IsAnHTMLChar(int ch) { return isalnum(ch) || ch == '-' || ch == '_' || ch == '.'; } static inline bool IsADirectiveChar(int ch) { return isalnum(ch) || isspace(ch) || ch == '-' || ch == '/'; } static inline bool IsANumberStart(StyleContext &sc) { return isdigit(sc.ch) || (!isdigit(sc.chPrev) && sc.ch == '.' && isdigit(sc.chNext)); } inline static void ColouriseTADS3Operator(StyleContext &sc) { int initState = sc.state; int c = sc.ch; sc.SetState(c == '{' || c == '}' ? SCE_T3_BRACE : SCE_T3_OPERATOR); sc.ForwardSetState(initState); } static void ColouriseTADSHTMLString(StyleContext &sc, int &lineState) { int endState = sc.state; int chQuote = sc.ch; int chString = (lineState & T3_SINGLE_QUOTE) ? '\'' : '"'; if (endState == SCE_T3_HTML_STRING) { if (lineState&T3_SINGLE_QUOTE) { endState = SCE_T3_S_STRING; chString = '\''; } else if (lineState&T3_INT_EXPRESSION) { endState = SCE_T3_X_STRING; chString = '"'; } else { endState = SCE_T3_HTML_DEFAULT; chString = '"'; } chQuote = (lineState & T3_HTML_SQUOTE) ? '\'' : '"'; } else { sc.SetState(SCE_T3_HTML_STRING); sc.Forward(); } if (chQuote == '"') lineState &= ~T3_HTML_SQUOTE; else lineState |= T3_HTML_SQUOTE; while (sc.More()) { if (IsEOL(sc.ch, sc.chNext)) { return; } if (sc.ch == chQuote) { sc.ForwardSetState(endState); return; } if (sc.Match('\\', static_cast<char>(chQuote))) { sc.Forward(2); sc.SetState(endState); return; } if (sc.ch == chString) { sc.SetState(SCE_T3_DEFAULT); return; } if (sc.Match('<', '<')) { lineState |= T3_INT_EXPRESSION | T3_INT_EXPRESSION_IN_TAG; sc.SetState(SCE_T3_X_DEFAULT); sc.Forward(2); return; } if (sc.Match('\\', static_cast<char>(chQuote)) || sc.Match('\\', static_cast<char>(chString)) || sc.Match('\\', '\\')) { sc.Forward(2); } else { sc.Forward(); } } } static void ColouriseTADS3HTMLTagStart(StyleContext &sc) { sc.SetState(SCE_T3_HTML_TAG); sc.Forward(); if (sc.ch == '/') { sc.Forward(); } while (IsAnHTMLChar(sc.ch)) { sc.Forward(); } } static void ColouriseTADS3HTMLTag(StyleContext &sc, int &lineState) { int endState = sc.state; int chQuote = '"'; int chString = '\''; switch (endState) { case SCE_T3_S_STRING: ColouriseTADS3HTMLTagStart(sc); sc.SetState(SCE_T3_HTML_DEFAULT); chQuote = '\''; chString = '"'; break; case SCE_T3_D_STRING: case SCE_T3_X_STRING: ColouriseTADS3HTMLTagStart(sc); sc.SetState(SCE_T3_HTML_DEFAULT); break; case SCE_T3_HTML_DEFAULT: if (lineState&T3_SINGLE_QUOTE) { endState = SCE_T3_S_STRING; chQuote = '\''; chString = '"'; } else if (lineState&T3_INT_EXPRESSION) { endState = SCE_T3_X_STRING; } else { endState = SCE_T3_D_STRING; } break; } while (sc.More()) { if (IsEOL(sc.ch, sc.chNext)) { return; } if (sc.Match('/', '>')) { sc.SetState(SCE_T3_HTML_TAG); sc.Forward(2); sc.SetState(endState); return; } if (sc.ch == '>') { sc.SetState(SCE_T3_HTML_TAG); sc.ForwardSetState(endState); return; } if (sc.ch == chQuote) { sc.SetState(endState); return; } if (sc.Match('\\', static_cast<char>(chQuote))) { sc.Forward(); ColouriseTADSHTMLString(sc, lineState); if (sc.state == SCE_T3_X_DEFAULT) break; } else if (sc.ch == chString) { ColouriseTADSHTMLString(sc, lineState); } else if (sc.ch == '=') { ColouriseTADS3Operator(sc); } else { sc.Forward(); } } } static void ColouriseTADS3Keyword(StyleContext &sc, WordList *keywordlists[], unsigned int endPos) { char s[250]; WordList &keywords = *keywordlists[0]; WordList &userwords1 = *keywordlists[1]; WordList &userwords2 = *keywordlists[2]; WordList &userwords3 = *keywordlists[3]; int initState = sc.state; sc.SetState(SCE_T3_IDENTIFIER); while (sc.More() && (IsAWordChar(sc.ch))) { sc.Forward(); } sc.GetCurrent(s, sizeof(s)); if ( strcmp(s, "is") == 0 || strcmp(s, "not") == 0) { // have to find if "in" is next int n = 1; while (n + sc.currentPos < endPos && IsASpaceOrTab(sc.GetRelative(n))) n++; if (sc.GetRelative(n) == 'i' && sc.GetRelative(n+1) == 'n') { sc.Forward(n+2); sc.ChangeState(SCE_T3_KEYWORD); } } else if (keywords.InList(s)) { sc.ChangeState(SCE_T3_KEYWORD); } else if (userwords3.InList(s)) { sc.ChangeState(SCE_T3_USER3); } else if (userwords2.InList(s)) { sc.ChangeState(SCE_T3_USER2); } else if (userwords1.InList(s)) { sc.ChangeState(SCE_T3_USER1); } sc.SetState(initState); } static void ColouriseTADS3MsgParam(StyleContext &sc, int &lineState) { int endState = sc.state; int chQuote = '"'; switch (endState) { case SCE_T3_S_STRING: sc.SetState(SCE_T3_MSG_PARAM); sc.Forward(); chQuote = '\''; break; case SCE_T3_D_STRING: case SCE_T3_X_STRING: sc.SetState(SCE_T3_MSG_PARAM); sc.Forward(); break; case SCE_T3_MSG_PARAM: if (lineState&T3_SINGLE_QUOTE) { endState = SCE_T3_S_STRING; chQuote = '\''; } else if (lineState&T3_INT_EXPRESSION) { endState = SCE_T3_X_STRING; } else { endState = SCE_T3_D_STRING; } break; } while (sc.More() && sc.ch != '}' && sc.ch != chQuote) { if (IsEOL(sc.ch, sc.chNext)) { return; } if (sc.ch == '\\') { sc.Forward(); } sc.Forward(); } if (sc.ch == chQuote) { sc.SetState(endState); } else { sc.ForwardSetState(endState); } } static void ColouriseTADS3LibDirective(StyleContext &sc, int &lineState) { int initState = sc.state; int chQuote = '"'; switch (initState) { case SCE_T3_S_STRING: sc.SetState(SCE_T3_LIB_DIRECTIVE); sc.Forward(2); chQuote = '\''; break; case SCE_T3_D_STRING: sc.SetState(SCE_T3_LIB_DIRECTIVE); sc.Forward(2); break; case SCE_T3_LIB_DIRECTIVE: if (lineState&T3_SINGLE_QUOTE) { initState = SCE_T3_S_STRING; chQuote = '\''; } else { initState = SCE_T3_D_STRING; } break; } while (sc.More() && IsADirectiveChar(sc.ch)) { if (IsEOL(sc.ch, sc.chNext)) { return; } sc.Forward(); }; if (sc.ch == '>' || !sc.More()) { sc.ForwardSetState(initState); } else if (sc.ch == chQuote) { sc.SetState(initState); } else { sc.ChangeState(initState); sc.Forward(); } } static void ColouriseTADS3String(StyleContext &sc, int &lineState) { int chQuote = sc.ch; int endState = sc.state; switch (sc.state) { case SCE_T3_DEFAULT: case SCE_T3_X_DEFAULT: if (chQuote == '"') { if (sc.state == SCE_T3_DEFAULT) { sc.SetState(SCE_T3_D_STRING); } else { sc.SetState(SCE_T3_X_STRING); } lineState &= ~T3_SINGLE_QUOTE; } else { sc.SetState(SCE_T3_S_STRING); lineState |= T3_SINGLE_QUOTE; } sc.Forward(); break; case SCE_T3_S_STRING: chQuote = '\''; endState = lineState&T3_INT_EXPRESSION ? SCE_T3_X_DEFAULT : SCE_T3_DEFAULT; break; case SCE_T3_D_STRING: chQuote = '"'; endState = SCE_T3_DEFAULT; break; case SCE_T3_X_STRING: chQuote = '"'; endState = SCE_T3_X_DEFAULT; break; } while (sc.More()) { if (IsEOL(sc.ch, sc.chNext)) { return; } if (sc.ch == chQuote) { sc.ForwardSetState(endState); return; } if (sc.state == SCE_T3_D_STRING && sc.Match('<', '<')) { lineState |= T3_INT_EXPRESSION; sc.SetState(SCE_T3_X_DEFAULT); sc.Forward(2); return; } if (sc.Match('\\', static_cast<char>(chQuote)) || sc.Match('\\', '\\')) { sc.Forward(2); } else if (sc.ch == '{') { ColouriseTADS3MsgParam(sc, lineState); } else if (sc.Match('<', '.')) { ColouriseTADS3LibDirective(sc, lineState); } else if (sc.ch == '<') { ColouriseTADS3HTMLTag(sc, lineState); if (sc.state == SCE_T3_X_DEFAULT) return; } else { sc.Forward(); } } } static void ColouriseTADS3Comment(StyleContext &sc, int endState) { sc.SetState(SCE_T3_BLOCK_COMMENT); while (sc.More()) { if (IsEOL(sc.ch, sc.chNext)) { return; } if (sc.Match('*', '/')) { sc.Forward(2); sc.SetState(endState); return; } sc.Forward(); } } static void ColouriseToEndOfLine(StyleContext &sc, int initState, int endState) { sc.SetState(initState); while (sc.More()) { if (sc.ch == '\\') { sc.Forward(); if (IsEOLSkip(sc)) { return; } } if (IsEOL(sc.ch, sc.chNext)) { sc.SetState(endState); return; } sc.Forward(); } } static void ColouriseTADS3Number(StyleContext &sc) { int endState = sc.state; bool inHexNumber = false; bool seenE = false; bool seenDot = sc.ch == '.'; sc.SetState(SCE_T3_NUMBER); if (sc.More()) { sc.Forward(); } if (sc.chPrev == '0' && tolower(sc.ch) == 'x') { inHexNumber = true; sc.Forward(); } while (sc.More()) { if (inHexNumber) { if (!IsAHexDigit(sc.ch)) { break; } } else if (!isdigit(sc.ch)) { if (!seenE && tolower(sc.ch) == 'e') { seenE = true; seenDot = true; if (sc.chNext == '+' || sc.chNext == '-') { sc.Forward(); } } else if (!seenDot && sc.ch == '.') { seenDot = true; } else { break; } } sc.Forward(); } sc.SetState(endState); } static void ColouriseTADS3Doc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { int visibleChars = 0; int bracketLevel = 0; int lineState = 0; unsigned int endPos = startPos + length; int lineCurrent = styler.GetLine(startPos); if (lineCurrent > 0) { lineState = styler.GetLineState(lineCurrent-1); } StyleContext sc(startPos, length, initStyle, styler); while (sc.More()) { if (IsEOL(sc.ch, sc.chNext)) { styler.SetLineState(lineCurrent, lineState); lineCurrent++; visibleChars = 0; sc.Forward(); if (sc.ch == '\n') { sc.Forward(); } } switch(sc.state) { case SCE_T3_PREPROCESSOR: case SCE_T3_LINE_COMMENT: ColouriseToEndOfLine(sc, sc.state, lineState&T3_INT_EXPRESSION ? SCE_T3_X_DEFAULT : SCE_T3_DEFAULT); break; case SCE_T3_S_STRING: case SCE_T3_D_STRING: case SCE_T3_X_STRING: ColouriseTADS3String(sc, lineState); visibleChars++; break; case SCE_T3_MSG_PARAM: ColouriseTADS3MsgParam(sc, lineState); break; case SCE_T3_LIB_DIRECTIVE: ColouriseTADS3LibDirective(sc, lineState); break; case SCE_T3_HTML_DEFAULT: ColouriseTADS3HTMLTag(sc, lineState); break; case SCE_T3_HTML_STRING: ColouriseTADSHTMLString(sc, lineState); break; case SCE_T3_BLOCK_COMMENT: ColouriseTADS3Comment(sc, lineState&T3_INT_EXPRESSION ? SCE_T3_X_DEFAULT : SCE_T3_DEFAULT); break; case SCE_T3_DEFAULT: case SCE_T3_X_DEFAULT: if (IsASpaceOrTab(sc.ch)) { sc.Forward(); } else if (sc.ch == '#' && visibleChars == 0) { ColouriseToEndOfLine(sc, SCE_T3_PREPROCESSOR, sc.state); } else if (sc.Match('/', '*')) { ColouriseTADS3Comment(sc, sc.state); visibleChars++; } else if (sc.Match('/', '/')) { ColouriseToEndOfLine(sc, SCE_T3_LINE_COMMENT, sc.state); } else if (sc.ch == '"') { bracketLevel = 0; ColouriseTADS3String(sc, lineState); visibleChars++; } else if (sc.ch == '\'') { ColouriseTADS3String(sc, lineState); visibleChars++; } else if (sc.state == SCE_T3_X_DEFAULT && bracketLevel == 0 && sc.Match('>', '>')) { sc.Forward(2); sc.SetState(SCE_T3_D_STRING); if (lineState & T3_INT_EXPRESSION_IN_TAG) sc.SetState(SCE_T3_HTML_STRING); lineState &= ~(T3_SINGLE_QUOTE|T3_INT_EXPRESSION |T3_INT_EXPRESSION_IN_TAG); } else if (IsATADS3Operator(sc.ch)) { if (sc.state == SCE_T3_X_DEFAULT) { if (sc.ch == '(') { bracketLevel++; } else if (sc.ch == ')' && bracketLevel > 0) { bracketLevel--; } } ColouriseTADS3Operator(sc); visibleChars++; } else if (IsANumberStart(sc)) { ColouriseTADS3Number(sc); visibleChars++; } else if (IsAWordStart(sc.ch)) { ColouriseTADS3Keyword(sc, keywordlists, endPos); visibleChars++; } else if (sc.Match("...")) { sc.SetState(SCE_T3_IDENTIFIER); sc.Forward(3); sc.SetState(SCE_T3_DEFAULT); } else { sc.Forward(); visibleChars++; } break; default: sc.SetState(SCE_T3_DEFAULT); sc.Forward(); } } sc.Complete(); } /* TADS3 has two styles of top level block (TLB). Eg // default style silverKey : Key 'small silver key' 'small silver key' "A small key glints in the sunlight. " ; and silverKey : Key { 'small silver key' 'small silver key' "A small key glints in the sunlight. " } Some constructs mandate one or the other, but usually the author has may choose either. T3_SEENSTART is used to indicate that a braceless TLB has been (potentially) seen and is also used to match the closing ';' of the default style. T3_EXPECTINGIDENTIFIER and T3_EXPECTINGPUNCTUATION are used to keep track of what characters may be seen without incrementing the block level. The general pattern is identifier <punc> identifier, acceptable punctuation characters are ':', ',', '(' and ')'. No attempt is made to ensure that punctuation characters are syntactically correct, eg parentheses match. A ')' always signifies the start of a block. We just need to check if it is followed by a '{', in which case we let the brace handling code handle the folding level. expectingIdentifier == false && expectingIdentifier == false Before the start of a TLB. expectingIdentifier == true && expectingIdentifier == true Currently in an identifier. Will accept identifier or punctuation. expectingIdentifier == true && expectingIdentifier == false Just seen a punctuation character & now waiting for an identifier to start. expectingIdentifier == false && expectingIdentifier == truee We were in an identifier and have seen space. Now waiting to see a punctuation character Space, comments & preprocessor directives are always acceptable and are equivalent. */ static const int T3_SEENSTART = 1 << 12; static const int T3_EXPECTINGIDENTIFIER = 1 << 13; static const int T3_EXPECTINGPUNCTUATION = 1 << 14; static inline bool IsStringTransition(int s1, int s2) { return s1 != s2 && (s1 == SCE_T3_S_STRING || s1 == SCE_T3_X_STRING || (s1 == SCE_T3_D_STRING && s2 != SCE_T3_X_DEFAULT)) && s2 != SCE_T3_LIB_DIRECTIVE && s2 != SCE_T3_MSG_PARAM && s2 != SCE_T3_HTML_TAG && s2 != SCE_T3_HTML_STRING; } static inline bool IsATADS3Punctuation(const int ch) { return ch == ':' || ch == ',' || ch == '(' || ch == ')'; } static inline bool IsAnIdentifier(const int style) { return style == SCE_T3_IDENTIFIER || style == SCE_T3_USER1 || style == SCE_T3_USER2 || style == SCE_T3_USER3; } static inline bool IsAnOperator(const int style) { return style == SCE_T3_OPERATOR || style == SCE_T3_BRACE; } static inline bool IsSpaceEquivalent(const int ch, const int style) { return isspace(ch) || style == SCE_T3_BLOCK_COMMENT || style == SCE_T3_LINE_COMMENT || style == SCE_T3_PREPROCESSOR; } static char peekAhead(unsigned int startPos, unsigned int endPos, Accessor &styler) { for (unsigned int i = startPos; i < endPos; i++) { int style = styler.StyleAt(i); char ch = styler[i]; if (!IsSpaceEquivalent(ch, style)) { if (IsAnIdentifier(style)) { return 'a'; } if (IsATADS3Punctuation(ch)) { return ':'; } if (ch == '{') { return '{'; } return '*'; } } return ' '; } static void FoldTADS3Doc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { unsigned int endPos = startPos + length; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int seenStart = levelCurrent & T3_SEENSTART; int expectingIdentifier = levelCurrent & T3_EXPECTINGIDENTIFIER; int expectingPunctuation = levelCurrent & T3_EXPECTINGPUNCTUATION; levelCurrent &= SC_FOLDLEVELNUMBERMASK; int levelMinCurrent = levelCurrent; int levelNext = levelCurrent; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; char ch = chNext; int stylePrev = style; bool redo = false; for (unsigned int i = startPos; i < endPos; i++) { if (redo) { redo = false; i--; } else { ch = chNext; chNext = styler.SafeGetCharAt(i + 1); stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); } bool atEOL = IsEOL(ch, chNext); if (levelNext == SC_FOLDLEVELBASE) { if (IsSpaceEquivalent(ch, style)) { if (expectingPunctuation) { expectingIdentifier = 0; } if (style == SCE_T3_BLOCK_COMMENT) { levelNext++; } } else if (ch == '{') { levelNext++; seenStart = 0; } else if (ch == '\'' || ch == '"' || ch == '[') { levelNext++; if (seenStart) { redo = true; } } else if (ch == ';') { seenStart = 0; expectingIdentifier = 0; expectingPunctuation = 0; } else if (expectingIdentifier && expectingPunctuation) { if (IsATADS3Punctuation(ch)) { if (ch == ')' && peekAhead(i+1, endPos, styler) != '{') { levelNext++; } else { expectingPunctuation = 0; } } else if (!IsAnIdentifier(style)) { levelNext++; } } else if (expectingIdentifier && !expectingPunctuation) { if (!IsAnIdentifier(style)) { levelNext++; } else { expectingPunctuation = T3_EXPECTINGPUNCTUATION; } } else if (!expectingIdentifier && expectingPunctuation) { if (!IsATADS3Punctuation(ch)) { levelNext++; } else { if (ch == ')' && peekAhead(i+1, endPos, styler) != '{') { levelNext++; } else { expectingIdentifier = T3_EXPECTINGIDENTIFIER; expectingPunctuation = 0; } } } else if (!expectingIdentifier && !expectingPunctuation) { if (IsAnIdentifier(style)) { seenStart = T3_SEENSTART; expectingIdentifier = T3_EXPECTINGIDENTIFIER; expectingPunctuation = T3_EXPECTINGPUNCTUATION; } } if (levelNext != SC_FOLDLEVELBASE && style != SCE_T3_BLOCK_COMMENT) { expectingIdentifier = 0; expectingPunctuation = 0; } } else if (levelNext == SC_FOLDLEVELBASE+1 && seenStart && ch == ';' && IsAnOperator(style)) { levelNext--; seenStart = 0; } else if (style == SCE_T3_BLOCK_COMMENT) { if (stylePrev != SCE_T3_BLOCK_COMMENT) { levelNext++; } else if (styleNext != SCE_T3_BLOCK_COMMENT && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelNext--; } } else if (ch == '\'' || ch == '"') { if (IsStringTransition(style, stylePrev)) { if (levelMinCurrent > levelNext) { levelMinCurrent = levelNext; } levelNext++; } else if (IsStringTransition(style, styleNext)) { levelNext--; } } else if (IsAnOperator(style)) { if (ch == '{' || ch == '[') { // Measure the minimum before a '{' to allow // folding on "} else {" if (levelMinCurrent > levelNext) { levelMinCurrent = levelNext; } levelNext++; } else if (ch == '}' || ch == ']') { levelNext--; } } if (atEOL) { if (seenStart && levelNext == SC_FOLDLEVELBASE) { switch (peekAhead(i+1, endPos, styler)) { case ' ': case '{': break; case '*': levelNext++; break; case 'a': if (expectingPunctuation) { levelNext++; } break; case ':': if (expectingIdentifier) { levelNext++; } break; } if (levelNext != SC_FOLDLEVELBASE) { expectingIdentifier = 0; expectingPunctuation = 0; } } int lev = levelMinCurrent | (levelNext | expectingIdentifier | expectingPunctuation | seenStart) << 16; if (levelMinCurrent < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelCurrent = levelNext; levelMinCurrent = levelCurrent; } } } static const char * const tads3WordList[] = { "TADS3 Keywords", "User defined 1", "User defined 2", "User defined 3", 0 }; LexerModule lmTADS3(SCLEX_TADS3, ColouriseTADS3Doc, "tads3", FoldTADS3Doc, tads3WordList); |
Added lexers/LexTAL.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 |
// Scintilla source code edit control /** @file LexTAL.cxx ** Lexer for TAL ** Based on LexPascal.cxx ** Written by Laurent le Tynevez ** Updated by Simon Steele <s.steele@pnotepad.org> September 2002 ** Updated by Mathias Rauen <scite@madshi.net> May 2003 (Delphi adjustments) ** Updated by Rod Falck, Aug 2006 Converted to TAL **/ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif inline bool isTALoperator(char ch) { return ch == '\'' || ch == '@' || ch == '#' || isoperator(ch); } inline bool isTALwordchar(char ch) { return ch == '$' || ch == '^' || iswordchar(ch); } inline bool isTALwordstart(char ch) { return ch == '$' || ch == '^' || iswordstart(ch); } static void getRange(unsigned int start, unsigned int end, Accessor &styler, char *s, unsigned int len) { unsigned int i = 0; while ((i < end - start + 1) && (i < len-1)) { s[i] = static_cast<char>(tolower(styler[start + i])); i++; } s[i] = '\0'; } static bool IsStreamCommentStyle(int style) { return style == SCE_C_COMMENT || style == SCE_C_COMMENTDOC || style == SCE_C_COMMENTDOCKEYWORD || style == SCE_C_COMMENTDOCKEYWORDERROR; } static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr, bool bInAsm) { if ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) { styler.ColourTo(end, SCE_C_REGEX); } else styler.ColourTo(end, attr); } // returns 1 if the item starts a class definition, and -1 if the word is "end", and 2 if the word is "asm" static int classifyWordTAL(unsigned int start, unsigned int end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, bool bInAsm) { int ret = 0; WordList& keywords = *keywordlists[0]; WordList& builtins = *keywordlists[1]; WordList& nonreserved_keywords = *keywordlists[2]; char s[100]; getRange(start, end, styler, s, sizeof(s)); char chAttr = SCE_C_IDENTIFIER; if (isdigit(s[0]) || (s[0] == '.')) { chAttr = SCE_C_NUMBER; } else { if (keywords.InList(s)) { chAttr = SCE_C_WORD; if (strcmp(s, "asm") == 0) { ret = 2; } else if (strcmp(s, "end") == 0) { ret = -1; } } else if (s[0] == '$' || builtins.InList(s)) { chAttr = SCE_C_WORD2; } else if (nonreserved_keywords.InList(s)) { chAttr = SCE_C_UUID; } } ColourTo(styler, end, chAttr, (bInAsm && ret != -1)); return ret; } static int classifyFoldPointTAL(const char* s) { int lev = 0; if (!(isdigit(s[0]) || (s[0] == '.'))) { if (strcmp(s, "begin") == 0 || strcmp(s, "block") == 0) { lev=1; } else if (strcmp(s, "end") == 0) { lev=-1; } } return lev; } static void ColouriseTALDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { styler.StartAt(startPos); int state = initStyle; if (state == SCE_C_CHARACTER) // Does not leak onto next line state = SCE_C_DEFAULT; char chPrev = ' '; char chNext = styler[startPos]; unsigned int lengthDoc = startPos + length; bool bInClassDefinition; int currentLine = styler.GetLine(startPos); if (currentLine > 0) { styler.SetLineState(currentLine, styler.GetLineState(currentLine-1)); bInClassDefinition = (styler.GetLineState(currentLine) == 1); } else { styler.SetLineState(currentLine, 0); bInClassDefinition = false; } bool bInAsm = (state == SCE_C_REGEX); if (bInAsm) state = SCE_C_DEFAULT; styler.StartSegment(startPos); int visibleChars = 0; for (unsigned int i = startPos; i < lengthDoc; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) // Avoid triggering two times on Dos/Win // End of line if (state == SCE_C_CHARACTER) { ColourTo(styler, i, state, bInAsm); state = SCE_C_DEFAULT; } visibleChars = 0; currentLine++; styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0)); } if (styler.IsLeadByte(ch)) { chNext = styler.SafeGetCharAt(i + 2); chPrev = ' '; i += 1; continue; } if (state == SCE_C_DEFAULT) { if (isTALwordstart(ch)) { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_IDENTIFIER; } else if (ch == '!' && chNext != '*') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_COMMENT; } else if (ch == '!' && chNext == '*') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_COMMENTDOC; } else if (ch == '-' && chNext == '-') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_COMMENTLINE; } else if (ch == '"') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_STRING; } else if (ch == '?' && visibleChars == 0) { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_PREPROCESSOR; } else if (isTALoperator(ch)) { ColourTo(styler, i-1, state, bInAsm); ColourTo(styler, i, SCE_C_OPERATOR, bInAsm); } } else if (state == SCE_C_IDENTIFIER) { if (!isTALwordchar(ch)) { int lStateChange = classifyWordTAL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm); if(lStateChange == 1) { styler.SetLineState(currentLine, 1); bInClassDefinition = true; } else if(lStateChange == 2) { bInAsm = true; } else if(lStateChange == -1) { styler.SetLineState(currentLine, 0); bInClassDefinition = false; bInAsm = false; } state = SCE_C_DEFAULT; chNext = styler.SafeGetCharAt(i + 1); if (ch == '!' && chNext != '*') { state = SCE_C_COMMENT; } else if (ch == '!' && chNext == '*') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_COMMENTDOC; } else if (ch == '-' && chNext == '-') { state = SCE_C_COMMENTLINE; } else if (ch == '"') { state = SCE_C_STRING; } else if (isTALoperator(ch)) { ColourTo(styler, i, SCE_C_OPERATOR, bInAsm); } } } else { if (state == SCE_C_PREPROCESSOR) { if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_DEFAULT; } } else if (state == SCE_C_COMMENT) { if (ch == '!' || (ch == '\r' || ch == '\n') ) { ColourTo(styler, i, state, bInAsm); state = SCE_C_DEFAULT; } } else if (state == SCE_C_COMMENTDOC) { if (ch == '!' || (ch == '\r' || ch == '\n')) { if (((i > styler.GetStartSegment() + 2) || ( (initStyle == SCE_C_COMMENTDOC) && (styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) { ColourTo(styler, i, state, bInAsm); state = SCE_C_DEFAULT; } } } else if (state == SCE_C_COMMENTLINE) { if (ch == '\r' || ch == '\n') { ColourTo(styler, i-1, state, bInAsm); state = SCE_C_DEFAULT; } } else if (state == SCE_C_STRING) { if (ch == '"') { ColourTo(styler, i, state, bInAsm); state = SCE_C_DEFAULT; } } } if (!isspacechar(ch)) visibleChars++; chPrev = ch; } ColourTo(styler, lengthDoc - 1, state, bInAsm); } static void FoldTALDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; bool was_end = false; bool section = false; int lastStart = 0; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (stylePrev == SCE_C_DEFAULT && (style == SCE_C_WORD || style == SCE_C_UUID || style == SCE_C_PREPROCESSOR)) { // Store last word start point. lastStart = i; } if (stylePrev == SCE_C_WORD || style == SCE_C_UUID || stylePrev == SCE_C_PREPROCESSOR) { if(isTALwordchar(ch) && !isTALwordchar(chNext)) { char s[100]; getRange(lastStart, i, styler, s, sizeof(s)); if (stylePrev == SCE_C_PREPROCESSOR && strcmp(s, "?section") == 0) { section = true; levelCurrent = 1; levelPrev = 0; } else if (stylePrev == SCE_C_WORD || stylePrev == SCE_C_UUID) { if (strcmp(s, "block") == 0) { // block keyword is ignored immediately after end keyword if (!was_end) levelCurrent++; } else levelCurrent += classifyFoldPointTAL(s); if (strcmp(s, "end") == 0) { was_end = true; } else { was_end = false; } } } } if (foldComment && (style == SCE_C_COMMENTLINE)) { if ((ch == '/') && (chNext == '/')) { char chNext2 = styler.SafeGetCharAt(i + 2); if (chNext2 == '{') { levelCurrent++; } else if (chNext2 == '}') { levelCurrent--; } } } if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) { if (ch == '{' && chNext == '$') { unsigned int j=i+2; // skip {$ while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { j++; } if (styler.Match(j, "region") || styler.Match(j, "if")) { levelCurrent++; } else if (styler.Match(j, "end")) { levelCurrent--; } } } if (foldComment && IsStreamCommentStyle(style)) { if (!IsStreamCommentStyle(stylePrev)) { levelCurrent++; } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelCurrent--; } } if (atEOL) { int lev = levelPrev | SC_FOLDLEVELBASE; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev || section) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; section = false; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char * const TALWordListDesc[] = { "Keywords", "Builtins", 0 }; LexerModule lmTAL(SCLEX_TAL, ColouriseTALDoc, "TAL", FoldTALDoc, TALWordListDesc); |
Added lexers/LexTCL.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 |
// Scintilla source code edit control /** @file LexTCL.cxx ** Lexer for TCL language. **/ // Copyright 1998-2001 by Andre Arpin <arpin@kingston.net> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // Extended to accept accented characters static inline bool IsAWordChar(int ch) { return ch >= 0x80 || (isalnum(ch) || ch == '_' || ch ==':' || ch=='.'); // : name space separator } static inline bool IsAWordStart(int ch) { return ch >= 0x80 || (ch ==':' || isalpha(ch) || ch == '_'); } static inline bool IsANumberChar(int ch) { // Not exactly following number definition (several dots are seen as OK, etc.) // but probably enough in most cases. return (ch < 0x80) && (IsADigit(ch, 0x10) || toupper(ch) == 'E' || ch == '.' || ch == '-' || ch == '+'); } static void ColouriseTCLDoc(unsigned int startPos, int length, int , WordList *keywordlists[], Accessor &styler) { #define isComment(s) (s==SCE_TCL_COMMENT || s==SCE_TCL_COMMENTLINE || s==SCE_TCL_COMMENT_BOX || s==SCE_TCL_BLOCK_COMMENT) bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool commentLevel = false; bool subBrace = false; // substitution begin with a brace ${.....} enum tLineState {LS_DEFAULT, LS_OPEN_COMMENT, LS_OPEN_DOUBLE_QUOTE, LS_COMMENT_BOX, LS_MASK_STATE = 0xf, LS_COMMAND_EXPECTED = 16, LS_BRACE_ONLY = 32 } lineState = LS_DEFAULT; bool prevSlash = false; int currentLevel = 0; bool expected = 0; bool subParen = 0; int currentLine = styler.GetLine(startPos); if (currentLine > 0) currentLine--; length += startPos - styler.LineStart(currentLine); // make sure lines overlap startPos = styler.LineStart(currentLine); WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; WordList &keywords5 = *keywordlists[4]; WordList &keywords6 = *keywordlists[5]; WordList &keywords7 = *keywordlists[6]; WordList &keywords8 = *keywordlists[7]; WordList &keywords9 = *keywordlists[8]; if (currentLine > 0) { int ls = styler.GetLineState(currentLine - 1); lineState = tLineState(ls & LS_MASK_STATE); expected = LS_COMMAND_EXPECTED == tLineState(ls & LS_COMMAND_EXPECTED); subBrace = LS_BRACE_ONLY == tLineState(ls & LS_BRACE_ONLY); currentLevel = styler.LevelAt(currentLine - 1) >> 17; commentLevel = (styler.LevelAt(currentLine - 1) >> 16) & 1; } else styler.SetLevel(0, SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG); bool visibleChars = false; int previousLevel = currentLevel; StyleContext sc(startPos, length, SCE_TCL_DEFAULT, styler); for (; ; sc.Forward()) { next: if (sc.ch=='\r' && sc.chNext == '\n') // only ignore \r on PC process on the mac continue; bool atEnd = !sc.More(); // make sure we coloured the last word if (lineState != LS_DEFAULT) { sc.SetState(SCE_TCL_DEFAULT); if (lineState == LS_OPEN_COMMENT) sc.SetState(SCE_TCL_COMMENTLINE); else if (lineState == LS_OPEN_DOUBLE_QUOTE) sc.SetState(SCE_TCL_IN_QUOTE); else if (lineState == LS_COMMENT_BOX && (sc.ch == '#' || (sc.ch == ' ' && sc.chNext=='#'))) sc.SetState(SCE_TCL_COMMENT_BOX); lineState = LS_DEFAULT; } if (subBrace) { // ${ overrides every thing even \ except } if (sc.ch == '}') { subBrace = false; sc.SetState(SCE_TCL_OPERATOR); sc.ForwardSetState(SCE_TCL_DEFAULT); goto next; } else sc.SetState(SCE_TCL_SUB_BRACE); if (!sc.atLineEnd) continue; } else if (sc.state == SCE_TCL_DEFAULT || sc.state ==SCE_TCL_OPERATOR) { expected &= isspacechar(static_cast<unsigned char>(sc.ch)) || IsAWordStart(sc.ch) || sc.ch =='#'; } else if (sc.state == SCE_TCL_SUBSTITUTION) { switch(sc.ch) { case '(': subParen=true; sc.SetState(SCE_TCL_OPERATOR); sc.ForwardSetState(SCE_TCL_SUBSTITUTION); continue; case ')': sc.SetState(SCE_TCL_OPERATOR); subParen=false; continue; case '$': continue; case ',': sc.SetState(SCE_TCL_OPERATOR); if (subParen) sc.ForwardSetState(SCE_TCL_SUBSTITUTION); continue; default : // maybe spaces should be allowed ??? if (!IsAWordChar(sc.ch)) { // probably the code is wrong sc.SetState(SCE_TCL_DEFAULT); subParen = 0; } break; } } else if (isComment(sc.state)) { } else if (!IsAWordChar(sc.ch)) { if ((sc.state == SCE_TCL_IDENTIFIER && expected) || sc.state == SCE_TCL_MODIFIER) { char w[100]; char *s=w; sc.GetCurrent(w, sizeof(w)); if (w[strlen(w)-1]=='\r') w[strlen(w)-1]=0; while(*s == ':') // ignore leading : like in ::set a 10 ++s; bool quote = sc.state == SCE_TCL_IN_QUOTE; if (commentLevel || expected) { if (keywords.InList(s)) { sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD); } else if (keywords2.InList(s)) { sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD2); } else if (keywords3.InList(s)) { sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD3); } else if (keywords4.InList(s)) { sc.ChangeState(quote ? SCE_TCL_WORD_IN_QUOTE : SCE_TCL_WORD4); } else if (sc.GetRelative(-static_cast<int>(strlen(s))-1) == '{' && keywords5.InList(s) && sc.ch == '}') { // {keyword} exactly no spaces sc.ChangeState(SCE_TCL_EXPAND); } if (keywords6.InList(s)) { sc.ChangeState(SCE_TCL_WORD5); } else if (keywords7.InList(s)) { sc.ChangeState(SCE_TCL_WORD6); } else if (keywords8.InList(s)) { sc.ChangeState(SCE_TCL_WORD7); } else if (keywords9.InList(s)) { sc.ChangeState(SCE_TCL_WORD8); } } expected = false; sc.SetState(quote ? SCE_TCL_IN_QUOTE : SCE_TCL_DEFAULT); } else if (sc.state == SCE_TCL_MODIFIER || sc.state == SCE_TCL_IDENTIFIER) { sc.SetState(SCE_TCL_DEFAULT); } } if (atEnd) break; if (sc.atLineEnd) { lineState = LS_DEFAULT; currentLine = styler.GetLine(sc.currentPos); if (foldComment && sc.state!=SCE_TCL_COMMENT && isComment(sc.state)) { if (currentLevel == 0) { ++currentLevel; commentLevel = true; } } else { if (visibleChars && commentLevel) { --currentLevel; --previousLevel; commentLevel = false; } } int flag = 0; if (!visibleChars) flag = SC_FOLDLEVELWHITEFLAG; if (currentLevel > previousLevel) flag = SC_FOLDLEVELHEADERFLAG; styler.SetLevel(currentLine, flag + previousLevel + SC_FOLDLEVELBASE + (currentLevel << 17) + (commentLevel << 16)); // Update the line state, so it can be seen by next line if (sc.state == SCE_TCL_IN_QUOTE) lineState = LS_OPEN_DOUBLE_QUOTE; else { if (prevSlash) { if (isComment(sc.state)) lineState = LS_OPEN_COMMENT; } else if (sc.state == SCE_TCL_COMMENT_BOX) lineState = LS_COMMENT_BOX; } styler.SetLineState(currentLine, (subBrace ? LS_BRACE_ONLY : 0) | (expected ? LS_COMMAND_EXPECTED : 0) | lineState); if (lineState == LS_COMMENT_BOX) sc.ForwardSetState(SCE_TCL_COMMENT_BOX); else if (lineState == LS_OPEN_DOUBLE_QUOTE) sc.ForwardSetState(SCE_TCL_IN_QUOTE); else sc.ForwardSetState(SCE_TCL_DEFAULT); prevSlash = false; previousLevel = currentLevel; goto next; } if (prevSlash) { prevSlash = false; if (sc.ch == '#' && IsANumberChar(sc.chNext)) sc.ForwardSetState(SCE_TCL_NUMBER); continue; } prevSlash = sc.ch == '\\'; if (isComment(sc.state)) continue; if (sc.atLineStart) { visibleChars = false; if (sc.state!=SCE_TCL_IN_QUOTE && !isComment(sc.state)) { sc.SetState(SCE_TCL_DEFAULT); expected = IsAWordStart(sc.ch)|| isspacechar(static_cast<unsigned char>(sc.ch)); } } switch (sc.state) { case SCE_TCL_NUMBER: if (!IsANumberChar(sc.ch)) sc.SetState(SCE_TCL_DEFAULT); break; case SCE_TCL_IN_QUOTE: if (sc.ch == '"') { sc.ForwardSetState(SCE_TCL_DEFAULT); visibleChars = true; // necessary if a " is the first and only character on a line goto next; } else if (sc.ch == '[' || sc.ch == ']' || sc.ch == '$') { sc.SetState(SCE_TCL_OPERATOR); expected = sc.ch == '['; sc.ForwardSetState(SCE_TCL_IN_QUOTE); goto next; } continue; case SCE_TCL_OPERATOR: sc.SetState(SCE_TCL_DEFAULT); break; } if (sc.ch == '#') { if (visibleChars) { if (sc.state != SCE_TCL_IN_QUOTE && expected) sc.SetState(SCE_TCL_COMMENT); } else { sc.SetState(SCE_TCL_COMMENTLINE); if (sc.chNext == '~') sc.SetState(SCE_TCL_BLOCK_COMMENT); if (sc.atLineStart && (sc.chNext == '#' || sc.chNext == '-')) sc.SetState(SCE_TCL_COMMENT_BOX); } } if (!isspacechar(static_cast<unsigned char>(sc.ch))) { visibleChars = true; } if (sc.ch == '\\') { prevSlash = true; continue; } // Determine if a new state should be entered. if (sc.state == SCE_TCL_DEFAULT) { if (IsAWordStart(sc.ch)) { sc.SetState(SCE_TCL_IDENTIFIER); } else if (IsADigit(sc.ch) && !IsAWordChar(sc.chPrev)) { sc.SetState(SCE_TCL_NUMBER); } else { switch (sc.ch) { case '\"': sc.SetState(SCE_TCL_IN_QUOTE); break; case '{': sc.SetState(SCE_TCL_OPERATOR); expected = true; ++currentLevel; break; case '}': sc.SetState(SCE_TCL_OPERATOR); expected = true; --currentLevel; break; case '[': expected = true; case ']': case '(': case ')': sc.SetState(SCE_TCL_OPERATOR); break; case ';': expected = true; break; case '$': subParen = 0; if (sc.chNext != '{') { sc.SetState(SCE_TCL_SUBSTITUTION); } else { sc.SetState(SCE_TCL_OPERATOR); // $ sc.Forward(); // { sc.ForwardSetState(SCE_TCL_SUB_BRACE); subBrace = true; } break; case '#': if ((isspacechar(static_cast<unsigned char>(sc.chPrev))|| isoperator(static_cast<char>(sc.chPrev))) && IsADigit(sc.chNext,0x10)) sc.SetState(SCE_TCL_NUMBER); break; case '-': sc.SetState(IsADigit(sc.chNext)? SCE_TCL_NUMBER: SCE_TCL_MODIFIER); break; default: if (isoperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_TCL_OPERATOR); } } } } } sc.Complete(); } static const char * const tclWordListDesc[] = { "TCL Keywords", "TK Keywords", "iTCL Keywords", "tkCommands", "expand" "user1", "user2", "user3", "user4", 0 }; // this code supports folding in the colourizer LexerModule lmTCL(SCLEX_TCL, ColouriseTCLDoc, "tcl", 0, tclWordListDesc); |
Added lexers/LexTCMD.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 |
// Scintilla\ source code edit control /** @file LexTCMD.cxx ** Lexer for Take Command / TCC batch scripts (.bat, .btm, .cmd). **/ // Written by Rex Conn (rconn [at] jpsoft [dot] com) // based on the CMD lexer // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static bool IsAlphabetic(int ch) { return isascii(ch) && isalpha(ch); } static inline bool AtEOL(Accessor &styler, unsigned int i) { return (styler[i] == '\n') || ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')); } // Tests for BATCH Operators static bool IsBOperator(char ch) { return (ch == '=') || (ch == '+') || (ch == '>') || (ch == '<') || (ch == '|') || (ch == '&') || (ch == '!') || (ch == '?') || (ch == '*') || (ch == '(') || (ch == ')'); } // Tests for BATCH Separators static bool IsBSeparator(char ch) { return (ch == '\\') || (ch == '.') || (ch == ';') || (ch == ' ') || (ch == '\t') || (ch == '[') || (ch == ']') || (ch == '\"') || (ch == '\'') || (ch == '/'); } // Tests for Environment Variable symbol static inline bool IsEnvironmentVar(char ch) { return isalpha(ch) || isdigit(ch) || (ch == '_') || (ch == '$'); } // Find length of CMD FOR variable with modifier (%~...) or return 0 static unsigned int GetBatchVarLen( char *wordBuffer ) { int nLength = 0; if ( wordBuffer[0] == '%' ) { if ( wordBuffer[1] == '~' ) nLength = 2; else if (( wordBuffer[1] == '%' ) && ( wordBuffer[2] == '~' )) nLength++; else return 0; for ( ; ( wordBuffer[nLength] ); nLength++ ) { switch ( toupper(wordBuffer[nLength]) ) { case 'A': // file attributes case 'D': // drive letter only case 'F': // fully qualified path name case 'N': // filename only case 'P': // path only case 'S': // short name case 'T': // date / time of file case 'X': // file extension only case 'Z': // file size break; default: return nLength; } } } return nLength; } static void ColouriseTCMDLine( char *lineBuffer, unsigned int lengthLine, unsigned int startLine, unsigned int endPos, WordList *keywordlists[], Accessor &styler) { unsigned int offset = 0; // Line Buffer Offset char wordBuffer[260]; // Word Buffer - large to catch long paths unsigned int wbl; // Word Buffer Length unsigned int wbo; // Word Buffer Offset - also Special Keyword Buffer Length WordList &keywords = *keywordlists[0]; // Internal Commands // WordList &keywords2 = *keywordlists[1]; // Aliases (optional) bool isDelayedExpansion = 1; // !var! bool continueProcessing = true; // Used to toggle Regular Keyword Checking // Special Keywords are those that allow certain characters without whitespace after the command // Examples are: cd. cd\ echo: echo. path= bool inString = false; // Used for processing while "" // Special Keyword Buffer used to determine if the first n characters is a Keyword char sKeywordBuffer[260]; // Special Keyword Buffer bool sKeywordFound; // Exit Special Keyword for-loop if found // Skip leading whitespace while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { offset++; } // Colorize Default Text styler.ColourTo(startLine + offset - 1, SCE_TCMD_DEFAULT); if ( offset >= lengthLine ) return; // Check for Fake Label (Comment) or Real Label - return if found if (lineBuffer[offset] == ':') { if (lineBuffer[offset + 1] == ':') { // Colorize Fake Label (Comment) - :: is the same as REM styler.ColourTo(endPos, SCE_TCMD_COMMENT); } else { // Colorize Real Label styler.ColourTo(endPos, SCE_TCMD_LABEL); } return; // Check for Comment - return if found } else if (( CompareNCaseInsensitive(lineBuffer+offset, "rem", 3) == 0 ) && (( lineBuffer[offset+3] == 0 ) || ( isspace(lineBuffer[offset+3] )))) { styler.ColourTo(endPos, SCE_TCMD_COMMENT); return; // Check for Drive Change (Drive Change is internal command) - return if found } else if ((IsAlphabetic(lineBuffer[offset])) && (lineBuffer[offset + 1] == ':') && ((isspacechar(lineBuffer[offset + 2])) || (((lineBuffer[offset + 2] == '\\')) && (isspacechar(lineBuffer[offset + 3]))))) { // Colorize Regular Keyword styler.ColourTo(endPos, SCE_TCMD_WORD); return; } // Check for Hide Command (@ECHO OFF/ON) if (lineBuffer[offset] == '@') { styler.ColourTo(startLine + offset, SCE_TCMD_HIDE); offset++; } // Skip whitespace while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { offset++; } // Read remainder of line word-at-a-time or remainder-of-word-at-a-time while (offset < lengthLine) { if (offset > startLine) { // Colorize Default Text styler.ColourTo(startLine + offset - 1, SCE_TCMD_DEFAULT); } // Copy word from Line Buffer into Word Buffer wbl = 0; for (; offset < lengthLine && ( wbl < 260 ) && !isspacechar(lineBuffer[offset]); wbl++, offset++) { wordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset])); } wordBuffer[wbl] = '\0'; wbo = 0; // Check for Separator if (IsBSeparator(wordBuffer[0])) { // Reset Offset to re-process remainder of word offset -= (wbl - 1); // Colorize Default Text styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); if (wordBuffer[0] == '"') inString = !inString; // Check for Regular expression } else if (( wordBuffer[0] == ':' ) && ( wordBuffer[1] == ':' ) && (continueProcessing)) { // Colorize Regular exoressuin styler.ColourTo(startLine + offset - 1, SCE_TCMD_DEFAULT); // No need to Reset Offset // Check for Labels in text (... :label) } else if (wordBuffer[0] == ':' && isspacechar(lineBuffer[offset - wbl - 1])) { // Colorize Default Text styler.ColourTo(startLine + offset - 1 - wbl, SCE_TCMD_DEFAULT); // Colorize Label styler.ColourTo(startLine + offset - 1, SCE_TCMD_CLABEL); // No need to Reset Offset // Check for delayed expansion Variable (!x...!) } else if (isDelayedExpansion && wordBuffer[0] == '!') { // Colorize Default Text styler.ColourTo(startLine + offset - 1 - wbl, SCE_TCMD_DEFAULT); wbo++; // Search to end of word for second ! while ((wbo < wbl) && (wordBuffer[wbo] != '!') && (!IsBOperator(wordBuffer[wbo])) && (!IsBSeparator(wordBuffer[wbo]))) { wbo++; } if (wordBuffer[wbo] == '!') { wbo++; // Colorize Environment Variable styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_TCMD_EXPANSION); } else { wbo = 1; // Colorize Symbol styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_TCMD_DEFAULT); } // Reset Offset to re-process remainder of word offset -= (wbl - wbo); // Check for Regular Keyword in list } else if ((keywords.InList(wordBuffer)) && (!inString) && (continueProcessing)) { // ECHO, PATH, and PROMPT require no further Regular Keyword Checking if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) || (CompareCaseInsensitive(sKeywordBuffer, "echos") == 0) || (CompareCaseInsensitive(sKeywordBuffer, "echoerr") == 0) || (CompareCaseInsensitive(sKeywordBuffer, "echoserr") == 0) || (CompareCaseInsensitive(wordBuffer, "path") == 0) || (CompareCaseInsensitive(wordBuffer, "prompt") == 0)) { continueProcessing = false; } // Colorize Regular keyword styler.ColourTo(startLine + offset - 1, SCE_TCMD_WORD); // No need to Reset Offset } else if ((wordBuffer[0] != '%') && (wordBuffer[0] != '!') && (!IsBOperator(wordBuffer[0])) && (!inString) && (continueProcessing)) { // a few commands accept "illegal" syntax -- cd\, echo., etc. sscanf( wordBuffer, "%[^.<>|&=\\/]", sKeywordBuffer ); sKeywordFound = false; if ((CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) || (CompareCaseInsensitive(sKeywordBuffer, "echos") == 0) || (CompareCaseInsensitive(sKeywordBuffer, "echoerr") == 0) || (CompareCaseInsensitive(sKeywordBuffer, "echoserr") == 0) || (CompareCaseInsensitive(sKeywordBuffer, "cd") == 0) || (CompareCaseInsensitive(sKeywordBuffer, "path") == 0) || (CompareCaseInsensitive(sKeywordBuffer, "prompt") == 0)) { // no further Regular Keyword Checking continueProcessing = false; sKeywordFound = true; wbo = (unsigned int)strlen( sKeywordBuffer ); // Colorize Special Keyword as Regular Keyword styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_TCMD_WORD); // Reset Offset to re-process remainder of word offset -= (wbl - wbo); } // Check for Default Text if (!sKeywordFound) { wbo = 0; // Read up to %, Operator or Separator while ((wbo < wbl) && (wordBuffer[wbo] != '%') && (!isDelayedExpansion || wordBuffer[wbo] != '!') && (!IsBOperator(wordBuffer[wbo])) && (!IsBSeparator(wordBuffer[wbo]))) { wbo++; } // Colorize Default Text styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_TCMD_DEFAULT); // Reset Offset to re-process remainder of word offset -= (wbl - wbo); } // Check for Argument (%n), Environment Variable (%x...%) or Local Variable (%%a) } else if (wordBuffer[0] == '%') { unsigned int varlen; unsigned int n = 1; // Colorize Default Text styler.ColourTo(startLine + offset - 1 - wbl, SCE_TCMD_DEFAULT); wbo++; // check for %[nn] syntax if ( wordBuffer[1] == '[' ) { n++; while ((n < wbl) && (wordBuffer[n] != ']')) { n++; } if ( wordBuffer[n] == ']' ) n++; goto ColorizeArg; } // Search to end of word for second % or to the first terminator (can be a long path) while ((wbo < wbl) && (wordBuffer[wbo] != '%') && (!IsBOperator(wordBuffer[wbo])) && (!IsBSeparator(wordBuffer[wbo]))) { wbo++; } // Check for Argument (%n) or (%*) if (((isdigit(wordBuffer[1])) || (wordBuffer[1] == '*')) && (wordBuffer[wbo] != '%')) { while (( wordBuffer[n] ) && ( strchr( "%0123456789*#$", wordBuffer[n] ) != NULL )) n++; ColorizeArg: // Colorize Argument styler.ColourTo(startLine + offset - 1 - (wbl - n), SCE_TCMD_IDENTIFIER); // Reset Offset to re-process remainder of word offset -= (wbl - n); // Check for Variable with modifiers (%~...) } else if ((varlen = GetBatchVarLen(wordBuffer)) != 0) { // Colorize Variable styler.ColourTo(startLine + offset - 1 - (wbl - varlen), SCE_TCMD_IDENTIFIER); // Reset Offset to re-process remainder of word offset -= (wbl - varlen); // Check for Environment Variable (%x...%) } else if (( wordBuffer[1] ) && ( wordBuffer[1] != '%')) { if ( wordBuffer[wbo] == '%' ) wbo++; // Colorize Environment Variable styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_TCMD_ENVIRONMENT); // Reset Offset to re-process remainder of word offset -= (wbl - wbo); // Check for Local Variable (%%a) } else if ( (wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] != '%') && (!IsBOperator(wordBuffer[2])) && (!IsBSeparator(wordBuffer[2]))) { n = 2; while (( wordBuffer[n] ) && (!IsBOperator(wordBuffer[n])) && (!IsBSeparator(wordBuffer[n]))) n++; // Colorize Local Variable styler.ColourTo(startLine + offset - 1 - (wbl - n), SCE_TCMD_IDENTIFIER); // Reset Offset to re-process remainder of word offset -= (wbl - n); // Check for %% } else if ((wbl > 1) && (wordBuffer[1] == '%')) { // Colorize Symbols styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_TCMD_DEFAULT); // Reset Offset to re-process remainder of word offset -= (wbl - 2); } else { // Colorize Symbol styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_TCMD_DEFAULT); // Reset Offset to re-process remainder of word offset -= (wbl - 1); } // Check for Operator } else if (IsBOperator(wordBuffer[0])) { // Colorize Default Text styler.ColourTo(startLine + offset - 1 - wbl, SCE_TCMD_DEFAULT); // Check for Pipe, compound, or conditional Operator if ((wordBuffer[0] == '|') || (wordBuffer[0] == '&')) { // Colorize Pipe Operator styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_TCMD_OPERATOR); // Reset Offset to re-process remainder of word offset -= (wbl - 1); continueProcessing = true; // Check for Other Operator } else { // Check for > Operator if ((wordBuffer[0] == '>') || (wordBuffer[0] == '<')) { // Turn Keyword and External Command / Program checking back on continueProcessing = true; } // Colorize Other Operator if (!inString || !(wordBuffer[0] == '(' || wordBuffer[0] == ')')) styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_TCMD_OPERATOR); // Reset Offset to re-process remainder of word offset -= (wbl - 1); } // Check for Default Text } else { // Read up to %, Operator or Separator while ((wbo < wbl) && (wordBuffer[wbo] != '%') && (!isDelayedExpansion || wordBuffer[wbo] != '!') && (!IsBOperator(wordBuffer[wbo])) && (!IsBSeparator(wordBuffer[wbo]))) { wbo++; } // Colorize Default Text styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_TCMD_DEFAULT); // Reset Offset to re-process remainder of word offset -= (wbl - wbo); } // Skip whitespace - nothing happens if Offset was Reset while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { offset++; } } // Colorize Default Text for remainder of line - currently not lexed styler.ColourTo(endPos, SCE_TCMD_DEFAULT); } static void ColouriseTCMDDoc( unsigned int startPos, int length, int /*initStyle*/, WordList *keywordlists[], Accessor &styler ) { char lineBuffer[16384]; styler.StartAt(startPos); styler.StartSegment(startPos); unsigned int linePos = 0; unsigned int startLine = startPos; for (unsigned int i = startPos; i < startPos + length; i++) { lineBuffer[linePos++] = styler[i]; if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { // End of line (or of line buffer) met, colourise it lineBuffer[linePos] = '\0'; ColouriseTCMDLine(lineBuffer, linePos, startLine, i, keywordlists, styler); linePos = 0; startLine = i + 1; } } if (linePos > 0) { // Last line does not have ending characters lineBuffer[linePos] = '\0'; ColouriseTCMDLine(lineBuffer, linePos, startLine, startPos + length - 1, keywordlists, styler); } } // Convert string to upper case static void StrUpr(char *s) { while (*s) { *s = MakeUpperCase(*s); s++; } } // Folding support (for DO, IFF, SWITCH, TEXT, and command groups) static void FoldTCMDDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { int line = styler.GetLine(startPos); int level = styler.LevelAt(line); int levelIndent = 0; unsigned int endPos = startPos + length; char s[16]; char chPrev = styler.SafeGetCharAt(startPos - 1); // Scan for ( and ) for (unsigned int i = startPos; i < endPos; i++) { int c = styler.SafeGetCharAt(i, '\n'); int style = styler.StyleAt(i); bool bLineStart = ((chPrev == '\r') || (chPrev == '\n')) || i == 0; if (style == SCE_TCMD_OPERATOR) { // CheckFoldPoint if (c == '(') { levelIndent += 1; } else if (c == ')') { levelIndent -= 1; } } if (( bLineStart ) && ( style == SCE_TCMD_WORD )) { for (unsigned int j = 0; j < 10; j++) { if (!iswordchar(styler[i + j])) { break; } s[j] = styler[i + j]; s[j + 1] = '\0'; } StrUpr( s ); if ((strcmp(s, "DO") == 0) || (strcmp(s, "IFF") == 0) || (strcmp(s, "SWITCH") == 0) || (strcmp(s, "TEXT") == 0)) { levelIndent++; } else if ((strcmp(s, "ENDDO") == 0) || (strcmp(s, "ENDIFF") == 0) || (strcmp(s, "ENDSWITCH") == 0) || (strcmp(s, "ENDTEXT") == 0)) { levelIndent--; } } if (c == '\n') { // line end if (levelIndent > 0) { level |= SC_FOLDLEVELHEADERFLAG; } if (level != styler.LevelAt(line)) styler.SetLevel(line, level); level += levelIndent; if ((level & SC_FOLDLEVELNUMBERMASK) < SC_FOLDLEVELBASE) level = SC_FOLDLEVELBASE; line++; // reset state levelIndent = 0; level &= ~SC_FOLDLEVELHEADERFLAG; level &= ~SC_FOLDLEVELWHITEFLAG; } chPrev = c; } } static const char *const tcmdWordListDesc[] = { "Internal Commands", "Aliases", 0 }; LexerModule lmTCMD(SCLEX_TCMD, ColouriseTCMDDoc, "tcmd", FoldTCMDDoc, tcmdWordListDesc); |
Added lexers/LexTeX.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 |
// Scintilla source code edit control // File: LexTeX.cxx - general context conformant tex coloring scheme // Author: Hans Hagen - PRAGMA ADE - Hasselt NL - www.pragma-ade.com // Version: September 28, 2003 // Copyright: 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. // This lexer is derived from the one written for the texwork environment (1999++) which in // turn is inspired on texedit (1991++) which finds its roots in wdt (1986). // If you run into strange boundary cases, just tell me and I'll look into it. // TeX Folding code added by instanton (soft_share@126.com) with borrowed code from VisualTeX source by Alex Romanenko. // Version: June 22, 2007 #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // val SCE_TEX_DEFAULT = 0 // val SCE_TEX_SPECIAL = 1 // val SCE_TEX_GROUP = 2 // val SCE_TEX_SYMBOL = 3 // val SCE_TEX_COMMAND = 4 // val SCE_TEX_TEXT = 5 // Definitions in SciTEGlobal.properties: // // TeX Highlighting // // # Default // style.tex.0=fore:#7F7F00 // # Special // style.tex.1=fore:#007F7F // # Group // style.tex.2=fore:#880000 // # Symbol // style.tex.3=fore:#7F7F00 // # Command // style.tex.4=fore:#008800 // # Text // style.tex.5=fore:#000000 // lexer.tex.interface.default=0 // lexer.tex.comment.process=0 // todo: lexer.tex.auto.if // Auxiliary functions: static inline bool endOfLine(Accessor &styler, unsigned int i) { return (styler[i] == '\n') || ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')) ; } static inline bool isTeXzero(int ch) { return (ch == '%') ; } static inline bool isTeXone(int ch) { return (ch == '[') || (ch == ']') || (ch == '=') || (ch == '#') || (ch == '(') || (ch == ')') || (ch == '<') || (ch == '>') || (ch == '"') ; } static inline bool isTeXtwo(int ch) { return (ch == '{') || (ch == '}') || (ch == '$') ; } static inline bool isTeXthree(int ch) { return (ch == '~') || (ch == '^') || (ch == '_') || (ch == '&') || (ch == '-') || (ch == '+') || (ch == '\"') || (ch == '`') || (ch == '/') || (ch == '|') || (ch == '%') ; } static inline bool isTeXfour(int ch) { return (ch == '\\') ; } static inline bool isTeXfive(int ch) { return ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) || (ch == '@') || (ch == '!') || (ch == '?') ; } static inline bool isTeXsix(int ch) { return (ch == ' ') ; } static inline bool isTeXseven(int ch) { return (ch == '^') ; } // Interface determination static int CheckTeXInterface( unsigned int startPos, int length, Accessor &styler, int defaultInterface) { char lineBuffer[1024] ; unsigned int linePos = 0 ; // some day we can make something lexer.tex.mapping=(all,0)(nl,1)(en,2)... if (styler.SafeGetCharAt(0) == '%') { for (unsigned int i = 0; i < startPos + length; i++) { lineBuffer[linePos++] = styler.SafeGetCharAt(i) ; if (endOfLine(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { lineBuffer[linePos] = '\0'; if (strstr(lineBuffer, "interface=all")) { return 0 ; } else if (strstr(lineBuffer, "interface=tex")) { return 1 ; } else if (strstr(lineBuffer, "interface=nl")) { return 2 ; } else if (strstr(lineBuffer, "interface=en")) { return 3 ; } else if (strstr(lineBuffer, "interface=de")) { return 4 ; } else if (strstr(lineBuffer, "interface=cz")) { return 5 ; } else if (strstr(lineBuffer, "interface=it")) { return 6 ; } else if (strstr(lineBuffer, "interface=ro")) { return 7 ; } else if (strstr(lineBuffer, "interface=latex")) { // we will move latex cum suis up to 91+ when more keyword lists are supported return 8 ; } else if (styler.SafeGetCharAt(1) == 'D' && strstr(lineBuffer, "%D \\module")) { // better would be to limit the search to just one line return 3 ; } else { return defaultInterface ; } } } } return defaultInterface ; } static void ColouriseTeXDoc( unsigned int startPos, int length, int, WordList *keywordlists[], Accessor &styler) { styler.StartAt(startPos) ; styler.StartSegment(startPos) ; bool processComment = styler.GetPropertyInt("lexer.tex.comment.process", 0) == 1 ; bool useKeywords = styler.GetPropertyInt("lexer.tex.use.keywords", 1) == 1 ; bool autoIf = styler.GetPropertyInt("lexer.tex.auto.if", 1) == 1 ; int defaultInterface = styler.GetPropertyInt("lexer.tex.interface.default", 1) ; char key[100] ; int k ; bool newifDone = false ; bool inComment = false ; int currentInterface = CheckTeXInterface(startPos,length,styler,defaultInterface) ; if (currentInterface == 0) { useKeywords = false ; currentInterface = 1 ; } WordList &keywords = *keywordlists[currentInterface-1] ; StyleContext sc(startPos, length, SCE_TEX_TEXT, styler); bool going = sc.More() ; // needed because of a fuzzy end of file state for (; going; sc.Forward()) { if (! sc.More()) { going = false ; } // we need to go one behind the end of text if (inComment) { if (sc.atLineEnd) { sc.SetState(SCE_TEX_TEXT) ; newifDone = false ; inComment = false ; } } else { if (! isTeXfive(sc.ch)) { if (sc.state == SCE_TEX_COMMAND) { if (sc.LengthCurrent() == 1) { // \<noncstoken> if (isTeXseven(sc.ch) && isTeXseven(sc.chNext)) { sc.Forward(2) ; // \^^ and \^^<token> } sc.ForwardSetState(SCE_TEX_TEXT) ; } else { sc.GetCurrent(key, sizeof(key)-1) ; k = static_cast<int>(strlen(key)) ; memmove(key,key+1,k) ; // shift left over escape token key[k] = '\0' ; k-- ; if (! keywords || ! useKeywords) { sc.SetState(SCE_TEX_COMMAND) ; newifDone = false ; } else if (k == 1) { //\<cstoken> sc.SetState(SCE_TEX_COMMAND) ; newifDone = false ; } else if (keywords.InList(key)) { sc.SetState(SCE_TEX_COMMAND) ; newifDone = autoIf && (strcmp(key,"newif") == 0) ; } else if (autoIf && ! newifDone && (key[0] == 'i') && (key[1] == 'f') && keywords.InList("if")) { sc.SetState(SCE_TEX_COMMAND) ; } else { sc.ChangeState(SCE_TEX_TEXT) ; sc.SetState(SCE_TEX_TEXT) ; newifDone = false ; } } } if (isTeXzero(sc.ch)) { sc.SetState(SCE_TEX_SYMBOL); if (!endOfLine(styler,sc.currentPos + 1)) sc.ForwardSetState(SCE_TEX_DEFAULT) ; inComment = ! processComment ; newifDone = false ; } else if (isTeXseven(sc.ch) && isTeXseven(sc.chNext)) { sc.SetState(SCE_TEX_TEXT) ; sc.ForwardSetState(SCE_TEX_TEXT) ; } else if (isTeXone(sc.ch)) { sc.SetState(SCE_TEX_SPECIAL) ; newifDone = false ; } else if (isTeXtwo(sc.ch)) { sc.SetState(SCE_TEX_GROUP) ; newifDone = false ; } else if (isTeXthree(sc.ch)) { sc.SetState(SCE_TEX_SYMBOL) ; newifDone = false ; } else if (isTeXfour(sc.ch)) { sc.SetState(SCE_TEX_COMMAND) ; } else if (isTeXsix(sc.ch)) { sc.SetState(SCE_TEX_TEXT) ; } else if (sc.atLineEnd) { sc.SetState(SCE_TEX_TEXT) ; newifDone = false ; inComment = false ; } else { sc.SetState(SCE_TEX_TEXT) ; } } else if (sc.state != SCE_TEX_COMMAND) { sc.SetState(SCE_TEX_TEXT) ; } } } sc.ChangeState(SCE_TEX_TEXT) ; sc.Complete(); } static inline bool isNumber(int ch) { return (ch == '0') || (ch == '1') || (ch == '2') || (ch == '3') || (ch == '4') || (ch == '5') || (ch == '6') || (ch == '7') || (ch == '8') || (ch == '9'); } static inline bool isWordChar(int ch) { return ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')); } static int ParseTeXCommand(unsigned int pos, Accessor &styler, char *command) { int length=0; char ch=styler.SafeGetCharAt(pos+1); if(ch==',' || ch==':' || ch==';' || ch=='%'){ command[0]=ch; command[1]=0; return 1; } // find end while(isWordChar(ch) && !isNumber(ch) && ch!='_' && ch!='.' && length<100){ command[length]=ch; length++; ch=styler.SafeGetCharAt(pos+length+1); } command[length]='\0'; if(!length) return 0; return length+1; } static int classifyFoldPointTeXPaired(const char* s) { int lev=0; if (!(isdigit(s[0]) || (s[0] == '.'))){ if (strcmp(s, "begin")==0||strcmp(s,"FoldStart")==0|| strcmp(s,"abstract")==0||strcmp(s,"unprotect")==0|| strcmp(s,"title")==0||strncmp(s,"start",5)==0||strncmp(s,"Start",5)==0|| strcmp(s,"documentclass")==0||strncmp(s,"if",2)==0 ) lev=1; if (strcmp(s, "end")==0||strcmp(s,"FoldStop")==0|| strcmp(s,"maketitle")==0||strcmp(s,"protect")==0|| strncmp(s,"stop",4)==0||strncmp(s,"Stop",4)==0|| strcmp(s,"fi")==0 ) lev=-1; } return lev; } static int classifyFoldPointTeXUnpaired(const char* s) { int lev=0; if (!(isdigit(s[0]) || (s[0] == '.'))){ if (strcmp(s,"part")==0|| strcmp(s,"chapter")==0|| strcmp(s,"section")==0|| strcmp(s,"subsection")==0|| strcmp(s,"subsubsection")==0|| strcmp(s,"CJKfamily")==0|| strcmp(s,"appendix")==0|| strcmp(s,"Topic")==0||strcmp(s,"topic")==0|| strcmp(s,"subject")==0||strcmp(s,"subsubject")==0|| strcmp(s,"def")==0||strcmp(s,"gdef")==0||strcmp(s,"edef")==0|| strcmp(s,"xdef")==0||strcmp(s,"framed")==0|| strcmp(s,"frame")==0|| strcmp(s,"foilhead")==0||strcmp(s,"overlays")==0||strcmp(s,"slide")==0 ){ lev=1; } } return lev; } static bool IsTeXCommentLine(int line, Accessor &styler) { int pos = styler.LineStart(line); int eol_pos = styler.LineStart(line + 1) - 1; int startpos = pos; while (startpos<eol_pos){ char ch = styler[startpos]; if (ch!='%' && ch!=' ') return false; else if (ch=='%') return true; startpos++; } return false; } // FoldTeXDoc: borrowed from VisualTeX with modifications static void FoldTexDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos+length; int visibleChars=0; int lineCurrent=styler.GetLine(startPos); int levelPrev=styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent=levelPrev; char chNext=styler[startPos]; char buffer[100]=""; for (unsigned int i=startPos; i < endPos; i++) { char ch=chNext; chNext=styler.SafeGetCharAt(i+1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if(ch=='\\') { ParseTeXCommand(i, styler, buffer); levelCurrent += classifyFoldPointTeXPaired(buffer)+classifyFoldPointTeXUnpaired(buffer); } if (levelCurrent > SC_FOLDLEVELBASE && ((ch == '\r' || ch=='\n') && (chNext == '\\'))) { ParseTeXCommand(i+1, styler, buffer); levelCurrent -= classifyFoldPointTeXUnpaired(buffer); } char chNext2; char chNext3; char chNext4; char chNext5; chNext2=styler.SafeGetCharAt(i+2); chNext3=styler.SafeGetCharAt(i+3); chNext4=styler.SafeGetCharAt(i+4); chNext5=styler.SafeGetCharAt(i+5); bool atEOfold = (ch == '%') && (chNext == '%') && (chNext2=='}') && (chNext3=='}')&& (chNext4=='-')&& (chNext5=='-'); bool atBOfold = (ch == '%') && (chNext == '%') && (chNext2=='-') && (chNext3=='-')&& (chNext4=='{')&& (chNext5=='{'); if(atBOfold){ levelCurrent+=1; } if(atEOfold){ levelCurrent-=1; } if(ch=='\\' && chNext=='['){ levelCurrent+=1; } if(ch=='\\' && chNext==']'){ levelCurrent-=1; } bool foldComment = styler.GetPropertyInt("fold.comment") != 0; if (foldComment && atEOL && IsTeXCommentLine(lineCurrent, styler)) { if (lineCurrent==0 && IsTeXCommentLine(lineCurrent + 1, styler) ) levelCurrent++; else if (lineCurrent!=0 && !IsTeXCommentLine(lineCurrent - 1, styler) && IsTeXCommentLine(lineCurrent + 1, styler) ) levelCurrent++; else if (lineCurrent!=0 && IsTeXCommentLine(lineCurrent - 1, styler) && !IsTeXCommentLine(lineCurrent+1, styler)) levelCurrent--; } //--------------------------------------------------------------------------------------------- if (atEOL) { int lev = levelPrev; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if ((levelCurrent > levelPrev) && (visibleChars > 0)) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelPrev = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } static const char * const texWordListDesc[] = { "TeX, eTeX, pdfTeX, Omega", "ConTeXt Dutch", "ConTeXt English", "ConTeXt German", "ConTeXt Czech", "ConTeXt Italian", "ConTeXt Romanian", 0, } ; LexerModule lmTeX(SCLEX_TEX, ColouriseTeXDoc, "tex", FoldTexDoc, texWordListDesc); |
Added lexers/LexTxt2tags.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 |
/****************************************************************** * LexTxt2tags.cxx * * A simple Txt2tags lexer for scintilla. * * * Adapted by Eric Forgeot * Based on the LexMarkdown.cxx by Jon Strait - jstrait@moonloop.net * * What could be improved: * - Verbatim lines could be like for raw lines : when there is no space between the ``` and the following text, the first letter should be colored so the user would understand there must be a space for a valid tag. * - marks such as bold, italic, strikeout, underline should begin to be highlighted only when they are closed and valid. * - verbatim and raw area should be highlighted too. * * The License.txt file describes the conditions under which this * software may be distributed. * *****************************************************************/ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsNewline(const int ch) { return (ch == '\n' || ch == '\r'); } // True if can follow ch down to the end with possibly trailing whitespace static bool FollowToLineEnd(const int ch, const int state, const unsigned int endPos, StyleContext &sc) { unsigned int i = 0; while (sc.GetRelative(++i) == ch) ; // Skip over whitespace while (IsASpaceOrTab(sc.GetRelative(i)) && sc.currentPos + i < endPos) ++i; if (IsNewline(sc.GetRelative(i)) || sc.currentPos + i == endPos) { sc.Forward(i); sc.ChangeState(state); sc.SetState(SCE_TXT2TAGS_LINE_BEGIN); return true; } else return false; } // Does the previous line have more than spaces and tabs? static bool HasPrevLineContent(StyleContext &sc) { int i = 0; // Go back to the previous newline while ((--i + sc.currentPos) && !IsNewline(sc.GetRelative(i))) ; while (--i + sc.currentPos) { if (IsNewline(sc.GetRelative(i))) break; if (!IsASpaceOrTab(sc.GetRelative(i))) return true; } return false; } // Separator line static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) { int c, count = 1; unsigned int i = 0; while (++i) { c = sc.GetRelative(i); if (c == sc.ch) ++count; // hit a terminating character else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) { // Are we a valid HRULE if ((IsNewline(c) || sc.currentPos + i == endPos) && count >= 20 && !HasPrevLineContent(sc)) { sc.SetState(SCE_TXT2TAGS_HRULE); sc.Forward(i); sc.SetState(SCE_TXT2TAGS_LINE_BEGIN); return true; } else { sc.SetState(SCE_TXT2TAGS_DEFAULT); return false; } } } return false; } static void ColorizeTxt2tagsDoc(unsigned int startPos, int length, int initStyle, WordList **, Accessor &styler) { unsigned int endPos = startPos + length; int precharCount = 0; // Don't advance on a new loop iteration and retry at the same position. // Useful in the corner case of having to start at the beginning file position // in the default state. bool freezeCursor = false; StyleContext sc(startPos, length, initStyle, styler); while (sc.More()) { // Skip past escaped characters if (sc.ch == '\\') { sc.Forward(); continue; } // A blockquotes resets the line semantics if (sc.state == SCE_TXT2TAGS_BLOCKQUOTE){ sc.Forward(2); sc.SetState(SCE_TXT2TAGS_LINE_BEGIN); } // An option colors the whole line if (sc.state == SCE_TXT2TAGS_OPTION){ FollowToLineEnd('%', SCE_TXT2TAGS_OPTION, endPos, sc); } if (sc.state == SCE_TXT2TAGS_POSTPROC){ FollowToLineEnd('%', SCE_TXT2TAGS_POSTPROC, endPos, sc); } if (sc.state == SCE_TXT2TAGS_PREPROC){ FollowToLineEnd('%', SCE_TXT2TAGS_PREPROC, endPos, sc); } // A comment colors the whole line if (sc.state == SCE_TXT2TAGS_COMMENT){ FollowToLineEnd('%', SCE_TXT2TAGS_COMMENT, endPos, sc); } // Conditional state-based actions if (sc.state == SCE_TXT2TAGS_CODE2) { if (IsNewline(sc.ch)) sc.SetState(SCE_TXT2TAGS_LINE_BEGIN); if (sc.Match("``") && sc.GetRelative(-2) != ' ') { sc.Forward(2); sc.SetState(SCE_TXT2TAGS_DEFAULT); } } // Table else if (sc.state == SCE_TXT2TAGS_CODE) { if (IsNewline(sc.ch)) sc.SetState(SCE_TXT2TAGS_LINE_BEGIN); if (sc.ch == '|' && sc.chPrev != ' ') sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT); } // Strong else if (sc.state == SCE_TXT2TAGS_STRONG1) { if (IsNewline(sc.ch)) sc.SetState(SCE_TXT2TAGS_LINE_BEGIN); if (sc.Match("**") && sc.chPrev != ' ') { sc.Forward(2); sc.SetState(SCE_TXT2TAGS_DEFAULT); } } // Emphasis else if (sc.state == SCE_TXT2TAGS_EM1) { if (IsNewline(sc.ch)) sc.SetState(SCE_TXT2TAGS_LINE_BEGIN); if (sc.Match("//") && sc.chPrev != ' ') { sc.Forward(2); sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT); } } // Underline else if (sc.state == SCE_TXT2TAGS_EM2) { if (IsNewline(sc.ch)) sc.SetState(SCE_TXT2TAGS_LINE_BEGIN); if (sc.Match("__") && sc.chPrev != ' ') { sc.Forward(2); sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT); } } // codeblock else if (sc.state == SCE_TXT2TAGS_CODEBK) { if (IsNewline(sc.ch)) sc.SetState(SCE_TXT2TAGS_LINE_BEGIN); if (sc.atLineStart && sc.Match("```")) { int i = 1; while (!IsNewline(sc.GetRelative(i)) && sc.currentPos + i < endPos) i++; sc.Forward(i); sc.SetState(SCE_TXT2TAGS_DEFAULT); } } // strikeout else if (sc.state == SCE_TXT2TAGS_STRIKEOUT) { if (IsNewline(sc.ch)) sc.SetState(SCE_TXT2TAGS_LINE_BEGIN); if (sc.Match("--") && sc.chPrev != ' ') { sc.Forward(2); sc.SetState(SCE_TXT2TAGS_DEFAULT); } } // Headers else if (sc.state == SCE_TXT2TAGS_LINE_BEGIN) { if (sc.Match("======")) { sc.SetState(SCE_TXT2TAGS_HEADER6); sc.Forward(); } else if (sc.Match("=====")) { sc.SetState(SCE_TXT2TAGS_HEADER5); sc.Forward(); } else if (sc.Match("====")) { sc.SetState(SCE_TXT2TAGS_HEADER4); sc.Forward(); } else if (sc.Match("===")) { sc.SetState(SCE_TXT2TAGS_HEADER3); sc.Forward(); } //SetStateAndZoom(SCE_TXT2TAGS_HEADER3, 3, '=', sc); else if (sc.Match("==")) { sc.SetState(SCE_TXT2TAGS_HEADER2); sc.Forward(); } //SetStateAndZoom(SCE_TXT2TAGS_HEADER2, 2, '=', sc); else if (sc.Match("=")) { // Catch the special case of an unordered list if (sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) { precharCount = 0; sc.SetState(SCE_TXT2TAGS_PRECHAR); } else { sc.SetState(SCE_TXT2TAGS_HEADER1); sc.Forward(); } //SetStateAndZoom(SCE_TXT2TAGS_HEADER1, 1, '=', sc); } // Numbered title else if (sc.Match("++++++")) { sc.SetState(SCE_TXT2TAGS_HEADER6); sc.Forward(); } else if (sc.Match("+++++")) { sc.SetState(SCE_TXT2TAGS_HEADER5); sc.Forward(); } else if (sc.Match("++++")) { sc.SetState(SCE_TXT2TAGS_HEADER4); sc.Forward(); } else if (sc.Match("+++")) { sc.SetState(SCE_TXT2TAGS_HEADER3); sc.Forward(); } //SetStateAndZoom(SCE_TXT2TAGS_HEADER3, 3, '+', sc); else if (sc.Match("++")) { sc.SetState(SCE_TXT2TAGS_HEADER2); sc.Forward(); } //SetStateAndZoom(SCE_TXT2TAGS_HEADER2, 2, '+', sc); else if (sc.Match("+")) { // Catch the special case of an unordered list if (sc.chNext == ' ' && IsASpaceOrTab(sc.GetRelative(1))) { // if (IsNewline(sc.ch)) { //precharCount = 0; // sc.SetState(SCE_TXT2TAGS_LINE_BEGIN); //sc.SetState(SCE_TXT2TAGS_PRECHAR); // } // else { // precharCount = 0; sc.SetState(SCE_TXT2TAGS_OLIST_ITEM); sc.Forward(2); sc.SetState(SCE_TXT2TAGS_DEFAULT); // sc.SetState(SCE_TXT2TAGS_PRECHAR); // } } else { sc.SetState(SCE_TXT2TAGS_HEADER1); sc.Forward(); } } // Codeblock else if (sc.Match("```")) { if (!HasPrevLineContent(sc)) // if (!FollowToLineEnd(sc)) sc.SetState(SCE_TXT2TAGS_CODEBK); else sc.SetState(SCE_TXT2TAGS_DEFAULT); } // Preproc else if (sc.Match("%!preproc")) { sc.SetState(SCE_TXT2TAGS_PREPROC); } // Postproc else if (sc.Match("%!postproc")) { sc.SetState(SCE_TXT2TAGS_POSTPROC); } // Option else if (sc.Match("%!")) { sc.SetState(SCE_TXT2TAGS_OPTION); } // Comment else if (sc.ch == '%') { sc.SetState(SCE_TXT2TAGS_COMMENT); } // list else if (sc.ch == '-') { precharCount = 0; sc.SetState(SCE_TXT2TAGS_PRECHAR); } // def list else if (sc.ch == ':') { precharCount = 0; sc.SetState(SCE_TXT2TAGS_OLIST_ITEM); sc.Forward(1); sc.SetState(SCE_TXT2TAGS_PRECHAR); } else if (IsNewline(sc.ch)) sc.SetState(SCE_TXT2TAGS_LINE_BEGIN); else { precharCount = 0; sc.SetState(SCE_TXT2TAGS_PRECHAR); } } // The header lasts until the newline else if (sc.state == SCE_TXT2TAGS_HEADER1 || sc.state == SCE_TXT2TAGS_HEADER2 || sc.state == SCE_TXT2TAGS_HEADER3 || sc.state == SCE_TXT2TAGS_HEADER4 || sc.state == SCE_TXT2TAGS_HEADER5 || sc.state == SCE_TXT2TAGS_HEADER6) { if (IsNewline(sc.ch)) sc.SetState(SCE_TXT2TAGS_LINE_BEGIN); } // New state only within the initial whitespace if (sc.state == SCE_TXT2TAGS_PRECHAR) { // Blockquote if (sc.Match("\"\"\"") && precharCount < 5){ sc.SetState(SCE_TXT2TAGS_BLOCKQUOTE); sc.Forward(1); } /* // Begin of code block else if (!HasPrevLineContent(sc) && (sc.chPrev == '\t' || precharCount >= 4)) sc.SetState(SCE_TXT2TAGS_CODEBK); */ // HRule - Total of 20 or more hyphens, asterisks, or underscores // on a line by themselves else if ((sc.ch == '-' ) && IsValidHrule(endPos, sc)) ; // Unordered list else if ((sc.ch == '-') && IsASpaceOrTab(sc.chNext)) { sc.SetState(SCE_TXT2TAGS_ULIST_ITEM); sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT); } // Ordered list else if (IsADigit(sc.ch)) { int digitCount = 0; while (IsADigit(sc.GetRelative(++digitCount))) ; if (sc.GetRelative(digitCount) == '.' && IsASpaceOrTab(sc.GetRelative(digitCount + 1))) { sc.SetState(SCE_TXT2TAGS_OLIST_ITEM); sc.Forward(digitCount + 1); sc.SetState(SCE_TXT2TAGS_DEFAULT); } } // Alternate Ordered list else if (sc.ch == '+' && sc.chNext == ' ' && IsASpaceOrTab(sc.GetRelative(2))) { // sc.SetState(SCE_TXT2TAGS_OLIST_ITEM); // sc.Forward(2); // sc.SetState(SCE_TXT2TAGS_DEFAULT); } else if (sc.ch != ' ' || precharCount > 2) sc.SetState(SCE_TXT2TAGS_DEFAULT); else ++precharCount; } // New state anywhere in doc if (sc.state == SCE_TXT2TAGS_DEFAULT) { // if (sc.atLineStart && sc.ch == '#') { // sc.SetState(SCE_TXT2TAGS_LINE_BEGIN); // freezeCursor = true; // } // Links and Images if (sc.Match("![") || sc.ch == '[') { int i = 0, j = 0, k = 0; int len = endPos - sc.currentPos; while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\')) ; if (sc.GetRelative(i) == ']') { j = i; if (sc.GetRelative(++i) == '(') { while (i < len && (sc.GetRelative(++i) != '(' || sc.GetRelative(i - 1) == '\\')) ; if (sc.GetRelative(i) == '(') k = i; } else if (sc.GetRelative(i) == '[' || sc.GetRelative(++i) == '[') { while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\')) ; if (sc.GetRelative(i) == ']') k = i; } } // At least a link text if (j) { sc.SetState(SCE_TXT2TAGS_LINK); sc.Forward(j); // Also has a URL or reference portion if (k) sc.Forward(k - j); sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT); } } // Code - also a special case for alternate inside spacing if (sc.Match("``") && sc.GetRelative(3) != ' ') { sc.SetState(SCE_TXT2TAGS_CODE2); sc.Forward(); } else if (sc.ch == '|' && sc.GetRelative(3) != ' ') { sc.SetState(SCE_TXT2TAGS_CODE); } // Strong else if (sc.Match("**") && sc.GetRelative(2) != ' ') { sc.SetState(SCE_TXT2TAGS_STRONG1); sc.Forward(); } // Emphasis else if (sc.Match("//") && sc.GetRelative(2) != ' ') { sc.SetState(SCE_TXT2TAGS_EM1); sc.Forward(); } else if (sc.Match("__") && sc.GetRelative(2) != ' ') { sc.SetState(SCE_TXT2TAGS_EM2); sc.Forward(); } // Strikeout else if (sc.Match("--") && sc.GetRelative(2) != ' ') { sc.SetState(SCE_TXT2TAGS_STRIKEOUT); sc.Forward(); } // Beginning of line else if (IsNewline(sc.ch)) sc.SetState(SCE_TXT2TAGS_LINE_BEGIN); } // Advance if not holding back the cursor for this iteration. if (!freezeCursor) sc.Forward(); freezeCursor = false; } sc.Complete(); } LexerModule lmTxt2tags(SCLEX_TXT2TAGS, ColorizeTxt2tagsDoc, "txt2tags"); |
Added lexers/LexVB.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 |
// Scintilla source code edit control /** @file LexVB.cxx ** Lexer for Visual Basic and VBScript. **/ // Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // Internal state, highlighted as number #define SCE_B_FILENUMBER SCE_B_DEFAULT+100 static bool IsVBComment(Accessor &styler, int pos, int len) { return len > 0 && styler[pos] == '\''; } static inline bool IsTypeCharacter(int ch) { return ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$'; } // Extended to accept accented characters static inline bool IsAWordChar(int ch) { return ch >= 0x80 || (isalnum(ch) || ch == '.' || ch == '_'); } static inline bool IsAWordStart(int ch) { return ch >= 0x80 || (isalpha(ch) || ch == '_'); } static inline bool IsANumberChar(int ch) { // Not exactly following number definition (several dots are seen as OK, etc.) // but probably enough in most cases. return (ch < 0x80) && (isdigit(ch) || toupper(ch) == 'E' || ch == '.' || ch == '-' || ch == '+'); } static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler, bool vbScriptSyntax) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; styler.StartAt(startPos); int visibleChars = 0; int fileNbDigits = 0; // Do not leak onto next line if (initStyle == SCE_B_STRINGEOL || initStyle == SCE_B_COMMENT || initStyle == SCE_B_PREPROCESSOR) { initStyle = SCE_B_DEFAULT; } StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.state == SCE_B_OPERATOR) { sc.SetState(SCE_B_DEFAULT); } else if (sc.state == SCE_B_IDENTIFIER) { if (!IsAWordChar(sc.ch)) { // In Basic (except VBScript), a variable name or a function name // can end with a special character indicating the type of the value // held or returned. bool skipType = false; if (!vbScriptSyntax && IsTypeCharacter(sc.ch)) { sc.Forward(); // Skip it skipType = true; } if (sc.ch == ']') { sc.Forward(); } char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (skipType) { s[strlen(s) - 1] = '\0'; } if (strcmp(s, "rem") == 0) { sc.ChangeState(SCE_B_COMMENT); } else { if (keywords.InList(s)) { sc.ChangeState(SCE_B_KEYWORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_B_KEYWORD2); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_B_KEYWORD3); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_B_KEYWORD4); } // Else, it is really an identifier... sc.SetState(SCE_B_DEFAULT); } } } else if (sc.state == SCE_B_NUMBER) { // We stop the number definition on non-numerical non-dot non-eE non-sign char // Also accepts A-F for hex. numbers if (!IsANumberChar(sc.ch) && !(tolower(sc.ch) >= 'a' && tolower(sc.ch) <= 'f')) { sc.SetState(SCE_B_DEFAULT); } } else if (sc.state == SCE_B_STRING) { // VB doubles quotes to preserve them, so just end this string // state now as a following quote will start again if (sc.ch == '\"') { if (sc.chNext == '\"') { sc.Forward(); } else { if (tolower(sc.chNext) == 'c') { sc.Forward(); } sc.ForwardSetState(SCE_B_DEFAULT); } } else if (sc.atLineEnd) { visibleChars = 0; sc.ChangeState(SCE_B_STRINGEOL); sc.ForwardSetState(SCE_B_DEFAULT); } } else if (sc.state == SCE_B_COMMENT) { if (sc.atLineEnd) { visibleChars = 0; sc.ForwardSetState(SCE_B_DEFAULT); } } else if (sc.state == SCE_B_PREPROCESSOR) { if (sc.atLineEnd) { visibleChars = 0; sc.ForwardSetState(SCE_B_DEFAULT); } } else if (sc.state == SCE_B_FILENUMBER) { if (IsADigit(sc.ch)) { fileNbDigits++; if (fileNbDigits > 3) { sc.ChangeState(SCE_B_DATE); } } else if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ',') { // Regular uses: Close #1; Put #1, ...; Get #1, ... etc. // Too bad if date is format #27, Oct, 2003# or something like that... // Use regular number state sc.ChangeState(SCE_B_NUMBER); sc.SetState(SCE_B_DEFAULT); } else if (sc.ch == '#') { sc.ChangeState(SCE_B_DATE); sc.ForwardSetState(SCE_B_DEFAULT); } else { sc.ChangeState(SCE_B_DATE); } if (sc.state != SCE_B_FILENUMBER) { fileNbDigits = 0; } } else if (sc.state == SCE_B_DATE) { if (sc.atLineEnd) { visibleChars = 0; sc.ChangeState(SCE_B_STRINGEOL); sc.ForwardSetState(SCE_B_DEFAULT); } else if (sc.ch == '#') { sc.ForwardSetState(SCE_B_DEFAULT); } } if (sc.state == SCE_B_DEFAULT) { if (sc.ch == '\'') { sc.SetState(SCE_B_COMMENT); } else if (sc.ch == '\"') { sc.SetState(SCE_B_STRING); } else if (sc.ch == '#' && visibleChars == 0) { // Preprocessor commands are alone on their line sc.SetState(SCE_B_PREPROCESSOR); } else if (sc.ch == '#') { // It can be a date literal, ending with #, or a file number, from 1 to 511 // The date literal depends on the locale, so anything can go between #'s. // Can be #January 1, 1993# or #1 Jan 93# or #05/11/2003#, etc. // So we set the FILENUMBER state, and switch to DATE if it isn't a file number sc.SetState(SCE_B_FILENUMBER); } else if (sc.ch == '&' && tolower(sc.chNext) == 'h') { // Hexadecimal number sc.SetState(SCE_B_NUMBER); sc.Forward(); } else if (sc.ch == '&' && tolower(sc.chNext) == 'o') { // Octal number sc.SetState(SCE_B_NUMBER); sc.Forward(); } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_B_NUMBER); } else if (IsAWordStart(sc.ch) || (sc.ch == '[')) { sc.SetState(SCE_B_IDENTIFIER); } else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) { // Integer division sc.SetState(SCE_B_OPERATOR); } } if (sc.atLineEnd) { visibleChars = 0; } if (!IsASpace(sc.ch)) { visibleChars++; } } if (sc.state == SCE_B_IDENTIFIER && !IsAWordChar(sc.ch)) { // In Basic (except VBScript), a variable name or a function name // can end with a special character indicating the type of the value // held or returned. bool skipType = false; if (!vbScriptSyntax && IsTypeCharacter(sc.ch)) { sc.Forward(); // Skip it skipType = true; } if (sc.ch == ']') { sc.Forward(); } char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (skipType) { s[strlen(s) - 1] = '\0'; } if (strcmp(s, "rem") == 0) { sc.ChangeState(SCE_B_COMMENT); } else { if (keywords.InList(s)) { sc.ChangeState(SCE_B_KEYWORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_B_KEYWORD2); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_B_KEYWORD3); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_B_KEYWORD4); } // Else, it is really an identifier... sc.SetState(SCE_B_DEFAULT); } } sc.Complete(); } static void FoldVBDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) { int endPos = startPos + length; // Backtrack to previous line in case need to fix its fold status int lineCurrent = styler.GetLine(startPos); if (startPos > 0) { if (lineCurrent > 0) { lineCurrent--; startPos = styler.LineStart(lineCurrent); } } int spaceFlags = 0; int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsVBComment); char chNext = styler[startPos]; for (int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) { int lev = indentCurrent; int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsVBComment); if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { // Only non whitespace lines can be headers if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) { lev |= SC_FOLDLEVELHEADERFLAG; } else if (indentNext & SC_FOLDLEVELWHITEFLAG) { // Line after is blank so check the next - maybe should continue further? int spaceFlags2 = 0; int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsVBComment); if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) { lev |= SC_FOLDLEVELHEADERFLAG; } } } indentCurrent = indentNext; styler.SetLevel(lineCurrent, lev); lineCurrent++; } } } static void ColouriseVBNetDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { ColouriseVBDoc(startPos, length, initStyle, keywordlists, styler, false); } static void ColouriseVBScriptDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { ColouriseVBDoc(startPos, length, initStyle, keywordlists, styler, true); } static const char * const vbWordListDesc[] = { "Keywords", "user1", "user2", "user3", 0 }; LexerModule lmVB(SCLEX_VB, ColouriseVBNetDoc, "vb", FoldVBDoc, vbWordListDesc); LexerModule lmVBScript(SCLEX_VBSCRIPT, ColouriseVBScriptDoc, "vbscript", FoldVBDoc, vbWordListDesc); |
Added lexers/LexVHDL.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 |
// Scintilla source code edit control /** @file LexVHDL.cxx ** Lexer for VHDL ** Written by Phil Reid, ** Based on: ** - The Verilog Lexer by Avi Yegudin ** - The Fortran Lexer by Chuan-jian Shen ** - The C++ lexer by Neil Hodgson **/ // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static void ColouriseVHDLDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler); /***************************************/ static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' ); } /***************************************/ static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_'); } /***************************************/ inline bool IsABlank(unsigned int ch) { return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ; } /***************************************/ static void ColouriseVHDLDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &Keywords = *keywordlists[0]; WordList &Operators = *keywordlists[1]; WordList &Attributes = *keywordlists[2]; WordList &Functions = *keywordlists[3]; WordList &Packages = *keywordlists[4]; WordList &Types = *keywordlists[5]; WordList &User = *keywordlists[6]; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { // Determine if the current state should terminate. if (sc.state == SCE_VHDL_OPERATOR) { sc.SetState(SCE_VHDL_DEFAULT); } else if (sc.state == SCE_VHDL_NUMBER) { if (!IsAWordChar(sc.ch) && (sc.ch != '#')) { sc.SetState(SCE_VHDL_DEFAULT); } } else if (sc.state == SCE_VHDL_IDENTIFIER) { if (!IsAWordChar(sc.ch) || (sc.ch == '.')) { char s[100]; sc.GetCurrentLowered(s, sizeof(s)); if (Keywords.InList(s)) { sc.ChangeState(SCE_VHDL_KEYWORD); } else if (Operators.InList(s)) { sc.ChangeState(SCE_VHDL_STDOPERATOR); } else if (Attributes.InList(s)) { sc.ChangeState(SCE_VHDL_ATTRIBUTE); } else if (Functions.InList(s)) { sc.ChangeState(SCE_VHDL_STDFUNCTION); } else if (Packages.InList(s)) { sc.ChangeState(SCE_VHDL_STDPACKAGE); } else if (Types.InList(s)) { sc.ChangeState(SCE_VHDL_STDTYPE); } else if (User.InList(s)) { sc.ChangeState(SCE_VHDL_USERWORD); } sc.SetState(SCE_VHDL_DEFAULT); } } else if (sc.state == SCE_VHDL_COMMENT || sc.state == SCE_VHDL_COMMENTLINEBANG) { if (sc.atLineEnd) { sc.SetState(SCE_VHDL_DEFAULT); } } else if (sc.state == SCE_VHDL_STRING) { if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_VHDL_DEFAULT); } else if (sc.atLineEnd) { sc.ChangeState(SCE_VHDL_STRINGEOL); sc.ForwardSetState(SCE_VHDL_DEFAULT); } } // Determine if a new state should be entered. if (sc.state == SCE_VHDL_DEFAULT) { if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_VHDL_NUMBER); } else if (IsAWordStart(sc.ch)) { sc.SetState(SCE_VHDL_IDENTIFIER); } else if (sc.Match('-', '-')) { if (sc.Match("--!")) // Nice to have a different comment style sc.SetState(SCE_VHDL_COMMENTLINEBANG); else sc.SetState(SCE_VHDL_COMMENT); } else if (sc.ch == '\"') { sc.SetState(SCE_VHDL_STRING); } else if (isoperator(static_cast<char>(sc.ch))) { sc.SetState(SCE_VHDL_OPERATOR); } } } sc.Complete(); } //============================================================================= static bool IsCommentLine(int line, Accessor &styler) { int pos = styler.LineStart(line); int eol_pos = styler.LineStart(line + 1) - 1; for (int i = pos; i < eol_pos; i++) { char ch = styler[i]; char chNext = styler[i+1]; if ((ch == '-') && (chNext == '-')) return true; else if (ch != ' ' && ch != '\t') return false; } return false; } //============================================================================= // Folding the code static void FoldNoBoxVHDLDoc( unsigned int startPos, int length, int, Accessor &styler) { // Decided it would be smarter to have the lexer have all keywords included. Therefore I // don't check if the style for the keywords that I use to adjust the levels. char words[] = "architecture begin case component else elsif end entity generate loop package process record then " "procedure function when"; WordList keywords; keywords.Set(words); bool foldComment = styler.GetPropertyInt("fold.comment", 1) != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 1) != 0; bool foldAtBegin = styler.GetPropertyInt("fold.at.Begin", 1) != 0; bool foldAtParenthese = styler.GetPropertyInt("fold.at.Parenthese", 1) != 0; //bool foldAtWhen = styler.GetPropertyInt("fold.at.When", 1) != 0; //< fold at when in case statements int visibleChars = 0; unsigned int endPos = startPos + length; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if(lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; //int levelMinCurrent = levelCurrent; int levelMinCurrentElse = levelCurrent; //< Used for folding at 'else' int levelMinCurrentBegin = levelCurrent; //< Used for folding at 'begin' int levelNext = levelCurrent; /***************************************/ int lastStart = 0; char prevWord[32] = ""; /***************************************/ // Find prev word // The logic for going up or down a level depends on a the previous keyword // This code could be cleaned up. int end = 0; unsigned int j; for(j = startPos; j>0; j--) { char ch = styler.SafeGetCharAt(j); char chPrev = styler.SafeGetCharAt(j-1); int style = styler.StyleAt(j); int stylePrev = styler.StyleAt(j-1); if ((stylePrev != SCE_VHDL_COMMENT) && (stylePrev != SCE_VHDL_STRING)) { if(IsAWordChar(chPrev) && !IsAWordChar(ch)) { end = j-1; } } if ((style != SCE_VHDL_COMMENT) && (style != SCE_VHDL_STRING)) { if(!IsAWordChar(chPrev) && IsAWordStart(ch) && (end != 0)) { char s[32]; unsigned int k; for(k=0; (k<31 ) && (k<end-j+1 ); k++) { s[k] = static_cast<char>(tolower(styler[j+k])); } s[k] = '\0'; if(keywords.InList(s)) { strcpy(prevWord, s); break; } } } } for(j=j+static_cast<unsigned int>(strlen(prevWord)); j<endPos; j++) { char ch = styler.SafeGetCharAt(j); int style = styler.StyleAt(j); if ((style != SCE_VHDL_COMMENT) && (style != SCE_VHDL_STRING)) { if((ch == ';') && (strcmp(prevWord, "end") == 0)) { strcpy(prevWord, ";"); } } } char chNext = styler[startPos]; char chPrev = '\0'; char chNextNonBlank; int styleNext = styler.StyleAt(startPos); //Platform::DebugPrintf("Line[%04d] Prev[%20s] ************************* Level[%x]\n", lineCurrent+1, prevWord, levelCurrent); /***************************************/ for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); chPrev = styler.SafeGetCharAt(i - 1); chNextNonBlank = chNext; unsigned int j = i+1; while(IsABlank(chNextNonBlank) && j<endPos) { j ++ ; chNextNonBlank = styler.SafeGetCharAt(j); } int style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment && atEOL && IsCommentLine(lineCurrent, styler)) { if(!IsCommentLine(lineCurrent-1, styler) && IsCommentLine(lineCurrent+1, styler)) { levelNext++; } else if(IsCommentLine(lineCurrent-1, styler) && !IsCommentLine(lineCurrent+1, styler)) { levelNext--; } } if ((style == SCE_VHDL_OPERATOR) && foldAtParenthese) { if(ch == '(') { levelNext++; } else if (ch == ')') { levelNext--; } } if ((style != SCE_VHDL_COMMENT) && (style != SCE_VHDL_STRING)) { if((ch == ';') && (strcmp(prevWord, "end") == 0)) { strcpy(prevWord, ";"); } if(!IsAWordChar(chPrev) && IsAWordStart(ch)) { lastStart = i; } if(iswordchar(ch) && !iswordchar(chNext)) { char s[32]; unsigned int k; for(k=0; (k<31 ) && (k<i-lastStart+1 ); k++) { s[k] = static_cast<char>(tolower(styler[lastStart+k])); } s[k] = '\0'; if(keywords.InList(s)) { if ( strcmp(s, "architecture") == 0 || strcmp(s, "case") == 0 || strcmp(s, "component") == 0 || strcmp(s, "entity") == 0 || strcmp(s, "generate") == 0 || strcmp(s, "loop") == 0 || strcmp(s, "package") ==0 || strcmp(s, "process") == 0 || strcmp(s, "record") == 0 || strcmp(s, "then") == 0) { if (strcmp(prevWord, "end") != 0) { if (levelMinCurrentElse > levelNext) { levelMinCurrentElse = levelNext; } levelNext++; } } else if ( strcmp(s, "procedure") == 0 || strcmp(s, "function") == 0) { if (strcmp(prevWord, "end") != 0) // check for "end procedure" etc. { // This code checks to see if the procedure / function is a definition within a "package" // rather than the actual code in the body. int BracketLevel = 0; for(int j=i+1; j<styler.Length(); j++) { int LocalStyle = styler.StyleAt(j); char LocalCh = styler.SafeGetCharAt(j); if(LocalCh == '(') BracketLevel++; if(LocalCh == ')') BracketLevel--; if( (BracketLevel == 0) && (LocalStyle != SCE_VHDL_COMMENT) && (LocalStyle != SCE_VHDL_STRING) && !iswordchar(styler.SafeGetCharAt(j-1)) && styler.Match(j, "is") && !iswordchar(styler.SafeGetCharAt(j+2))) { if (levelMinCurrentElse > levelNext) { levelMinCurrentElse = levelNext; } levelNext++; break; } if((BracketLevel == 0) && (LocalCh == ';')) { break; } } } } else if (strcmp(s, "end") == 0) { levelNext--; } else if(strcmp(s, "elsif") == 0) { // elsif is followed by then so folding occurs correctly levelNext--; } else if (strcmp(s, "else") == 0) { if(strcmp(prevWord, "when") != 0) // ignore a <= x when y else z; { levelMinCurrentElse = levelNext - 1; // VHDL else is all on its own so just dec. the min level } } else if( ((strcmp(s, "begin") == 0) && (strcmp(prevWord, "architecture") == 0)) || ((strcmp(s, "begin") == 0) && (strcmp(prevWord, "function") == 0)) || ((strcmp(s, "begin") == 0) && (strcmp(prevWord, "procedure") == 0))) { levelMinCurrentBegin = levelNext - 1; } //Platform::DebugPrintf("Line[%04d] Prev[%20s] Cur[%20s] Level[%x]\n", lineCurrent+1, prevWord, s, levelCurrent); strcpy(prevWord, s); } } } if (atEOL) { int levelUse = levelCurrent; if (foldAtElse && (levelMinCurrentElse < levelUse)) { levelUse = levelMinCurrentElse; } if (foldAtBegin && (levelMinCurrentBegin < levelUse)) { levelUse = levelMinCurrentBegin; } int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } //Platform::DebugPrintf("Line[%04d] ---------------------------------------------------- Level[%x]\n", lineCurrent+1, levelCurrent); lineCurrent++; levelCurrent = levelNext; //levelMinCurrent = levelCurrent; levelMinCurrentElse = levelCurrent; levelMinCurrentBegin = levelCurrent; visibleChars = 0; } /***************************************/ if (!isspacechar(ch)) visibleChars++; } /***************************************/ // Platform::DebugPrintf("Line[%04d] ---------------------------------------------------- Level[%x]\n", lineCurrent+1, levelCurrent); } //============================================================================= static void FoldVHDLDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { FoldNoBoxVHDLDoc(startPos, length, initStyle, styler); } //============================================================================= static const char * const VHDLWordLists[] = { "Keywords", "Operators", "Attributes", "Standard Functions", "Standard Packages", "Standard Types", "User Words", 0, }; LexerModule lmVHDL(SCLEX_VHDL, ColouriseVHDLDoc, "vhdl", FoldVHDLDoc, VHDLWordLists); // Keyword: // access after alias all architecture array assert attribute begin block body buffer bus case component // configuration constant disconnect downto else elsif end entity exit file for function generate generic // group guarded if impure in inertial inout is label library linkage literal loop map new next null of // on open others out package port postponed procedure process pure range record register reject report // return select severity shared signal subtype then to transport type unaffected units until use variable // wait when while with // // Operators: // abs and mod nand nor not or rem rol ror sla sll sra srl xnor xor // // Attributes: // left right low high ascending image value pos val succ pred leftof rightof base range reverse_range // length delayed stable quiet transaction event active last_event last_active last_value driving // driving_value simple_name path_name instance_name // // Std Functions: // now readline read writeline write endfile resolved to_bit to_bitvector to_stdulogic to_stdlogicvector // to_stdulogicvector to_x01 to_x01z to_UX01 rising_edge falling_edge is_x shift_left shift_right rotate_left // rotate_right resize to_integer to_unsigned to_signed std_match to_01 // // Std Packages: // std ieee work standard textio std_logic_1164 std_logic_arith std_logic_misc std_logic_signed // std_logic_textio std_logic_unsigned numeric_bit numeric_std math_complex math_real vital_primitives // vital_timing // // Std Types: // boolean bit character severity_level integer real time delay_length natural positive string bit_vector // file_open_kind file_open_status line text side width std_ulogic std_ulogic_vector std_logic // std_logic_vector X01 X01Z UX01 UX01Z unsigned signed // |
Added lexers/LexVerilog.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
// Scintilla source code edit control /** @file LexVerilog.cxx ** Lexer for Verilog. ** Written by Avi Yegudin, based on C++ lexer by Neil Hodgson **/ // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\''|| ch == '$'); } static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '$'); } static void ColouriseVerilogDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; WordList &keywords4 = *keywordlists[3]; // Do not leak onto next line if (initStyle == SCE_V_STRINGEOL) initStyle = SCE_V_DEFAULT; StyleContext sc(startPos, length, initStyle, styler); for (; sc.More(); sc.Forward()) { if (sc.atLineStart && (sc.state == SCE_V_STRING)) { // Prevent SCE_V_STRINGEOL from leaking back to previous line sc.SetState(SCE_V_STRING); } // Handle line continuation generically. if (sc.ch == '\\') { if (sc.chNext == '\n' || sc.chNext == '\r') { sc.Forward(); if (sc.ch == '\r' && sc.chNext == '\n') { sc.Forward(); } continue; } } // Determine if the current state should terminate. if (sc.state == SCE_V_OPERATOR) { sc.SetState(SCE_V_DEFAULT); } else if (sc.state == SCE_V_NUMBER) { if (!IsAWordChar(sc.ch)) { sc.SetState(SCE_V_DEFAULT); } } else if (sc.state == SCE_V_IDENTIFIER) { if (!IsAWordChar(sc.ch) || (sc.ch == '.')) { char s[100]; sc.GetCurrent(s, sizeof(s)); if (keywords.InList(s)) { sc.ChangeState(SCE_V_WORD); } else if (keywords2.InList(s)) { sc.ChangeState(SCE_V_WORD2); } else if (keywords3.InList(s)) { sc.ChangeState(SCE_V_WORD3); } else if (keywords4.InList(s)) { sc.ChangeState(SCE_V_USER); } sc.SetState(SCE_V_DEFAULT); } } else if (sc.state == SCE_V_PREPROCESSOR) { if (!IsAWordChar(sc.ch)) { sc.SetState(SCE_V_DEFAULT); } } else if (sc.state == SCE_V_COMMENT) { if (sc.Match('*', '/')) { sc.Forward(); sc.ForwardSetState(SCE_V_DEFAULT); } } else if (sc.state == SCE_V_COMMENTLINE || sc.state == SCE_V_COMMENTLINEBANG) { if (sc.atLineStart) { sc.SetState(SCE_V_DEFAULT); } } else if (sc.state == SCE_V_STRING) { if (sc.ch == '\\') { if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { sc.Forward(); } } else if (sc.ch == '\"') { sc.ForwardSetState(SCE_V_DEFAULT); } else if (sc.atLineEnd) { sc.ChangeState(SCE_V_STRINGEOL); sc.ForwardSetState(SCE_V_DEFAULT); } } // Determine if a new state should be entered. if (sc.state == SCE_V_DEFAULT) { if (IsADigit(sc.ch) || (sc.ch == '\'') || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_V_NUMBER); } else if (IsAWordStart(sc.ch)) { sc.SetState(SCE_V_IDENTIFIER); } else if (sc.Match('/', '*')) { sc.SetState(SCE_V_COMMENT); sc.Forward(); // Eat the * so it isn't used for the end of the comment } else if (sc.Match('/', '/')) { if (sc.Match("//!")) // Nice to have a different comment style sc.SetState(SCE_V_COMMENTLINEBANG); else sc.SetState(SCE_V_COMMENTLINE); } else if (sc.ch == '\"') { sc.SetState(SCE_V_STRING); } else if (sc.ch == '`') { sc.SetState(SCE_V_PREPROCESSOR); // Skip whitespace between ` and preprocessor word do { sc.Forward(); } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More()); if (sc.atLineEnd) { sc.SetState(SCE_V_DEFAULT); } } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '#') { sc.SetState(SCE_V_OPERATOR); } } } sc.Complete(); } static bool IsStreamCommentStyle(int style) { return style == SCE_V_COMMENT; } static bool IsCommentLine(int line, Accessor &styler) { int pos = styler.LineStart(line); int eolPos = styler.LineStart(line + 1) - 1; for (int i = pos; i < eolPos; i++) { char ch = styler[i]; char chNext = styler.SafeGetCharAt(i + 1); int style = styler.StyleAt(i); if (ch == '/' && chNext == '/' && (style == SCE_V_COMMENTLINE || style == SCE_V_COMMENTLINEBANG)) { return true; } else if (!IsASpaceOrTab(ch)) { return false; } } return false; } // Store both the current line's fold level and the next lines in the // level store to make it easy to pick up with each increment // and to make it possible to fiddle the current level for "} else {". static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle, Accessor &styler) { bool foldComment = styler.GetPropertyInt("fold.comment") != 0; bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0; // Verilog specific folding options: // fold_at_module - // Generally used methodology in verilog code is // one module per file, so folding at module definition is useless. // fold_at_brace/parenthese - // Folding of long port lists can be convenient. bool foldAtModule = styler.GetPropertyInt("fold.verilog.flags", 0) != 0; bool foldAtBrace = 1; bool foldAtParenthese = 1; unsigned int endPos = startPos + length; int visibleChars = 0; int lineCurrent = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (lineCurrent > 0) levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; int levelMinCurrent = levelCurrent; int levelNext = levelCurrent; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); int stylePrev = style; style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (foldComment && IsStreamCommentStyle(style)) { if (!IsStreamCommentStyle(stylePrev)) { levelNext++; } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { // Comments don't end at end of line and the next character may be unstyled. levelNext--; } } if (foldComment && atEOL && IsCommentLine(lineCurrent, styler)) { if (!IsCommentLine(lineCurrent - 1, styler) && IsCommentLine(lineCurrent + 1, styler)) levelNext++; else if (IsCommentLine(lineCurrent - 1, styler) && !IsCommentLine(lineCurrent+1, styler)) levelNext--; } if (foldComment && (style == SCE_V_COMMENTLINE)) { if ((ch == '/') && (chNext == '/')) { char chNext2 = styler.SafeGetCharAt(i + 2); if (chNext2 == '{') { levelNext++; } else if (chNext2 == '}') { levelNext--; } } } if (foldPreprocessor && (style == SCE_V_PREPROCESSOR)) { if (ch == '`') { unsigned int j = i + 1; while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { j++; } if (styler.Match(j, "if")) { levelNext++; } else if (styler.Match(j, "end")) { levelNext--; } } } if (style == SCE_V_OPERATOR) { if (foldAtParenthese) { if (ch == '(') { levelNext++; } else if (ch == ')') { levelNext--; } } } if (style == SCE_V_OPERATOR) { if (foldAtBrace) { if (ch == '{') { levelNext++; } else if (ch == '}') { levelNext--; } } } if (style == SCE_V_WORD && stylePrev != SCE_V_WORD) { unsigned int j = i; if (styler.Match(j, "case") || styler.Match(j, "casex") || styler.Match(j, "casez") || styler.Match(j, "class") || styler.Match(j, "function") || styler.Match(j, "generate") || styler.Match(j, "covergroup") || styler.Match(j, "package") || styler.Match(j, "primitive") || styler.Match(j, "program") || styler.Match(j, "sequence") || styler.Match(j, "specify") || styler.Match(j, "table") || styler.Match(j, "task") || styler.Match(j, "fork") || (styler.Match(j, "module") && foldAtModule) || styler.Match(j, "begin")) { levelNext++; } else if (styler.Match(j, "endcase") || styler.Match(j, "endclass") || styler.Match(j, "endfunction") || styler.Match(j, "endgenerate") || styler.Match(j, "endgroup") || styler.Match(j, "endpackage") || styler.Match(j, "endprimitive") || styler.Match(j, "endprogram") || styler.Match(j, "endsequence") || styler.Match(j, "endspecify") || styler.Match(j, "endtable") || styler.Match(j, "endtask") || styler.Match(j, "join") || styler.Match(j, "join_any") || styler.Match(j, "join_none") || (styler.Match(j, "endmodule") && foldAtModule) || (styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j+3)))) { levelNext--; } } if (atEOL) { int levelUse = levelCurrent; if (foldAtElse) { levelUse = levelMinCurrent; } int lev = levelUse | levelNext << 16; if (visibleChars == 0 && foldCompact) lev |= SC_FOLDLEVELWHITEFLAG; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); } lineCurrent++; levelCurrent = levelNext; levelMinCurrent = levelCurrent; visibleChars = 0; } if (!isspacechar(ch)) visibleChars++; } } static void FoldVerilogDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { FoldNoBoxVerilogDoc(startPos, length, initStyle, styler); } static const char * const verilogWordLists[] = { "Primary keywords and identifiers", "Secondary keywords and identifiers", "System Tasks", "User defined tasks and identifiers", "Unused", 0, }; LexerModule lmVerilog(SCLEX_VERILOG, ColouriseVerilogDoc, "verilog", FoldVerilogDoc, verilogWordLists); |
Added lexers/LexVisualProlog.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 |
// Scintilla source code edit control /** @file LexVisualProlog.cxx ** Lexer for Visual Prolog. **/ // Author Thomas Linder Puls, Prolog Development Denter A/S, http://www.visual-prolog.com // Based on Lexer for C++, C, Java, and JavaScript. // Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #ifdef _MSC_VER #pragma warning(disable: 4786) #endif #include <string> #include <vector> #include <map> #include <algorithm> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #include "OptionSet.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // Options used for LexerVisualProlog struct OptionsVisualProlog { OptionsVisualProlog() { } }; static const char *const visualPrologWordLists[] = { "Major keywords (class, predicates, ...)", "Minor keywords (if, then, try, ...)", "Directive keywords without the '#' (include, requires, ...)", "Documentation keywords without the '@' (short, detail, ...)", 0, }; struct OptionSetVisualProlog : public OptionSet<OptionsVisualProlog> { OptionSetVisualProlog() { DefineWordListSets(visualPrologWordLists); } }; class LexerVisualProlog : public ILexer { WordList majorKeywords; WordList minorKeywords; WordList directiveKeywords; WordList docKeywords; OptionsVisualProlog options; OptionSetVisualProlog osVisualProlog; public: LexerVisualProlog() { } virtual ~LexerVisualProlog() { } void SCI_METHOD Release() { delete this; } int SCI_METHOD Version() const { return lvOriginal; } const char * SCI_METHOD PropertyNames() { return osVisualProlog.PropertyNames(); } int SCI_METHOD PropertyType(const char *name) { return osVisualProlog.PropertyType(name); } const char * SCI_METHOD DescribeProperty(const char *name) { return osVisualProlog.DescribeProperty(name); } int SCI_METHOD PropertySet(const char *key, const char *val); const char * SCI_METHOD DescribeWordListSets() { return osVisualProlog.DescribeWordListSets(); } int SCI_METHOD WordListSet(int n, const char *wl); void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess); void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess); void * SCI_METHOD PrivateCall(int, void *) { return 0; } static ILexer *LexerFactoryVisualProlog() { return new LexerVisualProlog(); } }; int SCI_METHOD LexerVisualProlog::PropertySet(const char *key, const char *val) { if (osVisualProlog.PropertySet(&options, key, val)) { return 0; } return -1; } int SCI_METHOD LexerVisualProlog::WordListSet(int n, const char *wl) { WordList *wordListN = 0; switch (n) { case 0: wordListN = &majorKeywords; break; case 1: wordListN = &minorKeywords; break; case 2: wordListN = &directiveKeywords; break; case 3: wordListN = &docKeywords; break; } int firstModification = -1; if (wordListN) { WordList wlNew; wlNew.Set(wl); if (*wordListN != wlNew) { wordListN->Set(wl); firstModification = 0; } } return firstModification; } // Functor used to truncate history struct After { int line; After(int line_) : line(line_) {} }; // Look ahead to see which colour "end" should have (takes colour after the following keyword) static void endLookAhead(char s[], LexAccessor &styler, int start, CharacterSet &setIdentifier) { char ch = styler.SafeGetCharAt(start, '\n'); while (' ' == ch) { start++; ch = styler.SafeGetCharAt(start, '\n'); } int i = 0; while (i < 100 && setIdentifier.Contains(ch)){ s[i] = ch; i++; ch = styler.SafeGetCharAt(start + i, '\n'); } s[i] = '\0'; } static void forwardEscapeLiteral(StyleContext &sc, int OwnChar, int EscapeState) { sc.Forward(); if (sc.ch == OwnChar || sc.ch == '\\' || sc.ch == 'n' || sc.ch == 'l' || sc.ch == 'r' || sc.ch == 't') { sc.ChangeState(EscapeState); } else if (sc.ch == 'u') { if (IsADigit(sc.chNext, 16)) { sc.Forward(); if (IsADigit(sc.chNext, 16)) { sc.Forward(); if (IsADigit(sc.chNext, 16)) { sc.Forward(); if (IsADigit(sc.chNext, 16)) { sc.Forward(); sc.ChangeState(EscapeState); } } } } } } void SCI_METHOD LexerVisualProlog::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { LexAccessor styler(pAccess); CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]"); CharacterSet setLowerStart(CharacterSet::setLower); CharacterSet setVariableStart(CharacterSet::setUpper); CharacterSet setIdentifier(CharacterSet::setAlphaNum, "_", 0x80, true); int styleBeforeDocKeyword = SCE_VISUALPROLOG_DEFAULT; int currentLine = styler.GetLine(startPos); int nestLevel = 0; if (currentLine >= 1) { nestLevel = styler.GetLineState(currentLine - 1); } StyleContext sc(startPos, length, initStyle, styler, 0x7f); // Truncate ppDefineHistory before current line for (; sc.More(); sc.Forward()) { if (sc.atLineEnd) { // Update the line state, so it can be seen by next line styler.SetLineState(currentLine, nestLevel); currentLine++; } if (sc.atLineStart) { if ((sc.state == SCE_VISUALPROLOG_STRING) || (sc.state == SCE_VISUALPROLOG_CHARACTER)) { // Prevent SCE_VISUALPROLOG_STRING_EOL from leaking back to previous line which // ends with a line continuation by locking in the state upto this position. sc.SetState(sc.state); } } const bool atLineEndBeforeSwitch = sc.atLineEnd; // Determine if the current state should terminate. switch (sc.state) { case SCE_VISUALPROLOG_OPERATOR: sc.SetState(SCE_VISUALPROLOG_DEFAULT); break; case SCE_VISUALPROLOG_NUMBER: // We accept almost anything because of hex. and number suffixes if (!(setIdentifier.Contains(sc.ch) || (sc.ch == '.') || ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) { sc.SetState(SCE_VISUALPROLOG_DEFAULT); } break; case SCE_VISUALPROLOG_IDENTIFIER: if (!setIdentifier.Contains(sc.ch)) { char s[1000]; sc.GetCurrent(s, sizeof(s)); if (0 == strcmp(s, "end")) { endLookAhead(s, styler, sc.currentPos, setIdentifier); } if (majorKeywords.InList(s)) { sc.ChangeState(SCE_VISUALPROLOG_KEY_MAJOR); } else if (minorKeywords.InList(s)) { sc.ChangeState(SCE_VISUALPROLOG_KEY_MINOR); } sc.SetState(SCE_VISUALPROLOG_DEFAULT); } break; case SCE_VISUALPROLOG_VARIABLE: case SCE_VISUALPROLOG_ANONYMOUS: if (!setIdentifier.Contains(sc.ch)) { sc.SetState(SCE_VISUALPROLOG_DEFAULT); } break; case SCE_VISUALPROLOG_KEY_DIRECTIVE: if (!setLowerStart.Contains(sc.ch)) { char s[1000]; sc.GetCurrent(s, sizeof(s)); if (!directiveKeywords.InList(s+1)) { sc.ChangeState(SCE_VISUALPROLOG_IDENTIFIER); } sc.SetState(SCE_VISUALPROLOG_DEFAULT); } break; case SCE_VISUALPROLOG_COMMENT_BLOCK: if (sc.Match('*', '/')) { sc.Forward(); nestLevel--; int nextState = (nestLevel == 0) ? SCE_VISUALPROLOG_DEFAULT : SCE_VISUALPROLOG_COMMENT_BLOCK; sc.ForwardSetState(nextState); } else if (sc.Match('/', '*')) { sc.Forward(); nestLevel++; } else if (sc.ch == '%') { sc.SetState(SCE_VISUALPROLOG_COMMENT_LINE); } else if (sc.ch == '@') { styleBeforeDocKeyword = sc.state; sc.SetState(SCE_VISUALPROLOG_COMMENT_KEY_ERROR); } break; case SCE_VISUALPROLOG_COMMENT_LINE: if (sc.atLineEnd) { int nextState = (nestLevel == 0) ? SCE_VISUALPROLOG_DEFAULT : SCE_VISUALPROLOG_COMMENT_BLOCK; sc.SetState(nextState); } else if (sc.ch == '@') { styleBeforeDocKeyword = sc.state; sc.SetState(SCE_VISUALPROLOG_COMMENT_KEY_ERROR); } break; case SCE_VISUALPROLOG_COMMENT_KEY_ERROR: if (!setDoxygen.Contains(sc.ch)) { char s[1000]; sc.GetCurrent(s, sizeof(s)); if (docKeywords.InList(s+1)) { sc.ChangeState(SCE_VISUALPROLOG_COMMENT_KEY); } sc.SetState(styleBeforeDocKeyword); } if (SCE_VISUALPROLOG_COMMENT_LINE == styleBeforeDocKeyword && sc.atLineStart) { sc.SetState(SCE_VISUALPROLOG_DEFAULT); } else if (SCE_VISUALPROLOG_COMMENT_BLOCK == styleBeforeDocKeyword && sc.atLineStart) { sc.SetState(SCE_VISUALPROLOG_COMMENT_BLOCK); } break; case SCE_VISUALPROLOG_STRING_ESCAPE: case SCE_VISUALPROLOG_STRING_ESCAPE_ERROR: // return to SCE_VISUALPROLOG_STRING and treat as such (fall-through) sc.SetState(SCE_VISUALPROLOG_STRING); case SCE_VISUALPROLOG_STRING: if (sc.atLineEnd) { sc.SetState(SCE_VISUALPROLOG_STRING_EOL_OPEN); } else if (sc.ch == '"') { sc.ForwardSetState(SCE_VISUALPROLOG_DEFAULT); } else if (sc.ch == '\\') { sc.SetState(SCE_VISUALPROLOG_STRING_ESCAPE_ERROR); forwardEscapeLiteral(sc, '"', SCE_VISUALPROLOG_STRING_ESCAPE); } break; case SCE_VISUALPROLOG_CHARACTER_TOO_MANY: if (sc.atLineStart) { sc.SetState(SCE_VISUALPROLOG_DEFAULT); } else if (sc.ch == '\'') { sc.SetState(SCE_VISUALPROLOG_CHARACTER); sc.ForwardSetState(SCE_VISUALPROLOG_DEFAULT); } break; case SCE_VISUALPROLOG_CHARACTER: if (sc.atLineEnd) { sc.SetState(SCE_VISUALPROLOG_STRING_EOL_OPEN); // reuse STRING_EOL_OPEN for this } else if (sc.ch == '\'') { sc.SetState(SCE_VISUALPROLOG_CHARACTER_ESCAPE_ERROR); sc.ForwardSetState(SCE_VISUALPROLOG_DEFAULT); } else { if (sc.ch == '\\') { sc.SetState(SCE_VISUALPROLOG_CHARACTER_ESCAPE_ERROR); forwardEscapeLiteral(sc, '\'', SCE_VISUALPROLOG_CHARACTER); } sc.ForwardSetState(SCE_VISUALPROLOG_CHARACTER); if (sc.ch == '\'') { sc.ForwardSetState(SCE_VISUALPROLOG_DEFAULT); } else { sc.SetState(SCE_VISUALPROLOG_CHARACTER_TOO_MANY); } } break; case SCE_VISUALPROLOG_STRING_EOL_OPEN: if (sc.atLineStart) { sc.SetState(SCE_VISUALPROLOG_DEFAULT); } break; case SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL: case SCE_VISUALPROLOG_STRING_VERBATIM_EOL: // return to SCE_VISUALPROLOG_STRING_VERBATIM and treat as such (fall-through) sc.SetState(SCE_VISUALPROLOG_STRING_VERBATIM); case SCE_VISUALPROLOG_STRING_VERBATIM: if (sc.atLineEnd) { sc.SetState(SCE_VISUALPROLOG_STRING_VERBATIM_EOL); } else if (sc.ch == '\"') { if (sc.chNext == '\"') { sc.SetState(SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL); sc.Forward(); } else { sc.ForwardSetState(SCE_VISUALPROLOG_DEFAULT); } } break; } if (sc.atLineEnd && !atLineEndBeforeSwitch) { // State exit processing consumed characters up to end of line. currentLine++; } // Determine if a new state should be entered. if (sc.state == SCE_VISUALPROLOG_DEFAULT) { if (sc.Match('@', '\"')) { sc.SetState(SCE_VISUALPROLOG_STRING_VERBATIM); sc.Forward(); } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_VISUALPROLOG_NUMBER); } else if (setLowerStart.Contains(sc.ch)) { sc.SetState(SCE_VISUALPROLOG_IDENTIFIER); } else if (setVariableStart.Contains(sc.ch)) { sc.SetState(SCE_VISUALPROLOG_VARIABLE); } else if (sc.ch == '_') { sc.SetState(SCE_VISUALPROLOG_ANONYMOUS); } else if (sc.Match('/', '*')) { sc.SetState(SCE_VISUALPROLOG_COMMENT_BLOCK); nestLevel = 1; sc.Forward(); // Eat the * so it isn't used for the end of the comment } else if (sc.ch == '%') { sc.SetState(SCE_VISUALPROLOG_COMMENT_LINE); } else if (sc.ch == '\"') { sc.SetState(SCE_VISUALPROLOG_STRING); } else if (sc.ch == '\'') { sc.SetState(SCE_VISUALPROLOG_CHARACTER); } else if (sc.ch == '#') { sc.SetState(SCE_VISUALPROLOG_KEY_DIRECTIVE); } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '\\') { sc.SetState(SCE_VISUALPROLOG_OPERATOR); } } } sc.Complete(); styler.Flush(); } // Store both the current line's fold level and the next lines in the // level store to make it easy to pick up with each increment // and to make it possible to fiddle the current level for "} else {". void SCI_METHOD LexerVisualProlog::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { LexAccessor styler(pAccess); unsigned int endPos = startPos + length; int visibleChars = 0; int currentLine = styler.GetLine(startPos); int levelCurrent = SC_FOLDLEVELBASE; if (currentLine > 0) levelCurrent = styler.LevelAt(currentLine-1) >> 16; int levelMinCurrent = levelCurrent; int levelNext = levelCurrent; char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = initStyle; for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); style = styleNext; styleNext = styler.StyleAt(i + 1); bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); if (style == SCE_VISUALPROLOG_OPERATOR) { if (ch == '{') { // Measure the minimum before a '{' to allow // folding on "} else {" if (levelMinCurrent > levelNext) { levelMinCurrent = levelNext; } levelNext++; } else if (ch == '}') { levelNext--; } } if (!IsASpace(ch)) visibleChars++; if (atEOL || (i == endPos-1)) { int levelUse = levelCurrent; int lev = levelUse | levelNext << 16; if (levelUse < levelNext) lev |= SC_FOLDLEVELHEADERFLAG; if (lev != styler.LevelAt(currentLine)) { styler.SetLevel(currentLine, lev); } currentLine++; levelCurrent = levelNext; levelMinCurrent = levelCurrent; if (atEOL && (i == static_cast<unsigned int>(styler.Length()-1))) { // There is an empty line at end of file so give it same level and empty styler.SetLevel(currentLine, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG); } visibleChars = 0; } } } LexerModule lmVisualProlog(SCLEX_VISUALPROLOG, LexerVisualProlog::LexerFactoryVisualProlog, "visualprolog", visualPrologWordLists); |
Added lexers/LexYAML.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
// Scintilla source code edit control /** @file LexYAML.cxx ** Lexer for YAML. **/ // Copyright 2003- by Sean O'Dell <sean@celsoft.com> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static const char * const yamlWordListDesc[] = { "Keywords", 0 }; static inline bool AtEOL(Accessor &styler, unsigned int i) { return (styler[i] == '\n') || ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')); } static unsigned int SpaceCount(char* lineBuffer) { if (lineBuffer == NULL) return 0; char* headBuffer = lineBuffer; while (*headBuffer == ' ') headBuffer++; return headBuffer - lineBuffer; } #define YAML_STATE_BITSIZE 16 #define YAML_STATE_MASK (0xFFFF0000) #define YAML_STATE_DOCUMENT (1 << YAML_STATE_BITSIZE) #define YAML_STATE_VALUE (2 << YAML_STATE_BITSIZE) #define YAML_STATE_COMMENT (3 << YAML_STATE_BITSIZE) #define YAML_STATE_TEXT_PARENT (4 << YAML_STATE_BITSIZE) #define YAML_STATE_TEXT (5 << YAML_STATE_BITSIZE) static void ColouriseYAMLLine( char *lineBuffer, unsigned int currentLine, unsigned int lengthLine, unsigned int startLine, unsigned int endPos, WordList &keywords, Accessor &styler) { unsigned int i = 0; bool bInQuotes = false; unsigned int indentAmount = SpaceCount(lineBuffer); if (currentLine > 0) { int parentLineState = styler.GetLineState(currentLine - 1); if ((parentLineState&YAML_STATE_MASK) == YAML_STATE_TEXT || (parentLineState&YAML_STATE_MASK) == YAML_STATE_TEXT_PARENT) { unsigned int parentIndentAmount = parentLineState&(~YAML_STATE_MASK); if (indentAmount > parentIndentAmount) { styler.SetLineState(currentLine, YAML_STATE_TEXT | parentIndentAmount); styler.ColourTo(endPos, SCE_YAML_TEXT); return; } } } styler.SetLineState(currentLine, 0); if (strncmp(lineBuffer, "---", 3) == 0) { // Document marker styler.SetLineState(currentLine, YAML_STATE_DOCUMENT); styler.ColourTo(endPos, SCE_YAML_DOCUMENT); return; } // Skip initial spaces while ((i < lengthLine) && lineBuffer[i] == ' ') { // YAML always uses space, never TABS or anything else i++; } if (lineBuffer[i] == '\t') { // if we skipped all spaces, and we are NOT inside a text block, this is wrong styler.ColourTo(endPos, SCE_YAML_ERROR); return; } if (lineBuffer[i] == '#') { // Comment styler.SetLineState(currentLine, YAML_STATE_COMMENT); styler.ColourTo(endPos, SCE_YAML_COMMENT); return; } while (i < lengthLine) { if (lineBuffer[i] == '\'' || lineBuffer[i] == '\"') { bInQuotes = !bInQuotes; } else if (lineBuffer[i] == ':' && !bInQuotes) { styler.ColourTo(startLine + i - 1, SCE_YAML_IDENTIFIER); styler.ColourTo(startLine + i, SCE_YAML_OPERATOR); // Non-folding scalar i++; while ((i < lengthLine) && isspacechar(lineBuffer[i])) i++; unsigned int endValue = lengthLine - 1; while ((endValue >= i) && isspacechar(lineBuffer[endValue])) endValue--; lineBuffer[endValue + 1] = '\0'; if (lineBuffer[i] == '|' || lineBuffer[i] == '>') { i++; if (lineBuffer[i] == '+' || lineBuffer[i] == '-') i++; while ((i < lengthLine) && isspacechar(lineBuffer[i])) i++; if (lineBuffer[i] == '\0') { styler.SetLineState(currentLine, YAML_STATE_TEXT_PARENT | indentAmount); styler.ColourTo(endPos, SCE_YAML_DEFAULT); return; } else if (lineBuffer[i] == '#') { styler.SetLineState(currentLine, YAML_STATE_TEXT_PARENT | indentAmount); styler.ColourTo(startLine + i - 1, SCE_YAML_DEFAULT); styler.ColourTo(endPos, SCE_YAML_COMMENT); return; } else { styler.ColourTo(endPos, SCE_YAML_ERROR); return; } } else if (lineBuffer[i] == '#') { styler.ColourTo(startLine + i - 1, SCE_YAML_DEFAULT); styler.ColourTo(endPos, SCE_YAML_COMMENT); return; } styler.SetLineState(currentLine, YAML_STATE_VALUE); if (lineBuffer[i] == '&' || lineBuffer[i] == '*') { styler.ColourTo(endPos, SCE_YAML_REFERENCE); return; } if (keywords.InList(&lineBuffer[i])) { // Convertible value (true/false, etc.) styler.ColourTo(endPos, SCE_YAML_KEYWORD); return; } else { unsigned int i2 = i; while ((i < lengthLine) && lineBuffer[i]) { if (!(isascii(lineBuffer[i]) && isdigit(lineBuffer[i])) && lineBuffer[i] != '-' && lineBuffer[i] != '.' && lineBuffer[i] != ',') { styler.ColourTo(endPos, SCE_YAML_DEFAULT); return; } i++; } if (i > i2) { styler.ColourTo(endPos, SCE_YAML_NUMBER); return; } } break; // shouldn't get here, but just in case, the rest of the line is coloured the default } i++; } styler.ColourTo(endPos, SCE_YAML_DEFAULT); } static void ColouriseYAMLDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) { char lineBuffer[1024] = ""; styler.StartAt(startPos); styler.StartSegment(startPos); unsigned int linePos = 0; unsigned int startLine = startPos; unsigned int endPos = startPos + length; unsigned int maxPos = styler.Length(); unsigned int lineCurrent = styler.GetLine(startPos); for (unsigned int i = startPos; i < maxPos && i < endPos; i++) { lineBuffer[linePos++] = styler[i]; if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { // End of line (or of line buffer) met, colourise it lineBuffer[linePos] = '\0'; ColouriseYAMLLine(lineBuffer, lineCurrent, linePos, startLine, i, *keywordLists[0], styler); linePos = 0; startLine = i + 1; lineCurrent++; } } if (linePos > 0) { // Last line does not have ending characters ColouriseYAMLLine(lineBuffer, lineCurrent, linePos, startLine, startPos + length - 1, *keywordLists[0], styler); } } static bool IsCommentLine(int line, Accessor &styler) { int pos = styler.LineStart(line); if (styler[pos] == '#') return true; return false; } static void FoldYAMLDoc(unsigned int startPos, int length, int /*initStyle - unused*/, WordList *[], Accessor &styler) { const int maxPos = startPos + length; const int maxLines = styler.GetLine(maxPos - 1); // Requested last line const int docLines = styler.GetLine(styler.Length() - 1); // Available last line const bool foldComment = styler.GetPropertyInt("fold.comment.yaml") != 0; // Backtrack to previous non-blank line so we can determine indent level // for any white space lines // and so we can fix any preceding fold level (which is why we go back // at least one line in all cases) int spaceFlags = 0; int lineCurrent = styler.GetLine(startPos); int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL); while (lineCurrent > 0) { lineCurrent--; indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL); if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) && (!IsCommentLine(lineCurrent, styler))) break; } int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK; // Set up initial loop state int prevComment = 0; if (lineCurrent >= 1) prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler); // Process all characters to end of requested range // or comment that hangs over the end of the range. Cap processing in all cases // to end of document (in case of unclosed comment at end). while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevComment)) { // Gather info int lev = indentCurrent; int lineNext = lineCurrent + 1; int indentNext = indentCurrent; if (lineNext <= docLines) { // Information about next line is only available if not at end of document indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); } const int comment = foldComment && IsCommentLine(lineCurrent, styler); const int comment_start = (comment && !prevComment && (lineNext <= docLines) && IsCommentLine(lineNext, styler) && (lev > SC_FOLDLEVELBASE)); const int comment_continue = (comment && prevComment); if (!comment) indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK; if (indentNext & SC_FOLDLEVELWHITEFLAG) indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel; if (comment_start) { // Place fold point at start of a block of comments lev |= SC_FOLDLEVELHEADERFLAG; } else if (comment_continue) { // Add level to rest of lines in the block lev = lev + 1; } // Skip past any blank lines for next indent level info; we skip also // comments (all comments, not just those starting in column 0) // which effectively folds them into surrounding code rather // than screwing up folding. while ((lineNext < docLines) && ((indentNext & SC_FOLDLEVELWHITEFLAG) || (lineNext <= docLines && IsCommentLine(lineNext, styler)))) { lineNext++; indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); } const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK; const int levelBeforeComments = Maximum(indentCurrentLevel,levelAfterComments); // Now set all the indent levels on the lines we skipped // Do this from end to start. Once we encounter one line // which is indented more than the line after the end of // the comment-block, use the level of the block before int skipLine = lineNext; int skipLevel = levelAfterComments; while (--skipLine > lineCurrent) { int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL); if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments) skipLevel = levelBeforeComments; int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG; styler.SetLevel(skipLine, skipLevel | whiteFlag); } // Set fold header on non-comment line if (!comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) { if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) lev |= SC_FOLDLEVELHEADERFLAG; } // Keep track of block comment state of previous line prevComment = comment_start || comment_continue; // Set fold level for this line and move to next line styler.SetLevel(lineCurrent, lev); indentCurrent = indentNext; lineCurrent = lineNext; } // NOTE: Cannot set level of last line here because indentCurrent doesn't have // header flag set; the loop above is crafted to take care of this case! //styler.SetLevel(lineCurrent, indentCurrent); } LexerModule lmYAML(SCLEX_YAML, ColouriseYAMLDoc, "yaml", FoldYAMLDoc, yamlWordListDesc); |
Added lexlib/Accessor.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
// Scintilla source code edit control /** @file KeyWords.cxx ** Colourise for particular languages. **/ // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "PropSetSimple.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif Accessor::Accessor(IDocument *pAccess_, PropSetSimple *pprops_) : LexAccessor(pAccess_), pprops(pprops_) { } int Accessor::GetPropertyInt(const char *key, int defaultValue) { return pprops->GetInt(key, defaultValue); } int Accessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) { int end = Length(); int spaceFlags = 0; // Determines the indentation level of the current line and also checks for consistent // indentation compared to the previous line. // Indentation is judged consistent when the indentation whitespace of each line lines // the same or the indentation of one line is a prefix of the other. int pos = LineStart(line); char ch = (*this)[pos]; int indent = 0; bool inPrevPrefix = line > 0; int posPrev = inPrevPrefix ? LineStart(line-1) : 0; while ((ch == ' ' || ch == '\t') && (pos < end)) { if (inPrevPrefix) { char chPrev = (*this)[posPrev++]; if (chPrev == ' ' || chPrev == '\t') { if (chPrev != ch) spaceFlags |= wsInconsistent; } else { inPrevPrefix = false; } } if (ch == ' ') { spaceFlags |= wsSpace; indent++; } else { // Tab spaceFlags |= wsTab; if (spaceFlags & wsSpace) spaceFlags |= wsSpaceTab; indent = (indent / 8 + 1) * 8; } ch = (*this)[++pos]; } *flags = spaceFlags; indent += SC_FOLDLEVELBASE; // if completely empty line or the start of a comment... if ((LineStart(line) == Length()) || (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') || (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos))) return indent | SC_FOLDLEVELWHITEFLAG; else return indent; } |
Added lexlib/Accessor.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
// Scintilla source code edit control /** @file Accessor.h ** Interfaces between Scintilla and lexers. **/ // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef ACCESSOR_H #define ACCESSOR_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8}; class Accessor; class WordList; class PropSetSimple; typedef bool (*PFNIsCommentLeader)(Accessor &styler, int pos, int len); class Accessor : public LexAccessor { public: PropSetSimple *pprops; Accessor(IDocument *pAccess_, PropSetSimple *pprops_); int GetPropertyInt(const char *, int defaultValue=0); int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0); }; #ifdef SCI_NAMESPACE } #endif #endif |
Added lexlib/CharacterSet.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
// Scintilla source code edit control /** @file CharacterSet.cxx ** Simple case functions for ASCII. ** Lexer infrastructure. **/ // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdio.h> #include <assert.h> #include "CharacterSet.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif #ifdef SCI_NAMESPACE namespace Scintilla { #endif int CompareCaseInsensitive(const char *a, const char *b) { while (*a && *b) { if (*a != *b) { char upperA = MakeUpperCase(*a); char upperB = MakeUpperCase(*b); if (upperA != upperB) return upperA - upperB; } a++; b++; } // Either *a or *b is nul return *a - *b; } int CompareNCaseInsensitive(const char *a, const char *b, size_t len) { while (*a && *b && len) { if (*a != *b) { char upperA = MakeUpperCase(*a); char upperB = MakeUpperCase(*b); if (upperA != upperB) return upperA - upperB; } a++; b++; len--; } if (len == 0) return 0; else // Either *a or *b is nul return *a - *b; } #ifdef SCI_NAMESPACE } #endif |
Added lexlib/CharacterSet.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
// Scintilla source code edit control /** @file CharacterSet.h ** Encapsulates a set of characters. Used to test if a character is within a set. **/ // Copyright 2007 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef CHARACTERSET_H #define CHARACTERSET_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif class CharacterSet { int size; bool valueAfter; bool *bset; public: enum setBase { setNone=0, setLower=1, setUpper=2, setDigits=4, setAlpha=setLower|setUpper, setAlphaNum=setAlpha|setDigits }; CharacterSet(setBase base=setNone, const char *initialSet="", int size_=0x80, bool valueAfter_=false) { size = size_; valueAfter = valueAfter_; bset = new bool[size]; for (int i=0; i < size; i++) { bset[i] = false; } AddString(initialSet); if (base & setLower) AddString("abcdefghijklmnopqrstuvwxyz"); if (base & setUpper) AddString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); if (base & setDigits) AddString("0123456789"); } CharacterSet(const CharacterSet &other) { size = other.size; valueAfter = other.valueAfter; bset = new bool[size]; for (int i=0; i < size; i++) { bset[i] = other.bset[i]; } } ~CharacterSet() { delete []bset; bset = 0; size = 0; } CharacterSet &operator=(const CharacterSet &other) { if (this != &other) { bool *bsetNew = new bool[other.size]; for (int i=0; i < other.size; i++) { bsetNew[i] = other.bset[i]; } delete []bset; size = other.size; valueAfter = other.valueAfter; bset = bsetNew; } return *this; } void Add(int val) { assert(val >= 0); assert(val < size); bset[val] = true; } void AddString(const char *setToAdd) { for (const char *cp=setToAdd; *cp; cp++) { int val = static_cast<unsigned char>(*cp); assert(val >= 0); assert(val < size); bset[val] = true; } } bool Contains(int val) const { assert(val >= 0); if (val < 0) return false; return (val < size) ? bset[val] : valueAfter; } }; // Functions for classifying characters inline bool IsASpace(int ch) { return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); } inline bool IsASpaceOrTab(int ch) { return (ch == ' ') || (ch == '\t'); } inline bool IsADigit(int ch) { return (ch >= '0') && (ch <= '9'); } inline bool IsADigit(int ch, int base) { if (base <= 10) { return (ch >= '0') && (ch < '0' + base); } else { return ((ch >= '0') && (ch <= '9')) || ((ch >= 'A') && (ch < 'A' + base - 10)) || ((ch >= 'a') && (ch < 'a' + base - 10)); } } inline bool IsASCII(int ch) { return (ch >= 0) && (ch < 0x80); } inline bool IsLowerCase(int ch) { return (ch >= 'a') && (ch <= 'z'); } inline bool IsUpperCase(int ch) { return (ch >= 'A') && (ch <= 'Z'); } inline bool IsAlphaNumeric(int ch) { return ((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')); } /** * Check if a character is a space. * This is ASCII specific but is safe with chars >= 0x80. */ inline bool isspacechar(int ch) { return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); } inline bool iswordchar(int ch) { return IsAlphaNumeric(ch) || ch == '.' || ch == '_'; } inline bool iswordstart(int ch) { return IsAlphaNumeric(ch) || ch == '_'; } inline bool isoperator(int ch) { if (IsAlphaNumeric(ch)) return false; if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || ch == '(' || ch == ')' || ch == '-' || ch == '+' || ch == '=' || ch == '|' || ch == '{' || ch == '}' || ch == '[' || ch == ']' || ch == ':' || ch == ';' || ch == '<' || ch == '>' || ch == ',' || ch == '/' || ch == '?' || ch == '!' || ch == '.' || ch == '~') return true; return false; } // Simple case functions for ASCII. inline char MakeUpperCase(char ch) { if (ch < 'a' || ch > 'z') return ch; else return static_cast<char>(ch - 'a' + 'A'); } int CompareCaseInsensitive(const char *a, const char *b); int CompareNCaseInsensitive(const char *a, const char *b, size_t len); #ifdef SCI_NAMESPACE } #endif #endif |
Added lexlib/LexAccessor.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
// Scintilla source code edit control /** @file LexAccessor.h ** Interfaces between Scintilla and lexers. **/ // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef LEXACCESSOR_H #define LEXACCESSOR_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif enum EncodingType { enc8bit, encUnicode, encDBCS }; class LexAccessor { private: IDocument *pAccess; enum {extremePosition=0x7FFFFFFF}; /** @a bufferSize is a trade off between time taken to copy the characters * and retrieval overhead. * @a slopSize positions the buffer before the desired position * in case there is some backtracking. */ enum {bufferSize=4000, slopSize=bufferSize/8}; char buf[bufferSize+1]; int startPos; int endPos; int codePage; enum EncodingType encodingType; int lenDoc; int mask; char styleBuf[bufferSize]; int validLen; char chFlags; char chWhile; unsigned int startSeg; int startPosStyling; int documentVersion; void Fill(int position) { startPos = position - slopSize; if (startPos + bufferSize > lenDoc) startPos = lenDoc - bufferSize; if (startPos < 0) startPos = 0; endPos = startPos + bufferSize; if (endPos > lenDoc) endPos = lenDoc; pAccess->GetCharRange(buf, startPos, endPos-startPos); buf[endPos-startPos] = '\0'; } public: LexAccessor(IDocument *pAccess_) : pAccess(pAccess_), startPos(extremePosition), endPos(0), codePage(pAccess->CodePage()), encodingType(enc8bit), lenDoc(pAccess->Length()), mask(127), validLen(0), chFlags(0), chWhile(0), startSeg(0), startPosStyling(0), documentVersion(pAccess->Version()) { switch (codePage) { case 65001: encodingType = encUnicode; break; case 932: case 936: case 949: case 950: case 1361: encodingType = encDBCS; } } char operator[](int position) { if (position < startPos || position >= endPos) { Fill(position); } return buf[position - startPos]; } /** Safe version of operator[], returning a defined value for invalid position. */ char SafeGetCharAt(int position, char chDefault=' ') { if (position < startPos || position >= endPos) { Fill(position); if (position < startPos || position >= endPos) { // Position is outside range of document return chDefault; } } return buf[position - startPos]; } bool IsLeadByte(char ch) { return pAccess->IsDBCSLeadByte(ch); } EncodingType Encoding() const { return encodingType; } bool Match(int pos, const char *s) { for (int i=0; *s; i++) { if (*s != SafeGetCharAt(pos+i)) return false; s++; } return true; } char StyleAt(int position) { return static_cast<char>(pAccess->StyleAt(position) & mask); } int GetLine(int position) { return pAccess->LineFromPosition(position); } int LineStart(int line) { return pAccess->LineStart(line); } int LineEnd(int line) { if (documentVersion >= dvLineEnd) { return (static_cast<IDocumentWithLineEnd *>(pAccess))->LineEnd(line); } else { // Old interface means only '\r', '\n' and '\r\n' line ends. int startNext = pAccess->LineStart(line+1); char chLineEnd = SafeGetCharAt(startNext-1); if (chLineEnd == '\n' && (SafeGetCharAt(startNext-2) == '\r')) return startNext - 2; else return startNext - 1; } } int LevelAt(int line) { return pAccess->GetLevel(line); } int Length() const { return lenDoc; } void Flush() { startPos = extremePosition; if (validLen > 0) { pAccess->SetStyles(validLen, styleBuf); startPosStyling += validLen; validLen = 0; } } int GetLineState(int line) { return pAccess->GetLineState(line); } int SetLineState(int line, int state) { return pAccess->SetLineState(line, state); } // Style setting void StartAt(unsigned int start, char chMask=31) { // Store the mask specified for use with StyleAt. mask = chMask; pAccess->StartStyling(start, chMask); startPosStyling = start; } void SetFlags(char chFlags_, char chWhile_) { chFlags = chFlags_; chWhile = chWhile_; } unsigned int GetStartSegment() const { return startSeg; } void StartSegment(unsigned int pos) { startSeg = pos; } void ColourTo(unsigned int pos, int chAttr) { // Only perform styling if non empty range if (pos != startSeg - 1) { assert(pos >= startSeg); if (pos < startSeg) { return; } if (validLen + (pos - startSeg + 1) >= bufferSize) Flush(); if (validLen + (pos - startSeg + 1) >= bufferSize) { // Too big for buffer so send directly pAccess->SetStyleFor(pos - startSeg + 1, static_cast<char>(chAttr)); } else { if (chAttr != chWhile) chFlags = 0; chAttr = static_cast<char>(chAttr | chFlags); for (unsigned int i = startSeg; i <= pos; i++) { assert((startPosStyling + validLen) < Length()); styleBuf[validLen++] = static_cast<char>(chAttr); } } } startSeg = pos+1; } void SetLevel(int line, int level) { pAccess->SetLevel(line, level); } void IndicatorFill(int start, int end, int indicator, int value) { pAccess->DecorationSetCurrentIndicator(indicator); pAccess->DecorationFillRange(start, value, end - start); } void ChangeLexerState(int start, int end) { pAccess->ChangeLexerState(start, end); } }; #ifdef SCI_NAMESPACE } #endif #endif |
Added lexlib/LexerBase.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
// Scintilla source code edit control /** @file LexerBase.cxx ** A simple lexer with no state. **/ // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "PropSetSimple.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "LexerModule.h" #include "LexerBase.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif LexerBase::LexerBase() { for (int wl = 0; wl < numWordLists; wl++) keyWordLists[wl] = new WordList; keyWordLists[numWordLists] = 0; } LexerBase::~LexerBase() { for (int wl = 0; wl < numWordLists; wl++) { delete keyWordLists[wl]; keyWordLists[wl] = 0; } keyWordLists[numWordLists] = 0; } void SCI_METHOD LexerBase::Release() { delete this; } int SCI_METHOD LexerBase::Version() const { return lvOriginal; } const char * SCI_METHOD LexerBase::PropertyNames() { return ""; } int SCI_METHOD LexerBase::PropertyType(const char *) { return SC_TYPE_BOOLEAN; } const char * SCI_METHOD LexerBase::DescribeProperty(const char *) { return ""; } int SCI_METHOD LexerBase::PropertySet(const char *key, const char *val) { const char *valOld = props.Get(key); if (strcmp(val, valOld) != 0) { props.Set(key, val); return 0; } else { return -1; } } const char * SCI_METHOD LexerBase::DescribeWordListSets() { return ""; } int SCI_METHOD LexerBase::WordListSet(int n, const char *wl) { if (n < numWordLists) { WordList wlNew; wlNew.Set(wl); if (*keyWordLists[n] != wlNew) { keyWordLists[n]->Set(wl); return 0; } } return -1; } void * SCI_METHOD LexerBase::PrivateCall(int, void *) { return 0; } |
Added lexlib/LexerBase.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
// Scintilla source code edit control /** @file LexerBase.h ** A simple lexer with no state. **/ // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef LEXERBASE_H #define LEXERBASE_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif // A simple lexer with no state class LexerBase : public ILexer { protected: PropSetSimple props; enum {numWordLists=KEYWORDSET_MAX+1}; WordList *keyWordLists[numWordLists+1]; public: LexerBase(); virtual ~LexerBase(); void SCI_METHOD Release(); int SCI_METHOD Version() const; const char * SCI_METHOD PropertyNames(); int SCI_METHOD PropertyType(const char *name); const char * SCI_METHOD DescribeProperty(const char *name); int SCI_METHOD PropertySet(const char *key, const char *val); const char * SCI_METHOD DescribeWordListSets(); int SCI_METHOD WordListSet(int n, const char *wl); void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0; void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0; void * SCI_METHOD PrivateCall(int operation, void *pointer); }; #ifdef SCI_NAMESPACE } #endif #endif |
Added lexlib/LexerModule.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
// Scintilla source code edit control /** @file LexerModule.cxx ** Colourise for particular languages. **/ // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include <string> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "PropSetSimple.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "LexerModule.h" #include "LexerBase.h" #include "LexerSimple.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif LexerModule::LexerModule(int language_, LexerFunction fnLexer_, const char *languageName_, LexerFunction fnFolder_, const char *const wordListDescriptions_[], int styleBits_) : language(language_), fnLexer(fnLexer_), fnFolder(fnFolder_), fnFactory(0), wordListDescriptions(wordListDescriptions_), styleBits(styleBits_), languageName(languageName_) { } LexerModule::LexerModule(int language_, LexerFactoryFunction fnFactory_, const char *languageName_, const char * const wordListDescriptions_[], int styleBits_) : language(language_), fnLexer(0), fnFolder(0), fnFactory(fnFactory_), wordListDescriptions(wordListDescriptions_), styleBits(styleBits_), languageName(languageName_) { } int LexerModule::GetNumWordLists() const { if (wordListDescriptions == NULL) { return -1; } else { int numWordLists = 0; while (wordListDescriptions[numWordLists]) { ++numWordLists; } return numWordLists; } } const char *LexerModule::GetWordListDescription(int index) const { static const char *emptyStr = ""; assert(index < GetNumWordLists()); if (index >= GetNumWordLists()) { return emptyStr; } else { return wordListDescriptions[index]; } } int LexerModule::GetStyleBitsNeeded() const { return styleBits; } ILexer *LexerModule::Create() const { if (fnFactory) return fnFactory(); else return new LexerSimple(this); } void LexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle, WordList *keywordlists[], Accessor &styler) const { if (fnLexer) fnLexer(startPos, lengthDoc, initStyle, keywordlists, styler); } void LexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle, WordList *keywordlists[], Accessor &styler) const { if (fnFolder) { int lineCurrent = styler.GetLine(startPos); // Move back one line in case deletion wrecked current line fold state if (lineCurrent > 0) { lineCurrent--; int newStartPos = styler.LineStart(lineCurrent); lengthDoc += startPos - newStartPos; startPos = newStartPos; initStyle = 0; if (startPos > 0) { initStyle = styler.StyleAt(startPos - 1); } } fnFolder(startPos, lengthDoc, initStyle, keywordlists, styler); } } |
Added lexlib/LexerModule.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
// Scintilla source code edit control /** @file LexerModule.h ** Colourise for particular languages. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef LEXERMODULE_H #define LEXERMODULE_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif class Accessor; class WordList; typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle, WordList *keywordlists[], Accessor &styler); typedef ILexer *(*LexerFactoryFunction)(); /** * A LexerModule is responsible for lexing and folding a particular language. * The class maintains a list of LexerModules which can be searched to find a * module appropriate to a particular language. */ class LexerModule { protected: int language; LexerFunction fnLexer; LexerFunction fnFolder; LexerFactoryFunction fnFactory; const char * const * wordListDescriptions; int styleBits; public: const char *languageName; LexerModule(int language_, LexerFunction fnLexer_, const char *languageName_=0, LexerFunction fnFolder_=0, const char * const wordListDescriptions_[] = NULL, int styleBits_=5); LexerModule(int language_, LexerFactoryFunction fnFactory_, const char *languageName_, const char * const wordListDescriptions_[] = NULL, int styleBits_=8); virtual ~LexerModule() { } int GetLanguage() const { return language; } // -1 is returned if no WordList information is available int GetNumWordLists() const; const char *GetWordListDescription(int index) const; int GetStyleBitsNeeded() const; ILexer *Create() const; virtual void Lex(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) const; virtual void Fold(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) const; friend class Catalogue; }; inline int Maximum(int a, int b) { return (a > b) ? a : b; } // Shut up annoying Visual C++ warnings: #ifdef _MSC_VER #pragma warning(disable: 4244 4309 4514 4710) #endif #ifdef SCI_NAMESPACE } #endif #endif |
Added lexlib/LexerNoExceptions.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
// Scintilla source code edit control /** @file LexerNoExceptions.cxx ** A simple lexer with no state which does not throw exceptions so can be used in an external lexer. **/ // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "PropSetSimple.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "LexerModule.h" #include "LexerBase.h" #include "LexerNoExceptions.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif int SCI_METHOD LexerNoExceptions::PropertySet(const char *key, const char *val) { try { return LexerBase::PropertySet(key, val); } catch (...) { // Should not throw into caller as may be compiled with different compiler or options } return -1; } int SCI_METHOD LexerNoExceptions::WordListSet(int n, const char *wl) { try { return LexerBase::WordListSet(n, wl); } catch (...) { // Should not throw into caller as may be compiled with different compiler or options } return -1; } void SCI_METHOD LexerNoExceptions::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { try { Accessor astyler(pAccess, &props); Lexer(startPos, length, initStyle, pAccess, astyler); astyler.Flush(); } catch (...) { // Should not throw into caller as may be compiled with different compiler or options pAccess->SetErrorStatus(SC_STATUS_FAILURE); } } void SCI_METHOD LexerNoExceptions::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { try { Accessor astyler(pAccess, &props); Folder(startPos, length, initStyle, pAccess, astyler); astyler.Flush(); } catch (...) { // Should not throw into caller as may be compiled with different compiler or options pAccess->SetErrorStatus(SC_STATUS_FAILURE); } } |
Added lexlib/LexerNoExceptions.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
// Scintilla source code edit control /** @file LexerNoExceptions.h ** A simple lexer with no state. **/ // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef LexerNoExceptions_H #define LexerNoExceptions_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif // A simple lexer with no state class LexerNoExceptions : public LexerBase { public: // TODO Also need to prevent exceptions in constructor and destructor int SCI_METHOD PropertySet(const char *key, const char *val); int SCI_METHOD WordListSet(int n, const char *wl); void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess); void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *); virtual void Lexer(unsigned int startPos, int length, int initStyle, IDocument *pAccess, Accessor &styler) = 0; virtual void Folder(unsigned int startPos, int length, int initStyle, IDocument *pAccess, Accessor &styler) = 0; }; #ifdef SCI_NAMESPACE } #endif #endif |
Added lexlib/LexerSimple.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
// Scintilla source code edit control /** @file LexerSimple.cxx ** A simple lexer with no state. **/ // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include <string> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "PropSetSimple.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "LexerModule.h" #include "LexerBase.h" #include "LexerSimple.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif LexerSimple::LexerSimple(const LexerModule *module_) : module(module_) { for (int wl = 0; wl < module->GetNumWordLists(); wl++) { if (!wordLists.empty()) wordLists += "\n"; wordLists += module->GetWordListDescription(wl); } } const char * SCI_METHOD LexerSimple::DescribeWordListSets() { return wordLists.c_str(); } void SCI_METHOD LexerSimple::Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) { Accessor astyler(pAccess, &props); module->Lex(startPos, lengthDoc, initStyle, keyWordLists, astyler); astyler.Flush(); } void SCI_METHOD LexerSimple::Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) { if (props.GetInt("fold")) { Accessor astyler(pAccess, &props); module->Fold(startPos, lengthDoc, initStyle, keyWordLists, astyler); astyler.Flush(); } } |
Added lexlib/LexerSimple.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// Scintilla source code edit control /** @file LexerSimple.h ** A simple lexer with no state. **/ // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef LEXERSIMPLE_H #define LEXERSIMPLE_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif // A simple lexer with no state class LexerSimple : public LexerBase { const LexerModule *module; std::string wordLists; public: LexerSimple(const LexerModule *module_); const char * SCI_METHOD DescribeWordListSets(); void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess); void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess); }; #ifdef SCI_NAMESPACE } #endif #endif |
Added lexlib/OptionSet.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
// Scintilla source code edit control /** @file OptionSet.h ** Manage descriptive information about an options struct for a lexer. ** Hold the names, positions, and descriptions of boolean, integer and string options and ** allow setting options and retrieving metadata about the options. **/ // Copyright 2010 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef OPTIONSET_H #define OPTIONSET_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif template <typename T> class OptionSet { typedef T Target; typedef bool T::*plcob; typedef int T::*plcoi; typedef std::string T::*plcos; struct Option { int opType; union { plcob pb; plcoi pi; plcos ps; }; std::string description; Option() : opType(SC_TYPE_BOOLEAN), pb(0), description("") { } Option(plcob pb_, std::string description_="") : opType(SC_TYPE_BOOLEAN), pb(pb_), description(description_) { } Option(plcoi pi_, std::string description_) : opType(SC_TYPE_INTEGER), pi(pi_), description(description_) { } Option(plcos ps_, std::string description_) : opType(SC_TYPE_STRING), ps(ps_), description(description_) { } bool Set(T *base, const char *val) { switch (opType) { case SC_TYPE_BOOLEAN: { bool option = atoi(val) != 0; if ((*base).*pb != option) { (*base).*pb = option; return true; } break; } case SC_TYPE_INTEGER: { int option = atoi(val); if ((*base).*pi != option) { (*base).*pi = option; return true; } break; } case SC_TYPE_STRING: { if ((*base).*ps != val) { (*base).*ps = val; return true; } break; } } return false; } }; typedef std::map<std::string, Option> OptionMap; OptionMap nameToDef; std::string names; std::string wordLists; void AppendName(const char *name) { if (!names.empty()) names += "\n"; names += name; } public: virtual ~OptionSet() { } void DefineProperty(const char *name, plcob pb, std::string description="") { nameToDef[name] = Option(pb, description); AppendName(name); } void DefineProperty(const char *name, plcoi pi, std::string description="") { nameToDef[name] = Option(pi, description); AppendName(name); } void DefineProperty(const char *name, plcos ps, std::string description="") { nameToDef[name] = Option(ps, description); AppendName(name); } const char *PropertyNames() { return names.c_str(); } int PropertyType(const char *name) { typename OptionMap::iterator it = nameToDef.find(name); if (it != nameToDef.end()) { return it->second.opType; } return SC_TYPE_BOOLEAN; } const char *DescribeProperty(const char *name) { typename OptionMap::iterator it = nameToDef.find(name); if (it != nameToDef.end()) { return it->second.description.c_str(); } return ""; } bool PropertySet(T *base, const char *name, const char *val) { typename OptionMap::iterator it = nameToDef.find(name); if (it != nameToDef.end()) { return it->second.Set(base, val); } return false; } void DefineWordListSets(const char * const wordListDescriptions[]) { if (wordListDescriptions) { for (size_t wl = 0; wordListDescriptions[wl]; wl++) { if (!wordLists.empty()) wordLists += "\n"; wordLists += wordListDescriptions[wl]; } } } const char *DescribeWordListSets() { return wordLists.c_str(); } }; #ifdef SCI_NAMESPACE } #endif #endif |
Added lexlib/PropSetSimple.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
// SciTE - Scintilla based Text Editor /** @file PropSetSimple.cxx ** A Java style properties file module. **/ // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. // Maintain a dictionary of properties #include <stdlib.h> #include <string.h> #include <stdio.h> #ifdef _MSC_VER // Visual C++ doesn't like unreachable code in its own headers. #pragma warning(disable: 4018 4100 4245 4511 4512 4663 4702) #endif #include <string> #include <map> #include "PropSetSimple.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif typedef std::map<std::string, std::string> mapss; PropSetSimple::PropSetSimple() { mapss *props = new mapss; impl = static_cast<void *>(props); } PropSetSimple::~PropSetSimple() { mapss *props = static_cast<mapss *>(impl); delete props; impl = 0; } void PropSetSimple::Set(const char *key, const char *val, int lenKey, int lenVal) { mapss *props = static_cast<mapss *>(impl); if (!*key) // Empty keys are not supported return; if (lenKey == -1) lenKey = static_cast<int>(strlen(key)); if (lenVal == -1) lenVal = static_cast<int>(strlen(val)); (*props)[std::string(key, lenKey)] = std::string(val, lenVal); } static bool IsASpaceCharacter(unsigned int ch) { return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); } void PropSetSimple::Set(const char *keyVal) { while (IsASpaceCharacter(*keyVal)) keyVal++; const char *endVal = keyVal; while (*endVal && (*endVal != '\n')) endVal++; const char *eqAt = strchr(keyVal, '='); if (eqAt) { Set(keyVal, eqAt + 1, static_cast<int>(eqAt-keyVal), static_cast<int>(endVal - eqAt - 1)); } else if (*keyVal) { // No '=' so assume '=1' Set(keyVal, "1", static_cast<int>(endVal-keyVal), 1); } } void PropSetSimple::SetMultiple(const char *s) { const char *eol = strchr(s, '\n'); while (eol) { Set(s); s = eol + 1; eol = strchr(s, '\n'); } Set(s); } const char *PropSetSimple::Get(const char *key) const { mapss *props = static_cast<mapss *>(impl); mapss::const_iterator keyPos = props->find(std::string(key)); if (keyPos != props->end()) { return keyPos->second.c_str(); } else { return ""; } } // There is some inconsistency between GetExpanded("foo") and Expand("$(foo)"). // A solution is to keep a stack of variables that have been expanded, so that // recursive expansions can be skipped. For now I'll just use the C++ stack // for that, through a recursive function and a simple chain of pointers. struct VarChain { VarChain(const char *var_=NULL, const VarChain *link_=NULL): var(var_), link(link_) {} bool contains(const char *testVar) const { return (var && (0 == strcmp(var, testVar))) || (link && link->contains(testVar)); } const char *var; const VarChain *link; }; static int ExpandAllInPlace(const PropSetSimple &props, std::string &withVars, int maxExpands, const VarChain &blankVars) { size_t varStart = withVars.find("$("); while ((varStart != std::string::npos) && (maxExpands > 0)) { size_t varEnd = withVars.find(")", varStart+2); if (varEnd == std::string::npos) { break; } // For consistency, when we see '$(ab$(cde))', expand the inner variable first, // regardless whether there is actually a degenerate variable named 'ab$(cde'. size_t innerVarStart = withVars.find("$(", varStart+2); while ((innerVarStart != std::string::npos) && (innerVarStart > varStart) && (innerVarStart < varEnd)) { varStart = innerVarStart; innerVarStart = withVars.find("$(", varStart+2); } std::string var(withVars.c_str(), varStart + 2, varEnd - varStart - 2); std::string val = props.Get(var.c_str()); if (blankVars.contains(var.c_str())) { val = ""; // treat blankVar as an empty string (e.g. to block self-reference) } if (--maxExpands >= 0) { maxExpands = ExpandAllInPlace(props, val, maxExpands, VarChain(var.c_str(), &blankVars)); } withVars.erase(varStart, varEnd-varStart+1); withVars.insert(varStart, val.c_str(), val.length()); varStart = withVars.find("$("); } return maxExpands; } char *PropSetSimple::Expanded(const char *key) const { std::string val = Get(key); ExpandAllInPlace(*this, val, 100, VarChain(key)); char *ret = new char [val.size() + 1]; strcpy(ret, val.c_str()); return ret; } int PropSetSimple::GetExpanded(const char *key, char *result) const { char *val = Expanded(key); const int n = static_cast<int>(strlen(val)); if (result) { strcpy(result, val); } delete []val; return n; // Not including NUL } int PropSetSimple::GetInt(const char *key, int defaultValue) const { char *val = Expanded(key); if (val) { int retVal = val[0] ? atoi(val) : defaultValue; delete []val; return retVal; } return defaultValue; } |
Added lexlib/PropSetSimple.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
// Scintilla source code edit control /** @file PropSetSimple.h ** A basic string to string map. **/ // Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef PROPSETSIMPLE_H #define PROPSETSIMPLE_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif class PropSetSimple { void *impl; void Set(const char *keyVal); public: PropSetSimple(); virtual ~PropSetSimple(); void Set(const char *key, const char *val, int lenKey=-1, int lenVal=-1); void SetMultiple(const char *); const char *Get(const char *key) const; char *Expanded(const char *key) const; int GetExpanded(const char *key, char *result) const; int GetInt(const char *key, int defaultValue=0) const; }; #ifdef SCI_NAMESPACE } #endif #endif |
Added lexlib/SparseState.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
// Scintilla source code edit control /** @file SparseState.h ** Hold lexer state that may change rarely. ** This is often per-line state such as whether a particular type of section has been entered. ** A state continues until it is changed. **/ // Copyright 2011 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef SPARSESTATE_H #define SPARSESTATE_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif template <typename T> class SparseState { struct State { int position; T value; State(int position_, T value_) : position(position_), value(value_) { } inline bool operator<(const State &other) const { return position < other.position; } inline bool operator==(const State &other) const { return (position == other.position) && (value == other.value); } }; int positionFirst; typedef std::vector<State> stateVector; stateVector states; typename stateVector::iterator Find(int position) { State searchValue(position, T()); return std::lower_bound(states.begin(), states.end(), searchValue); } public: SparseState(int positionFirst_=-1) { positionFirst = positionFirst_; } void Set(int position, T value) { Delete(position); if (states.empty() || (value != states[states.size()-1].value)) { states.push_back(State(position, value)); } } T ValueAt(int position) { if (states.empty()) return T(); if (position < states[0].position) return T(); typename stateVector::iterator low = Find(position); if (low == states.end()) { return states[states.size()-1].value; } else { if (low->position > position) { --low; } return low->value; } } bool Delete(int position) { typename stateVector::iterator low = Find(position); if (low != states.end()) { states.erase(low, states.end()); return true; } return false; } size_t size() const { return states.size(); } // Returns true if Merge caused a significant change bool Merge(const SparseState<T> &other, int ignoreAfter) { // Changes caused beyond ignoreAfter are not significant Delete(ignoreAfter+1); bool different = true; bool changed = false; typename stateVector::iterator low = Find(other.positionFirst); if (static_cast<size_t>(states.end() - low) == other.states.size()) { // Same number in other as after positionFirst in this different = !std::equal(low, states.end(), other.states.begin()); } if (different) { if (low != states.end()) { states.erase(low, states.end()); changed = true; } typename stateVector::const_iterator startOther = other.states.begin(); if (!states.empty() && !other.states.empty() && states.back().value == startOther->value) ++startOther; if (startOther != other.states.end()) { states.insert(states.end(), startOther, other.states.end()); changed = true; } } return changed; } }; #ifdef SCI_NAMESPACE } #endif #endif |
Added lexlib/StyleContext.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
// Scintilla source code edit control /** @file StyleContext.cxx ** Lexer infrastructure. **/ // Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org> // This file is in the public domain. #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdio.h> #include <assert.h> #include "ILexer.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static void getRange(unsigned int start, unsigned int end, LexAccessor &styler, char *s, unsigned int len) { unsigned int i = 0; while ((i < end - start + 1) && (i < len-1)) { s[i] = styler[start + i]; i++; } s[i] = '\0'; } void StyleContext::GetCurrent(char *s, unsigned int len) { getRange(styler.GetStartSegment(), currentPos - 1, styler, s, len); } static void getRangeLowered(unsigned int start, unsigned int end, LexAccessor &styler, char *s, unsigned int len) { unsigned int i = 0; while ((i < end - start + 1) && (i < len-1)) { s[i] = static_cast<char>(tolower(styler[start + i])); i++; } s[i] = '\0'; } void StyleContext::GetCurrentLowered(char *s, unsigned int len) { getRangeLowered(styler.GetStartSegment(), currentPos - 1, styler, s, len); } |
Added lexlib/StyleContext.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
// Scintilla source code edit control /** @file StyleContext.cxx ** Lexer infrastructure. **/ // Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org> // This file is in the public domain. #ifndef STYLECONTEXT_H #define STYLECONTEXT_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif static inline int MakeLowerCase(int ch) { if (ch < 'A' || ch > 'Z') return ch; else return ch - 'A' + 'a'; } inline int UnicodeCodePoint(const unsigned char *us) { if (us[0] < 0xC2) { return us[0]; } else if (us[0] < 0xE0) { return ((us[0] & 0x1F) << 6) + (us[1] & 0x3F); } else if (us[0] < 0xF0) { return ((us[0] & 0xF) << 12) + ((us[1] & 0x3F) << 6) + (us[2] & 0x3F); } else if (us[0] < 0xF5) { return ((us[0] & 0x7) << 18) + ((us[1] & 0x3F) << 12) + ((us[2] & 0x3F) << 6) + (us[3] & 0x3F); } return us[0]; } inline int BytesInUnicodeCodePoint(int codePoint) { if (codePoint < 0x80) return 1; else if (codePoint < 0x800) return 2; else if (codePoint < 0x10000) return 3; else return 4; } // All languages handled so far can treat all characters >= 0x80 as one class // which just continues the current token or starts an identifier if in default. // DBCS treated specially as the second character can be < 0x80 and hence // syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80 class StyleContext { LexAccessor &styler; unsigned int endPos; StyleContext &operator=(const StyleContext &); void GetNextChar(unsigned int pos) { chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1)); if (styler.Encoding() == encUnicode) { if (chNext >= 0x80) { unsigned char bytes[4] = { static_cast<unsigned char>(chNext), 0, 0, 0 }; for (int trail=1; trail<3; trail++) { bytes[trail] = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1+trail)); if (!((bytes[trail] >= 0x80) && (bytes[trail] < 0xc0))) { bytes[trail] = 0; break; } } chNext = UnicodeCodePoint(bytes); } } else if (styler.Encoding() == encDBCS) { if (styler.IsLeadByte(static_cast<char>(chNext))) { chNext = chNext << 8; chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(pos+2)); } } // End of line? // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) // or on LF alone (Unix). Avoid triggering two times on Dos/Win. if (lineStartNext < styler.Length()) atLineEnd = static_cast<int>(pos) >= (lineStartNext-1); else // Last line atLineEnd = static_cast<int>(pos) >= lineStartNext; } public: unsigned int currentPos; int currentLine; int lineStartNext; bool atLineStart; bool atLineEnd; int state; int chPrev; int ch; int chNext; StyleContext(unsigned int startPos, unsigned int length, int initStyle, LexAccessor &styler_, char chMask=31) : styler(styler_), endPos(startPos + length), currentPos(startPos), currentLine(-1), lineStartNext(-1), atLineEnd(false), state(initStyle & chMask), // Mask off all bits which aren't in the chMask. chPrev(0), ch(0), chNext(0) { styler.StartAt(startPos, chMask); styler.StartSegment(startPos); currentLine = styler.GetLine(startPos); lineStartNext = styler.LineStart(currentLine+1); atLineStart = static_cast<unsigned int>(styler.LineStart(currentLine)) == startPos; unsigned int pos = currentPos; ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos)); if (styler.Encoding() == encUnicode) { // Get the current char GetNextChar(pos-1); ch = chNext; pos += BytesInUnicodeCodePoint(ch) - 1; } else if (styler.Encoding() == encDBCS) { if (styler.IsLeadByte(static_cast<char>(ch))) { pos++; ch = ch << 8; ch |= static_cast<unsigned char>(styler.SafeGetCharAt(pos)); } } GetNextChar(pos); } void Complete() { styler.ColourTo(currentPos - 1, state); styler.Flush(); } bool More() const { return currentPos < endPos; } void Forward() { if (currentPos < endPos) { atLineStart = atLineEnd; if (atLineStart) { currentLine++; lineStartNext = styler.LineStart(currentLine+1); } chPrev = ch; if (styler.Encoding() == encUnicode) { currentPos += BytesInUnicodeCodePoint(ch); } else if (styler.Encoding() == encDBCS) { currentPos++; if (ch >= 0x100) currentPos++; } else { currentPos++; } ch = chNext; if (styler.Encoding() == encUnicode) { GetNextChar(currentPos + BytesInUnicodeCodePoint(ch)-1); } else if (styler.Encoding() == encDBCS) { GetNextChar(currentPos + ((ch >= 0x100) ? 1 : 0)); } else { GetNextChar(currentPos); } } else { atLineStart = false; chPrev = ' '; ch = ' '; chNext = ' '; atLineEnd = true; } } void Forward(int nb) { for (int i = 0; i < nb; i++) { Forward(); } } void ChangeState(int state_) { state = state_; } void SetState(int state_) { styler.ColourTo(currentPos - 1, state); state = state_; } void ForwardSetState(int state_) { Forward(); styler.ColourTo(currentPos - 1, state); state = state_; } int LengthCurrent() { return currentPos - styler.GetStartSegment(); } int GetRelative(int n) { return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n)); } bool Match(char ch0) const { return ch == static_cast<unsigned char>(ch0); } bool Match(char ch0, char ch1) const { return (ch == static_cast<unsigned char>(ch0)) && (chNext == static_cast<unsigned char>(ch1)); } bool Match(const char *s) { if (ch != static_cast<unsigned char>(*s)) return false; s++; if (!*s) return true; if (chNext != static_cast<unsigned char>(*s)) return false; s++; for (int n=2; *s; n++) { if (*s != styler.SafeGetCharAt(currentPos+n)) return false; s++; } return true; } bool MatchIgnoreCase(const char *s) { if (MakeLowerCase(ch) != static_cast<unsigned char>(*s)) return false; s++; if (MakeLowerCase(chNext) != static_cast<unsigned char>(*s)) return false; s++; for (int n=2; *s; n++) { if (static_cast<unsigned char>(*s) != MakeLowerCase(static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n)))) return false; s++; } return true; } // Non-inline void GetCurrent(char *s, unsigned int len); void GetCurrentLowered(char *s, unsigned int len); }; #ifdef SCI_NAMESPACE } #endif #endif |
Added lexlib/SubStyles.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
// Scintilla source code edit control /** @file SubStyles.h ** Manage substyles for a lexer. **/ // Copyright 2012 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef SUBSTYLES_H #define SUBSTYLES_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif class WordClassifier { int firstStyle; int lenStyles; std::map<std::string, int> wordToStyle; public: WordClassifier() : firstStyle(0), lenStyles(0) { } void Allocate(int firstStyle_, int lenStyles_) { firstStyle = firstStyle_; lenStyles = lenStyles_; wordToStyle.clear(); } int Start() const { return firstStyle; } int Length() const { return lenStyles; } void Clear() { firstStyle = 0; lenStyles = 0; wordToStyle.clear(); } int ValueFor(const std::string &s) const { std::map<std::string, int>::const_iterator it = wordToStyle.find(s); if (it != wordToStyle.end()) return it->second; else return -1; } bool IncludesStyle(int style) const { return (style >= firstStyle) && (style < (firstStyle + lenStyles)); } void SetIdentifiers(int style, const char *identifiers) { while (*identifiers) { const char *cpSpace = identifiers; while (*cpSpace && *cpSpace != ' ') cpSpace++; std::string word(identifiers, cpSpace - identifiers); wordToStyle[word] = style; identifiers = cpSpace; if (*identifiers) identifiers++; } } }; class SubStyles { int classifications; const char *baseStyles; int styleFirst; int stylesAvailable; int secondaryDistance; int allocated; std::vector<WordClassifier> classifiers; int BlockFromBaseStyle(int baseStyle) const { for (int b=0; b < classifications; b++) { if (baseStyle == baseStyles[b]) return b; } return -1; } int BlockFromStyle(int style) const { int b = 0; for (std::vector<WordClassifier>::const_iterator it=classifiers.begin(); it != classifiers.end(); ++it) { if (it->IncludesStyle(style)) return b; b++; } return -1; } public: SubStyles(const char *baseStyles_, int styleFirst_, int stylesAvailable_, int secondaryDistance_) : classifications(0), baseStyles(baseStyles_), styleFirst(styleFirst_), stylesAvailable(stylesAvailable_), secondaryDistance(secondaryDistance_), allocated(0) { while (baseStyles[classifications]) { classifications++; classifiers.push_back(WordClassifier()); } } int Allocate(int styleBase, int numberStyles) { int block = BlockFromBaseStyle(styleBase); if (block >= 0) { if ((allocated + numberStyles) > stylesAvailable) return -1; int startBlock = styleFirst + allocated; allocated += numberStyles; classifiers[block].Allocate(startBlock, numberStyles); return startBlock; } else { return -1; } } int Start(int styleBase) { int block = BlockFromBaseStyle(styleBase); return (block >= 0) ? classifiers[block].Start() : -1; } int Length(int styleBase) { int block = BlockFromBaseStyle(styleBase); return (block >= 0) ? classifiers[block].Length() : 0; } int DistanceToSecondaryStyles() const { return secondaryDistance; } void SetIdentifiers(int style, const char *identifiers) { int block = BlockFromStyle(style); if (block >= 0) classifiers[block].SetIdentifiers(style, identifiers); } void Free() { allocated = 0; for (std::vector<WordClassifier>::iterator it=classifiers.begin(); it != classifiers.end(); ++it) it->Clear(); } const WordClassifier &Classifier(int baseStyle) const { return classifiers[BlockFromBaseStyle(baseStyle)]; } }; #ifdef SCI_NAMESPACE } #endif #endif |
Added lexlib/WordList.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
// Scintilla source code edit control /** @file KeyWords.cxx ** Colourise for particular languages. **/ // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdio.h> #include <stdarg.h> #include <algorithm> #include "WordList.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif /** * Creates an array that points into each word in the string and puts \0 terminators * after each word. */ static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) { int prev = '\n'; int words = 0; // For rapid determination of whether a character is a separator, build // a look up table. bool wordSeparator[256]; for (int i=0; i<256; i++) { wordSeparator[i] = false; } wordSeparator['\r'] = true; wordSeparator['\n'] = true; if (!onlyLineEnds) { wordSeparator[' '] = true; wordSeparator['\t'] = true; } for (int j = 0; wordlist[j]; j++) { int curr = static_cast<unsigned char>(wordlist[j]); if (!wordSeparator[curr] && wordSeparator[prev]) words++; prev = curr; } char **keywords = new char *[words + 1]; if (keywords) { words = 0; prev = '\0'; size_t slen = strlen(wordlist); for (size_t k = 0; k < slen; k++) { if (!wordSeparator[static_cast<unsigned char>(wordlist[k])]) { if (!prev) { keywords[words] = &wordlist[k]; words++; } } else { wordlist[k] = '\0'; } prev = wordlist[k]; } keywords[words] = &wordlist[slen]; *len = words; } else { *len = 0; } return keywords; } bool WordList::operator!=(const WordList &other) const { if (len != other.len) return true; for (int i=0; i<len; i++) { if (strcmp(words[i], other.words[i]) != 0) return true; } return false; } void WordList::Clear() { if (words) { delete []list; delete []words; } words = 0; list = 0; len = 0; } #ifdef _MSC_VER static bool cmpWords(const char *a, const char *b) { return strcmp(a, b) == -1; } #else static int cmpWords(const void *a, const void *b) { return strcmp(*static_cast<const char * const *>(a), *static_cast<const char * const *>(b)); } static void SortWordList(char **words, unsigned int len) { qsort(reinterpret_cast<void *>(words), len, sizeof(*words), cmpWords); } #endif void WordList::Set(const char *s) { Clear(); list = new char[strlen(s) + 1]; strcpy(list, s); words = ArrayFromWordList(list, &len, onlyLineEnds); #ifdef _MSC_VER std::sort(words, words + len, cmpWords); #else SortWordList(words, len); #endif for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++) starts[k] = -1; for (int l = len - 1; l >= 0; l--) { unsigned char indexChar = words[l][0]; starts[indexChar] = l; } } /** Check whether a string is in the list. * List elements are either exact matches or prefixes. * Prefix elements start with '^' and match all strings that start with the rest of the element * so '^GTK_' matches 'GTK_X', 'GTK_MAJOR_VERSION', and 'GTK_'. */ bool WordList::InList(const char *s) const { if (0 == words) return false; unsigned char firstChar = s[0]; int j = starts[firstChar]; if (j >= 0) { while (static_cast<unsigned char>(words[j][0]) == firstChar) { if (s[1] == words[j][1]) { const char *a = words[j] + 1; const char *b = s + 1; while (*a && *a == *b) { a++; b++; } if (!*a && !*b) return true; } j++; } } j = starts['^']; if (j >= 0) { while (words[j][0] == '^') { const char *a = words[j] + 1; const char *b = s; while (*a && *a == *b) { a++; b++; } if (!*a) return true; j++; } } return false; } /** similar to InList, but word s can be a substring of keyword. * eg. the keyword define is defined as def~ine. This means the word must start * with def to be a keyword, but also defi, defin and define are valid. * The marker is ~ in this case. */ bool WordList::InListAbbreviated(const char *s, const char marker) const { if (0 == words) return false; unsigned char firstChar = s[0]; int j = starts[firstChar]; if (j >= 0) { while (static_cast<unsigned char>(words[j][0]) == firstChar) { bool isSubword = false; int start = 1; if (words[j][1] == marker) { isSubword = true; start++; } if (s[1] == words[j][start]) { const char *a = words[j] + start; const char *b = s + 1; while (*a && *a == *b) { a++; if (*a == marker) { isSubword = true; a++; } b++; } if ((!*a || isSubword) && !*b) return true; } j++; } } j = starts['^']; if (j >= 0) { while (words[j][0] == '^') { const char *a = words[j] + 1; const char *b = s; while (*a && *a == *b) { a++; b++; } if (!*a) return true; j++; } } return false; } |
Added lexlib/WordList.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
// Scintilla source code edit control /** @file WordList.h ** Hold a list of words. **/ // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef WORDLIST_H #define WORDLIST_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif /** */ class WordList { public: // Each word contains at least one character - a empty word acts as sentinel at the end. char **words; char *list; int len; bool onlyLineEnds; ///< Delimited by any white space or only line ends int starts[256]; WordList(bool onlyLineEnds_ = false) : words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_) {} ~WordList() { Clear(); } operator bool() const { return len ? true : false; } bool operator!=(const WordList &other) const; void Clear(); void Set(const char *s); bool InList(const char *s) const; bool InListAbbreviated(const char *s, const char marker) const; }; #ifdef SCI_NAMESPACE } #endif #endif |
Added qt/README.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
README for building of Scintilla on Qt There are three different Scintilla libraries that can be produced: ScintillaEditBase A basic widget callable from C++ which is small and can be used just as is or with higher level functionality added. ScintillaEdit A more complete C++ widget with a method for every Scintilla API and a secondary API allowing direct access to document objects. ScintillaEditPy A Python callable version of ScintillaEdit using the PySide bindings. Building a library ScintillaEditBase can be built without performing any generation steps. The ScintillaEditBase/ScintillaEditBase.pro project can be loaded into Qt Creator and the "Build All" command performed. Alternatively, run "qmake" to build make files and then use the platform make to build. Most commonly, use "make" on Unix and "nmake" on Windows. ScintillaEdit requires a generation command be run first. From the ScintillaEdit directory: python WidgetGen.py After the generation command has run, the ScintillaEdit.h and ScintillaEdit.cpp files will have been populated with the Scintilla API methods. To build, use Qt Creator or qmake and make as for ScintillaEditBase. ScintillaEditPy is more complex and instructions are found in ScintillaEditPy/README. |
Added qt/ScintillaEdit/ScintillaDocument.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
// ScintillaDocument.cpp // Wrapper for Scintilla document object so it can be manipulated independently. // Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware #include <vector> #include <map> #include "ScintillaDocument.h" #include "Platform.h" #include "ILexer.h" #include "Scintilla.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" #include "ContractionState.h" #include "CellBuffer.h" #include "KeyMap.h" #include "Indicator.h" #include "XPM.h" #include "LineMarker.h" #include "Style.h" #include "ViewStyle.h" #include "CharClassify.h" #include "Decoration.h" #include "Document.h" class WatcherHelper : public DocWatcher { ScintillaDocument *owner; public: WatcherHelper(ScintillaDocument *owner_); virtual ~WatcherHelper(); void NotifyModifyAttempt(Document *doc, void *userData); void NotifySavePoint(Document *doc, void *userData, bool atSavePoint); void NotifyModified(Document *doc, DocModification mh, void *userData); void NotifyDeleted(Document *doc, void *userData); void NotifyStyleNeeded(Document *doc, void *userData, int endPos); void NotifyLexerChanged(Document *doc, void *userData); void NotifyErrorOccurred(Document *doc, void *userData, int status); }; WatcherHelper::WatcherHelper(ScintillaDocument *owner_) : owner(owner_) { } WatcherHelper::~WatcherHelper() { } void WatcherHelper::NotifyModifyAttempt(Document *, void *) { owner->emit_modify_attempt(); } void WatcherHelper::NotifySavePoint(Document *, void *, bool atSavePoint) { owner->emit_save_point(atSavePoint); } void WatcherHelper::NotifyModified(Document *, DocModification mh, void *) { int length = mh.length; if (!mh.text) length = 0; QByteArray ba = QByteArray::fromRawData(mh.text, length); owner->emit_modified(mh.position, mh.modificationType, ba, length, mh.linesAdded, mh.line, mh.foldLevelNow, mh.foldLevelPrev); } void WatcherHelper::NotifyDeleted(Document *, void *) { } void WatcherHelper::NotifyStyleNeeded(Document *, void *, int endPos) { owner->emit_style_needed(endPos); } void WatcherHelper::NotifyLexerChanged(Document *, void *) { owner->emit_lexer_changed(); } void WatcherHelper::NotifyErrorOccurred(Document *, void *, int status) { owner->emit_error_occurred(status); } ScintillaDocument::ScintillaDocument(QObject *parent, void *pdoc_) : QObject(parent), pdoc(pdoc_), docWatcher(0) { if (!pdoc) { pdoc = new Document(); } docWatcher = new WatcherHelper(this); ((Document *)pdoc)->AddRef(); ((Document *)pdoc)->AddWatcher(docWatcher, pdoc); } ScintillaDocument::~ScintillaDocument() { Document *doc = static_cast<Document *>(pdoc); if (doc) { doc->RemoveWatcher(docWatcher, doc); doc->Release(); } pdoc = NULL; delete docWatcher; docWatcher = NULL; } void *ScintillaDocument::pointer() { return pdoc; } int ScintillaDocument::line_from_position(int pos) { return ((Document *)pdoc)->LineFromPosition(pos); } bool ScintillaDocument::is_cr_lf(int pos) { return ((Document *)pdoc)->IsCrLf(pos); } bool ScintillaDocument::delete_chars(int pos, int len) { return ((Document *)pdoc)->DeleteChars(pos, len); } int ScintillaDocument::undo() { return ((Document *)pdoc)->Undo(); } int ScintillaDocument::redo() { return ((Document *)pdoc)->Redo(); } bool ScintillaDocument::can_undo() { return ((Document *)pdoc)->CanUndo(); } bool ScintillaDocument::can_redo() { return ((Document *)pdoc)->CanRedo(); } void ScintillaDocument::delete_undo_history() { ((Document *)pdoc)->DeleteUndoHistory(); } bool ScintillaDocument::set_undo_collection(bool collect_undo) { return ((Document *)pdoc)->SetUndoCollection(collect_undo); } bool ScintillaDocument::is_collecting_undo() { return ((Document *)pdoc)->IsCollectingUndo(); } void ScintillaDocument::begin_undo_action() { ((Document *)pdoc)->BeginUndoAction(); } void ScintillaDocument::end_undo_action() { ((Document *)pdoc)->EndUndoAction(); } void ScintillaDocument::set_save_point() { ((Document *)pdoc)->SetSavePoint(); } bool ScintillaDocument::is_save_point() { return ((Document *)pdoc)->IsSavePoint(); } void ScintillaDocument::set_read_only(bool read_only) { ((Document *)pdoc)->SetReadOnly(read_only); } bool ScintillaDocument::is_read_only() { return ((Document *)pdoc)->IsReadOnly(); } void ScintillaDocument::insert_string(int position, QByteArray &str) { ((Document *)pdoc)->InsertString(position, str.data(), str.size()); } QByteArray ScintillaDocument::get_char_range(int position, int length) { Document *doc = (Document *)pdoc; if (position < 0 || length <= 0 || position + length > doc->Length()) return QByteArray(); QByteArray ba(length, '\0'); doc->GetCharRange(ba.data(), position, length); return ba; } char ScintillaDocument::style_at(int position) { return ((Document *)pdoc)->StyleAt(position); } int ScintillaDocument::line_start(int lineno) { return ((Document *)pdoc)->LineStart(lineno); } int ScintillaDocument::line_end(int lineno) { return ((Document *)pdoc)->LineEnd(lineno); } int ScintillaDocument::line_end_position(int pos) { return ((Document *)pdoc)->LineEndPosition(pos); } int ScintillaDocument::length() { return ((Document *)pdoc)->Length(); } int ScintillaDocument::lines_total() { return ((Document *)pdoc)->LinesTotal(); } void ScintillaDocument::start_styling(int position, char flags) { ((Document *)pdoc)->StartStyling(position, flags); } bool ScintillaDocument::set_style_for(int length, char style) { return ((Document *)pdoc)->SetStyleFor(length, style); } int ScintillaDocument::get_end_styled() { return ((Document *)pdoc)->GetEndStyled(); } void ScintillaDocument::ensure_styled_to(int position) { ((Document *)pdoc)->EnsureStyledTo(position); } void ScintillaDocument::set_current_indicator(int indic) { ((Document *)pdoc)->decorations.SetCurrentIndicator(indic); } void ScintillaDocument::decoration_fill_range(int position, int value, int fillLength) { ((Document *)pdoc)->DecorationFillRange(position, value, fillLength); } int ScintillaDocument::decorations_value_at(int indic, int position) { return ((Document *)pdoc)->decorations.ValueAt(indic, position); } int ScintillaDocument::decorations_start(int indic, int position) { return ((Document *)pdoc)->decorations.Start(indic, position); } int ScintillaDocument::decorations_end(int indic, int position) { return ((Document *)pdoc)->decorations.End(indic, position); } int ScintillaDocument::get_code_page() { return ((Document *)pdoc)->CodePage(); } void ScintillaDocument::set_code_page(int code_page) { ((Document *)pdoc)->dbcsCodePage = code_page; } int ScintillaDocument::move_position_outside_char(int pos, int move_dir, bool check_line_end) { return ((Document *)pdoc)->MovePositionOutsideChar(pos, move_dir, check_line_end); } // Signal emitters void ScintillaDocument::emit_modify_attempt() { emit modify_attempt(); } void ScintillaDocument::emit_save_point(bool atSavePoint) { emit save_point(atSavePoint); } void ScintillaDocument::emit_modified(int position, int modification_type, const QByteArray& text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev) { emit modified(position, modification_type, text, length, linesAdded, line, foldLevelNow, foldLevelPrev); } void ScintillaDocument::emit_style_needed(int pos) { emit style_needed(pos); } void ScintillaDocument::emit_lexer_changed() { emit lexer_changed(); } void ScintillaDocument::emit_error_occurred(int status) { emit error_occurred(status); } |
Added qt/ScintillaEdit/ScintillaDocument.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
// ScintillaDocument.h // Wrapper for Scintilla document object so it can be manipulated independently. // Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware #ifndef SCINTILLADOCUMENT_H #define SCINTILLADOCUMENT_H #include <QObject> class WatcherHelper; #ifndef EXPORT_IMPORT_API #ifdef WIN32 #ifdef MAKING_LIBRARY #define EXPORT_IMPORT_API __declspec(dllexport) #else // Defining dllimport upsets moc #define EXPORT_IMPORT_API __declspec(dllimport) //#define EXPORT_IMPORT_API #endif #else #define EXPORT_IMPORT_API #endif #endif class EXPORT_IMPORT_API ScintillaDocument : public QObject { Q_OBJECT void *pdoc; WatcherHelper *docWatcher; public: explicit ScintillaDocument(QObject *parent = 0, void *pdoc_=0); virtual ~ScintillaDocument(); void *pointer(); int line_from_position(int pos); bool is_cr_lf(int pos); bool delete_chars(int pos, int len); int undo(); int redo(); bool can_undo(); bool can_redo(); void delete_undo_history(); bool set_undo_collection(bool collect_undo); bool is_collecting_undo(); void begin_undo_action(); void end_undo_action(); void set_save_point(); bool is_save_point(); void set_read_only(bool read_only); bool is_read_only(); void insert_string(int position, QByteArray &str); QByteArray get_char_range(int position, int length); char style_at(int position); int line_start(int lineno); int line_end(int lineno); int line_end_position(int pos); int length(); int lines_total(); void start_styling(int position, char flags); bool set_style_for(int length, char style); int get_end_styled(); void ensure_styled_to(int position); void set_current_indicator(int indic); void decoration_fill_range(int position, int value, int fillLength); int decorations_value_at(int indic, int position); int decorations_start(int indic, int position); int decorations_end(int indic, int position); int get_code_page(); void set_code_page(int code_page); int move_position_outside_char(int pos, int move_dir, bool check_line_end); private: void emit_modify_attempt(); void emit_save_point(bool atSavePoint); void emit_modified(int position, int modification_type, const QByteArray& text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev); void emit_style_needed(int pos); void emit_lexer_changed(); void emit_error_occurred(int status); signals: void modify_attempt(); void save_point(bool atSavePoint); void modified(int position, int modification_type, const QByteArray& text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev); void style_needed(int pos); void lexer_changed(); void error_occurred(int status); friend class WatcherHelper; }; #endif // SCINTILLADOCUMENT_H |
Added qt/ScintillaEdit/ScintillaEdit.cpp.template.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
// ScintillaEdit.cpp // Extended version of ScintillaEditBase with a method for each API // Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware #include "ScintillaEdit.h" ScintillaEdit::ScintillaEdit(QWidget *parent) : ScintillaEditBase(parent) { } ScintillaEdit::~ScintillaEdit() { } QByteArray ScintillaEdit::TextReturner(int message, uptr_t wParam) const { int length = send(message, wParam, 0); QByteArray ba(length, '\0'); send(message, wParam, (sptr_t)ba.data()); // Remove extra NULs if (ba.size() > 0 && ba.at(ba.size()-1) == 0) ba.chop(1); return ba; } QPair<int, int>ScintillaEdit::find_text(int flags, const char *text, int cpMin, int cpMax) { struct TextToFind ft = {{0, 0}, 0, {0, 0}}; ft.chrg.cpMin = cpMin; ft.chrg.cpMax = cpMax; ft.chrgText.cpMin = cpMin; ft.chrgText.cpMax = cpMax; ft.lpstrText = const_cast<char *>(text); send(SCI_FINDTEXT, flags, (uptr_t) (&ft)); return QPair<int,int>(ft.chrgText.cpMin, ft.chrgText.cpMax); } QByteArray ScintillaEdit::get_text_range(int start, int end) { if (start > end) start = end; int length = end-start; QByteArray ba(length+1, '\0'); struct TextRange tr = {{start, end}, ba.data()}; length = send(SCI_GETTEXTRANGE, 0, (sptr_t)&tr); ba.chop(1); // Remove extra NUL return ba; } ScintillaDocument *ScintillaEdit::get_doc() { return new ScintillaDocument(0, (void *)send(SCI_GETDOCPOINTER, 0, 0)); } void ScintillaEdit::set_doc(ScintillaDocument *pdoc_) { send(SCI_SETDOCPOINTER, 0, (sptr_t)(pdoc_->pointer())); } /* ++Autogenerated -- start of section automatically generated from Scintilla.iface */ /* --Autogenerated -- end of section automatically generated from Scintilla.iface */ |
Added qt/ScintillaEdit/ScintillaEdit.h.template.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
// ScintillaEdit.h // Extended version of ScintillaEditBase with a method for each API // Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware #ifndef SCINTILLAEDIT_H #define SCINTILLAEDIT_H #include <QPair> #include "ScintillaEditBase.h" #include "ScintillaDocument.h" #ifdef SCI_NAMESPACE namespace Scintilla { #endif #ifndef EXPORT_IMPORT_API #ifdef WIN32 #ifdef MAKING_LIBRARY #define EXPORT_IMPORT_API __declspec(dllexport) #else // Defining dllimport upsets moc #define EXPORT_IMPORT_API __declspec(dllimport) //#define EXPORT_IMPORT_API #endif #else #define EXPORT_IMPORT_API #endif #endif class EXPORT_IMPORT_API ScintillaEdit : public ScintillaEditBase { Q_OBJECT public: ScintillaEdit(QWidget *parent = 0); virtual ~ScintillaEdit(); QByteArray TextReturner(int message, uptr_t wParam) const; QPair<int, int>find_text(int flags, const char *text, int cpMin, int cpMax); QByteArray get_text_range(int start, int end); ScintillaDocument *get_doc(); void set_doc(ScintillaDocument *pdoc_); // Same as previous two methods but with Qt style names QPair<int, int>findText(int flags, const char *text, int cpMin, int cpMax) { return find_text(flags, text, cpMin, cpMax); } QByteArray textRange(int start, int end) { return get_text_range(start, end); } /* ++Autogenerated -- start of section automatically generated from Scintilla.iface */ /* --Autogenerated -- end of section automatically generated from Scintilla.iface */ }; #ifdef SCI_NAMESPACE } #endif #endif /* SCINTILLAEDIT_H */ |
Added qt/ScintillaEdit/ScintillaEdit.pro.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
#------------------------------------------------- # # Project created by QtCreator 2011-05-05T12:41:23 # #------------------------------------------------- QT += core gui TARGET = ScintillaEdit TEMPLATE = lib CONFIG += lib_bundle VERSION = 3.3.0 SOURCES += \ ScintillaEdit.cpp \ ScintillaDocument.cpp \ ../ScintillaEditBase/PlatQt.cpp \ ../ScintillaEditBase/ScintillaQt.cpp \ ../ScintillaEditBase/ScintillaEditBase.cpp \ ../../src/XPM.cxx \ ../../src/ViewStyle.cxx \ ../../src/UniConversion.cxx \ ../../src/Style.cxx \ ../../src/Selection.cxx \ ../../src/ScintillaBase.cxx \ ../../src/RunStyles.cxx \ ../../src/RESearch.cxx \ ../../src/PositionCache.cxx \ ../../src/PerLine.cxx \ ../../src/LineMarker.cxx \ ../../src/KeyMap.cxx \ ../../src/Indicator.cxx \ ../../src/ExternalLexer.cxx \ ../../src/Editor.cxx \ ../../src/Document.cxx \ ../../src/Decoration.cxx \ ../../src/ContractionState.cxx \ ../../src/CharClassify.cxx \ ../../src/CellBuffer.cxx \ ../../src/Catalogue.cxx \ ../../src/CallTip.cxx \ ../../src/AutoComplete.cxx \ ../../lexlib/WordList.cxx \ ../../lexlib/StyleContext.cxx \ ../../lexlib/PropSetSimple.cxx \ ../../lexlib/LexerSimple.cxx \ ../../lexlib/LexerNoExceptions.cxx \ ../../lexlib/LexerModule.cxx \ ../../lexlib/LexerBase.cxx \ ../../lexlib/CharacterSet.cxx \ ../../lexlib/Accessor.cxx \ ../../lexers/*.cxx HEADERS += \ ScintillaEdit.h \ ScintillaDocument.h \ ../ScintillaEditBase/ScintillaEditBase.h \ ../ScintillaEditBase/ScintillaQt.h OTHER_FILES += INCLUDEPATH += ../ScintillaEditBase ../../include ../../src ../../lexlib DEFINES += SCINTILLA_QT=1 MAKING_LIBRARY=1 SCI_LEXER=1 _CRT_SECURE_NO_DEPRECATE=1 DESTDIR = ../../bin DLLDESTDIR = ../../bin macx { QMAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../Frameworks/ } |
Added qt/ScintillaEdit/WidgetGen.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
#!/usr/bin/env python # WidgetGen.py - regenerate the ScintillaWidgetCpp.cpp and ScintillaWidgetCpp.h files # Check that API includes all gtkscintilla2 functions import sys import os import getopt scintillaDirectory = "../.." scintillaIncludeDirectory = os.path.join(scintillaDirectory, "include") sys.path.append(scintillaIncludeDirectory) import Face def Contains(s,sub): return s.find(sub) != -1 def underscoreName(s): # Name conversion fixes to match gtkscintilla2 irregular = ['WS', 'EOL', 'AutoC', 'KeyWords', 'BackSpace', 'UnIndents', 'RE', 'RGBA'] for word in irregular: replacement = word[0] + word[1:].lower() s = s.replace(word, replacement) out = "" for c in s: if c.isupper(): if out: out += "_" out += c.lower() else: out += c return out def normalisedName(s, options, role=None): if options["qtStyle"]: if role == "get": s = s.replace("Get", "") return s[0].lower() + s[1:] else: return underscoreName(s) typeAliases = { "position": "int", "colour": "int", "keymod": "int", "string": "const char *", "stringresult": "const char *", "cells": "const char *", } def cppAlias(s): if s in typeAliases: return typeAliases[s] else: return s understoodTypes = ["", "void", "int", "bool", "position", "colour", "keymod", "string", "stringresult", "cells"] def checkTypes(name, v): understandAllTypes = True if v["ReturnType"] not in understoodTypes: #~ print("Do not understand", v["ReturnType"], "for", name) understandAllTypes = False if v["Param1Type"] not in understoodTypes: #~ print("Do not understand", v["Param1Type"], "for", name) understandAllTypes = False if v["Param2Type"] not in understoodTypes: #~ print("Do not understand", v["Param2Type"], "for", name) understandAllTypes = False return understandAllTypes def arguments(v, stringResult, options): ret = "" p1Type = cppAlias(v["Param1Type"]) if p1Type: ret = ret + p1Type + " " + normalisedName(v["Param1Name"], options) p2Type = cppAlias(v["Param2Type"]) if p2Type and not stringResult: if p1Type: ret = ret + ", " ret = ret + p2Type + " " + normalisedName(v["Param2Name"], options) return ret def printPyFile(f,out, options): for name in f.order: v = f.features[name] if v["Category"] != "Deprecated": feat = v["FeatureType"] if feat in ["val"]: out.write(name + "=" + v["Value"] + "\n") if feat in ["evt"]: out.write("SCN_" + name.upper() + "=" + v["Value"] + "\n") def printHFile(f,out, options): for name in f.order: v = f.features[name] if v["Category"] != "Deprecated": feat = v["FeatureType"] if feat in ["fun", "get", "set"]: if checkTypes(name, v): constDeclarator = " const" if feat == "get" else "" returnType = cppAlias(v["ReturnType"]) stringResult = v["Param2Type"] == "stringresult" if stringResult: returnType = "QByteArray" out.write("\t" + returnType + " " + normalisedName(name, options, feat) + "(") out.write(arguments(v, stringResult, options)) out.write(")" + constDeclarator + ";\n") def methodNames(f, options): for name in f.order: v = f.features[name] if v["Category"] != "Deprecated": feat = v["FeatureType"] if feat in ["fun", "get", "set"]: if checkTypes(name, v): yield normalisedName(name, options) def printCPPFile(f,out, options): for name in f.order: v = f.features[name] if v["Category"] != "Deprecated": feat = v["FeatureType"] if feat in ["fun", "get", "set"]: if checkTypes(name, v): constDeclarator = " const" if feat == "get" else "" featureDefineName = "SCI_" + name.upper() returnType = cppAlias(v["ReturnType"]) stringResult = v["Param2Type"] == "stringresult" if stringResult: returnType = "QByteArray" returnStatement = "" if returnType != "void": returnStatement = "return " out.write(returnType + " ScintillaEdit::" + normalisedName(name, options, feat) + "(") out.write(arguments(v, stringResult, options)) out.write(")" + constDeclarator + " {\n") if stringResult: out.write(" " + returnStatement + "TextReturner(" + featureDefineName + ", ") if "*" in cppAlias(v["Param1Type"]): out.write("(uptr_t)") if v["Param1Name"]: out.write(normalisedName(v["Param1Name"], options)) else: out.write("0") out.write(");\n") else: out.write(" " + returnStatement + "send(" + featureDefineName + ", ") if "*" in cppAlias(v["Param1Type"]): out.write("(uptr_t)") if v["Param1Name"]: out.write(normalisedName(v["Param1Name"], options)) else: out.write("0") out.write(", ") if "*" in cppAlias(v["Param2Type"]): out.write("(sptr_t)") if v["Param2Name"]: out.write(normalisedName(v["Param2Name"], options)) else: out.write("0") out.write(");\n") out.write("}\n") out.write("\n") def CopyWithInsertion(input, output, genfn, definition, options): copying = 1 for line in input.readlines(): if copying: output.write(line) if "/* ++Autogenerated" in line or "# ++Autogenerated" in line or "<!-- ++Autogenerated" in line: copying = 0 genfn(definition, output, options) # ~~ form needed as XML comments can not contain -- if "/* --Autogenerated" in line or "# --Autogenerated" in line or "<!-- ~~Autogenerated" in line: copying = 1 output.write(line) def contents(filename): with open(filename, "U") as f: t = f.read() return t def Generate(templateFile, destinationFile, genfn, definition, options): inText = contents(templateFile) try: currentText = contents(destinationFile) except IOError: currentText = "" tempname = "WidgetGen.tmp" with open(tempname, "w") as out: with open(templateFile, "U") as hfile: CopyWithInsertion(hfile, out, genfn, definition, options) outText = contents(tempname) if currentText == outText: os.unlink(tempname) else: try: os.unlink(destinationFile) except OSError: # Will see failure if file does not yet exist pass os.rename(tempname, destinationFile) def gtkNames(): # The full path on my machine: should be altered for anyone else p = "C:/Users/Neil/Downloads/wingide-source-4.0.1-1/wingide-source-4.0.1-1/external/gtkscintilla2/gtkscintilla.c" with open(p) as f: for l in f.readlines(): if "gtk_scintilla_" in l: name = l.split()[1][14:] if '(' in name: name = name.split('(')[0] yield name def usage(): print("WidgetGen.py [-c|--clean][-h|--help][-u|--underscore-names]") print("") print("Generate full APIs for ScintillaEdit class and ScintillaConstants.py.") print("") print("options:") print("") print("-c --clean remove all generated code from files") print("-h --help display this text") print("-u --underscore-names use method_names consistent with GTK+ standards") def readInterface(cleanGenerated): f = Face.Face() if not cleanGenerated: f.ReadFromFile("../../include/Scintilla.iface") return f def main(argv): # Using local path for gtkscintilla2 so don't default to checking checkGTK = False cleanGenerated = False qtStyleInterface = True # The --gtk-check option checks for full coverage of the gtkscintilla2 API but # depends on a particular directory so is not mentioned in --help. opts, args = getopt.getopt(argv, "hcgu", ["help", "clean", "gtk-check", "underscore-names"]) for opt, arg in opts: if opt in ("-h", "--help"): usage() sys.exit() elif opt in ("-c", "--clean"): cleanGenerated = True elif opt in ("-g", "--gtk-check"): checkGTK = True elif opt in ("-u", "--underscore-names"): qtStyleInterface = False options = {"qtStyle": qtStyleInterface} f = readInterface(cleanGenerated) try: Generate("ScintillaEdit.cpp.template", "ScintillaEdit.cpp", printCPPFile, f, options) Generate("ScintillaEdit.h.template", "ScintillaEdit.h", printHFile, f, options) Generate("../ScintillaEditPy/ScintillaConstants.py.template", "../ScintillaEditPy/ScintillaConstants.py", printPyFile, f, options) if checkGTK: names = set(methodNames(f)) #~ print("\n".join(names)) namesGtk = set(gtkNames()) for name in namesGtk: if name not in names: print(name, "not found in Qt version") for name in names: if name not in namesGtk: print(name, "not found in GTK+ version") except: raise if cleanGenerated: for file in ["ScintillaEdit.cpp", "ScintillaEdit.h", "../ScintillaEditPy/ScintillaConstants.py"]: try: os.remove(file) except OSError: pass if __name__ == "__main__": main(sys.argv[1:]) |
Added qt/ScintillaEdit/WidgetGen.pyc.
cannot compute difference between binary files
Added qt/ScintillaEditBase/Notes.txt.
> > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Issues with Scintilla for Qt Qt reports character descenders are 1 pixel shorter than they really are. There is a tweak in the code to add a pixel in. This may have to be reviewed for Qt 5. There's a comment in the Qt code for Windows: // ### we substract 1 to even out the historical +1 in QFontMetrics's // ### height=asc+desc+1 equation. Fix in Qt5. The clocks used aren't great. QTime is a time since midnight clock so wraps around and is only accurate to, at best, milliseconds. On OS X drawing text into a pixmap moves it around 1 pixel to the right compared to drawing it directly onto a window. Buffered drawing turned off by default to avoid this. Reported as QTBUG-19483. Only one QPainter can be active on any widget at a time. Scintilla only draws into one widget but reenters for measurement. |
Added qt/ScintillaEditBase/PlatQt.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 |
// // Copyright (c) 1990-2011, Scientific Toolworks, Inc. // // The License.txt file describes the conditions under which this software may be distributed. // // Author: Jason Haslam // // Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware // Scintilla platform layer for Qt #include "PlatQt.h" #include "Scintilla.h" #include "FontQuality.h" #include <QApplication> #include <QFont> #include <QColor> #include <QRect> #include <QPaintDevice> #include <QPaintEngine> #include <QWidget> #include <QPixmap> #include <QPainter> #include <QMenu> #include <QAction> #include <QTime> #include <QMessageBox> #include <QTextCodec> #include <QListWidget> #include <QVarLengthArray> #include <QScrollBar> #include <QDesktopWidget> #include <QTextLayout> #include <QTextLine> #include <QLibrary> #include <cstdio> #ifdef SCI_NAMESPACE namespace Scintilla { #endif //---------------------------------------------------------------------- // Convert from a Scintilla characterSet value to a Qt codec name. const char *CharacterSetID(int characterSet) { switch (characterSet) { //case SC_CHARSET_ANSI: // return ""; case SC_CHARSET_DEFAULT: return "ISO 8859-1"; case SC_CHARSET_BALTIC: return "ISO 8859-13"; case SC_CHARSET_CHINESEBIG5: return "Big5"; case SC_CHARSET_EASTEUROPE: return "ISO 8859-2"; case SC_CHARSET_GB2312: return "GB18030-0"; case SC_CHARSET_GREEK: return "ISO 8859-7"; case SC_CHARSET_HANGUL: return "CP949"; case SC_CHARSET_MAC: return "Apple Roman"; //case SC_CHARSET_OEM: // return "ASCII"; case SC_CHARSET_RUSSIAN: return "KOI8-R"; case SC_CHARSET_CYRILLIC: return "Windows-1251"; case SC_CHARSET_SHIFTJIS: return "Shift-JIS"; //case SC_CHARSET_SYMBOL: // return ""; case SC_CHARSET_TURKISH: return "ISO 8859-9"; //case SC_CHARSET_JOHAB: // return "CP1361"; case SC_CHARSET_HEBREW: return "ISO 8859-8"; case SC_CHARSET_ARABIC: return "ISO 8859-6"; case SC_CHARSET_VIETNAMESE: return "Windows-1258"; case SC_CHARSET_THAI: return "TIS-620"; case SC_CHARSET_8859_15: return "ISO 8859-15"; default: return "ISO 8859-1"; } } class FontAndCharacterSet { public: int characterSet; QFont *pfont; FontAndCharacterSet(int characterSet_, QFont *pfont): characterSet(characterSet_), pfont(pfont) { } ~FontAndCharacterSet() { delete pfont; pfont = 0; } }; static int FontCharacterSet(Font &f) { return reinterpret_cast<FontAndCharacterSet *>(f.GetID())->characterSet; } static QFont *FontPointer(Font &f) { return reinterpret_cast<FontAndCharacterSet *>(f.GetID())->pfont; } Font::Font() : fid(0) {} Font::~Font() { delete reinterpret_cast<FontAndCharacterSet *>(fid); fid = 0; } static QFont::StyleStrategy ChooseStrategy(int eff) { switch (eff) { case SC_EFF_QUALITY_DEFAULT: return QFont::PreferDefault; case SC_EFF_QUALITY_NON_ANTIALIASED: return QFont::NoAntialias; case SC_EFF_QUALITY_ANTIALIASED: return QFont::PreferAntialias; case SC_EFF_QUALITY_LCD_OPTIMIZED: return QFont::PreferAntialias; default: return QFont::PreferDefault; } } void Font::Create(const FontParameters &fp) { Release(); QFont *font = new QFont; font->setStyleStrategy(ChooseStrategy(fp.extraFontFlag)); font->setFamily(QString::fromUtf8(fp.faceName)); font->setPointSize(fp.size); font->setBold(fp.weight > 500); font->setItalic(fp.italic); fid = new FontAndCharacterSet(fp.characterSet, font); } void Font::Release() { if (fid) delete reinterpret_cast<FontAndCharacterSet *>(fid); fid = 0; } SurfaceImpl::SurfaceImpl() : device(0), painter(0), deviceOwned(false), painterOwned(false), x(0), y(0), unicodeMode(false), codePage(0), codecName(0), codec(0) {} SurfaceImpl::~SurfaceImpl() { Release(); } void SurfaceImpl::Init(WindowID wid) { Release(); device = static_cast<QWidget *>(wid); } void SurfaceImpl::Init(SurfaceID sid, WindowID /*wid*/) { Release(); device = static_cast<QPaintDevice *>(sid); } void SurfaceImpl::InitPixMap(int width, int height, Surface * /*surface*/, WindowID /*wid*/) { Release(); if (width < 1) width = 1; if (height < 1) height = 1; deviceOwned = true; device = new QPixmap(width, height); } void SurfaceImpl::Release() { if (painterOwned && painter) { delete painter; } if (deviceOwned && device) { delete device; } device = 0; painter = 0; deviceOwned = false; painterOwned = false; } bool SurfaceImpl::Initialised() { return device != 0; } void SurfaceImpl::PenColour(ColourDesired fore) { QPen penOutline(QColorFromCA(fore)); penOutline.setCapStyle(Qt::FlatCap); GetPainter()->setPen(penOutline); } void SurfaceImpl::BrushColour(ColourDesired back) { GetPainter()->setBrush(QBrush(QColorFromCA(back))); } void SurfaceImpl::SetCodec(Font &font) { if (font.GetID()) { const char *csid = "UTF-8"; if (!unicodeMode) csid = CharacterSetID(FontCharacterSet(font)); if (csid != codecName) { codecName = csid; codec = QTextCodec::codecForName(csid); } } } void SurfaceImpl::SetFont(Font &font) { if (font.GetID()) { GetPainter()->setFont(*FontPointer(font)); SetCodec(font); } } int SurfaceImpl::LogPixelsY() { return device->logicalDpiY(); } int SurfaceImpl::DeviceHeightFont(int points) { return points; } void SurfaceImpl::MoveTo(int x_, int y_) { x = x_; y = y_; } void SurfaceImpl::LineTo(int x_, int y_) { QLineF line(x, y, x_, y_); GetPainter()->drawLine(line); x = x_; y = y_; } void SurfaceImpl::Polygon(Point *pts, int npts, ColourDesired fore, ColourDesired back) { PenColour(fore); BrushColour(back); QPoint *qpts = new QPoint[npts]; for (int i = 0; i < npts; i++) { qpts[i] = QPoint(pts[i].x, pts[i].y); } GetPainter()->drawPolygon(qpts, npts); delete [] qpts; } void SurfaceImpl::RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) { PenColour(fore); BrushColour(back); QRect rect = QRect(rc.left, rc.top, rc.Width() - 1, rc.Height() - 1); GetPainter()->drawRect(rect); } void SurfaceImpl::FillRectangle(PRectangle rc, ColourDesired back) { BrushColour(back); GetPainter()->setPen(Qt::NoPen); GetPainter()->drawRect(QRectFromPRect(rc)); } void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) { // Tile pattern over rectangle SurfaceImpl *surface = static_cast<SurfaceImpl *>(&surfacePattern); // Currently assumes 8x8 pattern int widthPat = 8; int heightPat = 8; for (int xTile = rc.left; xTile < rc.right; xTile += widthPat) { int widthx = (xTile + widthPat > rc.right) ? rc.right - xTile : widthPat; for (int yTile = rc.top; yTile < rc.bottom; yTile += heightPat) { int heighty = (yTile + heightPat > rc.bottom) ? rc.bottom - yTile : heightPat; QRect source(0, 0, widthx, heighty); QRect target(xTile, yTile, widthx, heighty); QPixmap *pixmap = static_cast<QPixmap *>(surface->GetPaintDevice()); GetPainter()->drawPixmap(target, *pixmap, source); } } } void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back) { PenColour(fore); BrushColour(back); GetPainter()->drawRoundRect(QRectFromPRect(rc)); } void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, ColourDesired outline, int alphaOutline, int /*flags*/) { QColor qOutline = QColorFromCA(outline); qOutline.setAlpha(alphaOutline); GetPainter()->setPen(QPen(qOutline)); QColor qFill = QColorFromCA(fill); qFill.setAlpha(alphaFill); GetPainter()->setBrush(QBrush(qFill)); // A radius of 1 shows no curve so add 1 qreal radius = cornerSize+1; QRect rect(rc.left, rc.top, rc.Width() - 1, rc.Height() - 1); GetPainter()->drawRoundedRect(rect, radius, radius); } static std::vector<unsigned char> ImageByteSwapped(int width, int height, const unsigned char *pixelsImage) { // Input is RGBA, but Format_ARGB32 is BGRA, so swap the red bytes and blue bytes size_t bytes = width * height * 4; std::vector<unsigned char> imageBytes(pixelsImage, pixelsImage+bytes); for (size_t i=0; i<bytes; i+=4) std::swap(imageBytes[i], imageBytes[i+2]); return imageBytes; } void SurfaceImpl::DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) { std::vector<unsigned char> imageBytes = ImageByteSwapped(width, height, pixelsImage); QImage image(&imageBytes[0], width, height, QImage::Format_ARGB32); QPoint pt(rc.left, rc.top); GetPainter()->drawImage(pt, image); } void SurfaceImpl::Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) { PenColour(fore); BrushColour(back); GetPainter()->drawEllipse(QRectFromPRect(rc)); } void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) { SurfaceImpl *source = static_cast<SurfaceImpl *>(&surfaceSource); QPixmap *pixmap = static_cast<QPixmap *>(source->GetPaintDevice()); GetPainter()->drawPixmap(rc.left, rc.top, *pixmap, from.x, from.y, -1, -1); } void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) { SetFont(font); PenColour(fore); GetPainter()->setBackground(QColorFromCA(back)); GetPainter()->setBackgroundMode(Qt::OpaqueMode); QString su = codec->toUnicode(s, len); GetPainter()->drawText(QPointF(rc.left, ybase), su); } void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) { SetClip(rc); DrawTextNoClip(rc, font, ybase, s, len, fore, back); GetPainter()->setClipping(false); } void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font, XYPOSITION ybase, const char *s, int len, ColourDesired fore) { SetFont(font); PenColour(fore); GetPainter()->setBackgroundMode(Qt::TransparentMode); QString su = codec->toUnicode(s, len); GetPainter()->drawText(QPointF(rc.left, ybase), su); } void SurfaceImpl::SetClip(PRectangle rc) { GetPainter()->setClipRect(QRectFromPRect(rc)); } static size_t utf8LengthFromLead(unsigned char uch) { if (uch >= (0x80 + 0x40 + 0x20 + 0x10)) { return 4; } else if (uch >= (0x80 + 0x40 + 0x20)) { return 3; } else if (uch >= (0x80)) { return 2; } else { return 1; } } void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, XYPOSITION *positions) { if (!font.GetID()) return; SetCodec(font); QString su = codec->toUnicode(s, len); QTextLayout tlay(su, *FontPointer(font)); tlay.beginLayout(); QTextLine tl = tlay.createLine(); tlay.endLayout(); if (unicodeMode) { int fit = su.size(); int ui=0; const unsigned char *us = reinterpret_cast<const unsigned char *>(s); int i=0; while (ui<fit) { size_t lenChar = utf8LengthFromLead(us[i]); size_t codeUnits = (lenChar < 4) ? 1 : 2; qreal xPosition = tl.cursorToX(ui+codeUnits); for (unsigned int bytePos=0; (bytePos<lenChar) && (i<len); bytePos++) { positions[i++] = qRound(xPosition); } ui += codeUnits; } int lastPos = 0; if (i > 0) lastPos = positions[i-1]; while (i<len) { positions[i++] = lastPos; } } else if (codePage) { // DBCS int ui = 0; for (int i=0; i<len;) { size_t lenChar = Platform::IsDBCSLeadByte(codePage, s[i]) ? 2 : 1; qreal xPosition = tl.cursorToX(ui+1); for (unsigned int bytePos=0; (bytePos<lenChar) && (i<len); bytePos++) { positions[i++] = qRound(xPosition); } ui++; } } else { // Single byte encoding for (int i=0; i<len; i++) { positions[i] = qRound(tl.cursorToX(i+1)); } } } XYPOSITION SurfaceImpl::WidthText(Font &font, const char *s, int len) { QFontMetrics metrics(*FontPointer(font), device); SetCodec(font); QString string = codec->toUnicode(s, len); return metrics.width(string); } XYPOSITION SurfaceImpl::WidthChar(Font &font, char ch) { QFontMetrics metrics(*FontPointer(font), device); return metrics.width(ch); } XYPOSITION SurfaceImpl::Ascent(Font &font) { QFontMetrics metrics(*FontPointer(font), device); return metrics.ascent(); } XYPOSITION SurfaceImpl::Descent(Font &font) { QFontMetrics metrics(*FontPointer(font), device); // Qt returns 1 less than true descent // See: QFontEngineWin::descent which says: // ### we substract 1 to even out the historical +1 in QFontMetrics's // ### height=asc+desc+1 equation. Fix in Qt5. return metrics.descent() + 1; } XYPOSITION SurfaceImpl::InternalLeading(Font & /* font */) { return 0; } XYPOSITION SurfaceImpl::ExternalLeading(Font &font) { QFontMetrics metrics(*FontPointer(font), device); return metrics.leading(); } XYPOSITION SurfaceImpl::Height(Font &font) { QFontMetrics metrics(*FontPointer(font), device); return metrics.height(); } XYPOSITION SurfaceImpl::AverageCharWidth(Font &font) { QFontMetrics metrics(*FontPointer(font), device); return metrics.averageCharWidth(); } void SurfaceImpl::FlushCachedState() { if (device->paintingActive()) { GetPainter()->setPen(QPen()); GetPainter()->setBrush(QBrush()); } } void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) { unicodeMode=unicodeMode_; } void SurfaceImpl::SetDBCSMode(int codePage_) { codePage = codePage_; } QPaintDevice *SurfaceImpl::GetPaintDevice() { return device; } QPainter *SurfaceImpl::GetPainter() { Q_ASSERT(device); if (painter == 0) { if (device->paintingActive()) { painter = device->paintEngine()->painter(); } else { painterOwned = true; painter = new QPainter(device); } // Set text antialiasing unconditionally. // The font's style strategy will override. painter->setRenderHint(QPainter::TextAntialiasing, true); } return painter; } Surface *Surface::Allocate(int) { return new SurfaceImpl; } //---------------------------------------------------------------------- namespace { QWidget *window(WindowID wid) { return static_cast<QWidget *>(wid); } } Window::~Window() {} void Window::Destroy() { if (wid) delete window(wid); wid = 0; } bool Window::HasFocus() { return wid ? window(wid)->hasFocus() : false; } PRectangle Window::GetPosition() { // Before any size allocated pretend its 1000 wide so not scrolled return wid ? PRectFromQRect(window(wid)->frameGeometry()) : PRectangle(0, 0, 1000, 1000); } void Window::SetPosition(PRectangle rc) { if (wid) window(wid)->setGeometry(QRectFromPRect(rc)); } void Window::SetPositionRelative(PRectangle rc, Window relativeTo) { QPoint oPos = window(relativeTo.wid)->mapToGlobal(QPoint(0,0)); int ox = oPos.x(); int oy = oPos.y(); ox += rc.left; if (ox < 0) ox = 0; oy += rc.top; if (oy < 0) oy = 0; QDesktopWidget *desktop = QApplication::desktop(); QRect rectDesk = desktop->availableGeometry(window(wid)); /* do some corrections to fit into screen */ int sizex = rc.right - rc.left; int sizey = rc.bottom - rc.top; int screenWidth = rectDesk.width(); int screenHeight = rectDesk.height(); if (sizex > screenWidth) ox = 0; /* the best we can do */ else if (ox + sizex > screenWidth) ox = screenWidth - sizex; if (oy + sizey > screenHeight) oy = screenHeight - sizey; Q_ASSERT(wid); window(wid)->move(ox, oy); window(wid)->resize(sizex, sizey); } PRectangle Window::GetClientPosition() { // The client position is the window position return GetPosition(); } void Window::Show(bool show) { if (wid) window(wid)->setVisible(show); } void Window::InvalidateAll() { if (wid) window(wid)->update(); } void Window::InvalidateRectangle(PRectangle rc) { if (wid) window(wid)->update(QRectFromPRect(rc)); } void Window::SetFont(Font &font) { if (wid) window(wid)->setFont(*FontPointer(font)); } void Window::SetCursor(Cursor curs) { if (wid) { Qt::CursorShape shape; switch (curs) { case cursorText: shape = Qt::IBeamCursor; break; case cursorArrow: shape = Qt::ArrowCursor; break; case cursorUp: shape = Qt::UpArrowCursor; break; case cursorWait: shape = Qt::WaitCursor; break; case cursorHoriz: shape = Qt::SizeHorCursor; break; case cursorVert: shape = Qt::SizeVerCursor; break; case cursorHand: shape = Qt::PointingHandCursor; break; default: shape = Qt::ArrowCursor; break; } QCursor cursor = QCursor(shape); if (curs != cursorLast) { window(wid)->setCursor(cursor); cursorLast = curs; } } } void Window::SetTitle(const char *s) { if (wid) window(wid)->setWindowTitle(s); } /* Returns rectangle of monitor pt is on, both rect and pt are in Window's window coordinates */ PRectangle Window::GetMonitorRect(Point pt) { QPoint originGlobal = window(wid)->mapToGlobal(QPoint(0, 0)); QPoint posGlobal = window(wid)->mapToGlobal(QPoint(pt.x, pt.y)); QDesktopWidget *desktop = QApplication::desktop(); QRect rectScreen = desktop->availableGeometry(posGlobal); rectScreen.moveLeft(-originGlobal.x()); rectScreen.moveTop(-originGlobal.y()); return PRectangle(rectScreen.left(), rectScreen.top(), rectScreen.right(), rectScreen.bottom()); } //---------------------------------------------------------------------- class ListBoxImpl : public ListBox { public: ListBoxImpl(); ~ListBoxImpl(); virtual void SetFont(Font &font); virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight, bool unicodeMode, int technology); virtual void SetAverageCharWidth(int width); virtual void SetVisibleRows(int rows); virtual int GetVisibleRows() const; virtual PRectangle GetDesiredRect(); virtual int CaretFromEdge(); virtual void Clear(); virtual void Append(char *s, int type = -1); virtual int Length(); virtual void Select(int n); virtual int GetSelection(); virtual int Find(const char *prefix); virtual void GetValue(int n, char *value, int len); virtual void RegisterImage(int type, const char *xpmData); virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage); virtual void ClearRegisteredImages(); virtual void SetDoubleClickAction(CallBackAction action, void *data); virtual void SetList(const char *list, char separator, char typesep); private: bool unicodeMode; int visibleRows; QMap<int,QPixmap> images; }; class ListWidget : public QListWidget { public: ListWidget(QWidget *parent); virtual ~ListWidget(); void setDoubleClickAction(CallBackAction action, void *data); protected: virtual void mouseDoubleClickEvent(QMouseEvent *event); virtual QStyleOptionViewItem viewOptions() const; private: CallBackAction doubleClickAction; void *doubleClickActionData; }; ListBoxImpl::ListBoxImpl() : unicodeMode(false), visibleRows(5) {} ListBoxImpl::~ListBoxImpl() {} void ListBoxImpl::Create(Window &parent, int /*ctrlID*/, Point location, int /*lineHeight*/, bool unicodeMode_, int) { unicodeMode = unicodeMode_; QWidget *qparent = static_cast<QWidget *>(parent.GetID()); ListWidget *list = new ListWidget(qparent); #if defined(Q_OS_WIN) // On Windows, Qt::ToolTip causes a crash when the list is clicked on // so Qt::Tool is used. list->setParent(0, Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); #else // On OS X, Qt::Tool takes focus so main window loses focus so // keyboard stops working. Qt::ToolTip works but its only really // documented for tooltips. // On Linux / X this setting allows clicking on list items. list->setParent(0, Qt::ToolTip | Qt::FramelessWindowHint); #endif list->setAttribute(Qt::WA_ShowWithoutActivating); list->setFocusPolicy(Qt::NoFocus); list->setUniformItemSizes(true); list->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); list->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); list->move(location.x, location.y); wid = list; } void ListBoxImpl::SetFont(Font &font) { ListWidget *list = static_cast<ListWidget *>(wid); list->setFont(*FontPointer(font)); } void ListBoxImpl::SetAverageCharWidth(int /*width*/) {} void ListBoxImpl::SetVisibleRows(int rows) { visibleRows = rows; } int ListBoxImpl::GetVisibleRows() const { return visibleRows; } PRectangle ListBoxImpl::GetDesiredRect() { ListWidget *list = static_cast<ListWidget *>(wid); int rows = Length(); if (rows == 0 || rows > visibleRows) { rows = visibleRows; } int rowHeight = list->sizeHintForRow(0); int height = (rows * rowHeight) + (2 * list->frameWidth()); QStyle *style = QApplication::style(); int width = list->sizeHintForColumn(0) + (2 * list->frameWidth()); if (Length() > rows) { width += style->pixelMetric(QStyle::PM_ScrollBarExtent); } return PRectangle(0, 0, width, height); } int ListBoxImpl::CaretFromEdge() { ListWidget *list = static_cast<ListWidget *>(wid); int maxIconWidth = 0; foreach (QPixmap im, images) { if (maxIconWidth < im.width()) maxIconWidth = im.width(); } // The '7' is from trial and error on Windows - there may be // a better programmatic way to find any padding factors. return maxIconWidth + (2 * list->frameWidth()) + 7; } void ListBoxImpl::Clear() { ListWidget *list = static_cast<ListWidget *>(wid); list->clear(); } void ListBoxImpl::Append(char *s, int type) { ListWidget *list = static_cast<ListWidget *>(wid); QString str = unicodeMode ? QString::fromUtf8(s) : QString::fromLocal8Bit(s); QIcon icon; if (type >= 0) { Q_ASSERT(images.contains(type)); icon = images.value(type); } new QListWidgetItem(icon, str, list); } int ListBoxImpl::Length() { ListWidget *list = static_cast<ListWidget *>(wid); return list->count(); } void ListBoxImpl::Select(int n) { ListWidget *list = static_cast<ListWidget *>(wid); list->setCurrentRow(n); } int ListBoxImpl::GetSelection() { ListWidget *list = static_cast<ListWidget *>(wid); return list->currentRow(); } int ListBoxImpl::Find(const char *prefix) { ListWidget *list = static_cast<ListWidget *>(wid); QString sPrefix = unicodeMode ? QString::fromUtf8(prefix) : QString::fromLocal8Bit(prefix); QList<QListWidgetItem *> ms = list->findItems(sPrefix, Qt::MatchStartsWith); int result = -1; if (!ms.isEmpty()) { result = list->row(ms.first()); } return result; } void ListBoxImpl::GetValue(int n, char *value, int len) { ListWidget *list = static_cast<ListWidget *>(wid); QListWidgetItem *item = list->item(n); QString str = item->data(Qt::DisplayRole).toString(); QByteArray bytes = unicodeMode ? str.toUtf8() : str.toLocal8Bit(); strncpy(value, bytes.constData(), len); value[len-1] = '\0'; } void ListBoxImpl::RegisterImage(int type, const char *xpmData) { images[type] = QPixmap(reinterpret_cast<const char * const *>(xpmData)); } void ListBoxImpl::RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) { std::vector<unsigned char> imageBytes = ImageByteSwapped(width, height, pixelsImage); QImage image(&imageBytes[0], width, height, QImage::Format_ARGB32); images[type] = QPixmap::fromImage(image); } void ListBoxImpl::ClearRegisteredImages() { images.clear(); } void ListBoxImpl::SetDoubleClickAction(CallBackAction action, void *data) { ListWidget *list = static_cast<ListWidget *>(wid); list->setDoubleClickAction(action, data); } void ListBoxImpl::SetList(const char *list, char separator, char typesep) { // This method is *not* platform dependent. // It is borrowed from the GTK implementation. Clear(); int count = strlen(list) + 1; char *words = new char[count]; if (words) { memcpy(words, list, count); char *startword = words; char *numword = NULL; int i = 0; for (; words[i]; i++) { if (words[i] == separator) { words[i] = '\0'; if (numword) *numword = '\0'; Append(startword, numword?atoi(numword + 1):-1); startword = words + i + 1; numword = NULL; } else if (words[i] == typesep) { numword = words + i; } } if (startword) { if (numword) *numword = '\0'; Append(startword, numword?atoi(numword + 1):-1); } delete []words; } } ListBox::ListBox() {} ListBox::~ListBox() {} ListBox *ListBox::Allocate() { return new ListBoxImpl(); } ListWidget::ListWidget(QWidget *parent) : QListWidget(parent), doubleClickAction(0), doubleClickActionData(0) {} ListWidget::~ListWidget() {} void ListWidget::setDoubleClickAction(CallBackAction action, void *data) { doubleClickAction = action; doubleClickActionData = data; } void ListWidget::mouseDoubleClickEvent(QMouseEvent * /* event */) { if (doubleClickAction != 0) { doubleClickAction(doubleClickActionData); } } QStyleOptionViewItem ListWidget::viewOptions() const { QStyleOptionViewItem result = QListWidget::viewOptions(); result.state |= QStyle::State_Active; return result; } //---------------------------------------------------------------------- Menu::Menu() : mid(0) {} void Menu::CreatePopUp() { Destroy(); mid = new QMenu(); } void Menu::Destroy() { if (mid) { QMenu *menu = static_cast<QMenu *>(mid); delete menu; } mid = 0; } void Menu::Show(Point pt, Window & /*w*/) { QMenu *menu = static_cast<QMenu *>(mid); menu->exec(QPoint(pt.x, pt.y)); Destroy(); } //---------------------------------------------------------------------- class DynamicLibraryImpl : public DynamicLibrary { protected: QLibrary *lib; public: DynamicLibraryImpl(const char *modulePath) { QString path = QString::fromUtf8(modulePath); lib = new QLibrary(path); } virtual ~DynamicLibraryImpl() { if (lib) lib->unload(); lib = 0; } virtual Function FindFunction(const char *name) { if (lib) { void *fnAddress = lib->resolve(name); return static_cast<Function>(fnAddress); } return NULL; } virtual bool IsValid() { return lib != NULL; } }; DynamicLibrary *DynamicLibrary::Load(const char *modulePath) { return static_cast<DynamicLibrary *>(new DynamicLibraryImpl(modulePath)); } ColourDesired Platform::Chrome() { QColor c(Qt::gray); return ColourDesired(c.red(), c.green(), c.blue()); } ColourDesired Platform::ChromeHighlight() { QColor c(Qt::lightGray); return ColourDesired(c.red(), c.green(), c.blue()); } const char *Platform::DefaultFont() { static char fontNameDefault[200] = ""; if (!fontNameDefault[0]) { QFont font = QApplication::font(); strcpy(fontNameDefault, font.family().toAscii()); } return fontNameDefault; } int Platform::DefaultFontSize() { QFont font = QApplication::font(); return font.pointSize(); } unsigned int Platform::DoubleClickTime() { return QApplication::doubleClickInterval(); } bool Platform::MouseButtonBounce() { return false; } bool Platform::IsKeyDown(int /*key*/) { return false; } long Platform::SendScintilla(WindowID /*w*/, unsigned int /*msg*/, unsigned long /*wParam*/, long /*lParam*/) { return 0; } long Platform::SendScintillaPointer(WindowID /*w*/, unsigned int /*msg*/, unsigned long /*wParam*/, void * /*lParam*/) { return 0; } int Platform::Minimum(int a, int b) { return qMin(a, b); } int Platform::Maximum(int a, int b) { return qMax(a, b); } int Platform::Clamp(int val, int minVal, int maxVal) { return qBound(minVal, val, maxVal); } void Platform::DebugDisplay(const char *s) { qWarning("Scintilla: %s", s); } void Platform::DebugPrintf(const char *format, ...) { char buffer[2000]; va_list pArguments; va_start(pArguments, format); vsprintf(buffer, format, pArguments); va_end(pArguments); Platform::DebugDisplay(buffer); } bool Platform::ShowAssertionPopUps(bool /*assertionPopUps*/) { return false; } void Platform::Assert(const char *c, const char *file, int line) { char buffer[2000]; sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line); if (Platform::ShowAssertionPopUps(false)) { QMessageBox mb("Assertion Failure", buffer, QMessageBox::NoIcon, QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton); mb.exec(); } else { strcat(buffer, "\n"); Platform::DebugDisplay(buffer); } } bool Platform::IsDBCSLeadByte(int codePage, char ch) { // Byte ranges found in Wikipedia articles with relevant search strings in each case unsigned char uch = static_cast<unsigned char>(ch); switch (codePage) { case 932: // Shift_jis return ((uch >= 0x81) && (uch <= 0x9F)) || ((uch >= 0xE0) && (uch <= 0xEF)); case 936: // GBK return (uch >= 0x81) && (uch <= 0xFE); case 949: // Korean Wansung KS C-5601-1987 return (uch >= 0x81) && (uch <= 0xFE); case 950: // Big5 return (uch >= 0x81) && (uch <= 0xFE); case 1361: // Korean Johab KS C-5601-1992 return ((uch >= 0x84) && (uch <= 0xD3)) || ((uch >= 0xD8) && (uch <= 0xDE)) || ((uch >= 0xE0) && (uch <= 0xF9)); } return false; } int Platform::DBCSCharLength(int codePage, const char *s) { if (codePage == 932 || codePage == 936 || codePage == 949 || codePage == 950 || codePage == 1361) { return IsDBCSLeadByte(codePage, s[0]) ? 2 : 1; } else { return 1; } } int Platform::DBCSCharMaxLength() { return 2; } //---------------------------------------------------------------------- static QTime timer; ElapsedTime::ElapsedTime() { timer.start(); } double ElapsedTime::Duration(bool reset) { double result = timer.elapsed(); if (reset) { timer.restart(); } result /= 1000.0; return result; } #ifdef SCI_NAMESPACE } #endif |
Added qt/ScintillaEditBase/PlatQt.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
// // Copyright (c) 1990-2011, Scientific Toolworks, Inc. // // The License.txt file describes the conditions under which this software may be distributed. // // Author: Jason Haslam // // Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware // Scintilla platform layer for Qt #ifndef PLATQT_H #define PLATQT_H #include "Platform.h" #include <QPaintDevice> #include <QPainter> #include <QHash> #ifdef SCI_NAMESPACE namespace Scintilla { #endif const char *CharacterSetID(int characterSet); inline QColor QColorFromCA(ColourDesired ca) { long c = ca.AsLong(); return QColor(c & 0xff, (c >> 8) & 0xff, (c >> 16) & 0xff); } inline QRect QRectFromPRect(PRectangle pr) { return QRect(pr.left, pr.top, pr.Width(), pr.Height()); } inline PRectangle PRectFromQRect(QRect qr) { return PRectangle(qr.x(), qr.y(), qr.x() + qr.width(), qr.y() + qr.height()); } inline Point PointFromQPoint(QPoint qp) { return Point(qp.x(), qp.y()); } class SurfaceImpl : public Surface { private: QPaintDevice *device; QPainter *painter; bool deviceOwned; bool painterOwned; float x, y; bool unicodeMode; int codePage; const char *codecName; QTextCodec *codec; public: SurfaceImpl(); virtual ~SurfaceImpl(); virtual void Init(WindowID wid); virtual void Init(SurfaceID sid, WindowID wid); virtual void InitPixMap(int width, int height, Surface *surface, WindowID wid); virtual void Release(); virtual bool Initialised(); virtual void PenColour(ColourDesired fore); virtual int LogPixelsY(); virtual int DeviceHeightFont(int points); virtual void MoveTo(int x, int y); virtual void LineTo(int x, int y); virtual void Polygon(Point *pts, int npts, ColourDesired fore, ColourDesired back); virtual void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back); virtual void FillRectangle(PRectangle rc, ColourDesired back); virtual void FillRectangle(PRectangle rc, Surface &surfacePattern); virtual void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back); virtual void AlphaRectangle(PRectangle rc, int corner, ColourDesired fill, int alphaFill, ColourDesired outline, int alphaOutline, int flags); virtual void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage); virtual void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back); virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource); virtual void DrawTextNoClip(PRectangle rc, Font &font, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back); virtual void DrawTextClipped(PRectangle rc, Font &font, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back); virtual void DrawTextTransparent(PRectangle rc, Font &font, XYPOSITION ybase, const char *s, int len, ColourDesired fore); virtual void MeasureWidths(Font &font, const char *s, int len, XYPOSITION *positions); virtual XYPOSITION WidthText(Font &font, const char *s, int len); virtual XYPOSITION WidthChar(Font &font, char ch); virtual XYPOSITION Ascent(Font &font); virtual XYPOSITION Descent(Font &font); virtual XYPOSITION InternalLeading(Font &font); virtual XYPOSITION ExternalLeading(Font &font); virtual XYPOSITION Height(Font &font); virtual XYPOSITION AverageCharWidth(Font &font); virtual void SetClip(PRectangle rc); virtual void FlushCachedState(); virtual void SetUnicodeMode(bool unicodeMode); virtual void SetDBCSMode(int codePage); void BrushColour(ColourDesired back); void SetCodec(Font &font); void SetFont(Font &font); QPaintDevice *GetPaintDevice(); void SetPainter(QPainter *painter); QPainter *GetPainter(); }; #ifdef SCI_NAMESPACE } #endif #endif |
Added qt/ScintillaEditBase/ScintillaEditBase.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 |
// // Copyright (c) 1990-2011, Scientific Toolworks, Inc. // // The License.txt file describes the conditions under which this software may be distributed. // // Author: Jason Haslam // // Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware // ScintillaEditBase.cpp - Qt widget that wraps ScintillaQt and provides events and scrolling #include "ScintillaEditBase.h" #include "ScintillaQt.h" #include "PlatQt.h" #include <QApplication> #include <QInputContext> #include <QPainter> #include <QScrollBar> #include <QTextFormat> #include <QVarLengthArray> #define INDIC_INPUTMETHOD 24 #ifdef SCI_NAMESPACE using namespace Scintilla; #endif ScintillaEditBase::ScintillaEditBase(QWidget *parent) : QAbstractScrollArea(parent), sqt(0), preeditPos(-1), wheelDelta(0) { sqt = new ScintillaQt(this); time.start(); // Set Qt defaults. setAcceptDrops(true); setMouseTracking(true); setAutoFillBackground(false); setFrameStyle(QFrame::NoFrame); setFocusPolicy(Qt::StrongFocus); setAttribute(Qt::WA_StaticContents); setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_KeyCompression); setAttribute(Qt::WA_InputMethodEnabled); connect(sqt, SIGNAL(notifyParent(SCNotification)), this, SLOT(notifyParent(SCNotification))); // Connect scroll bars. connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(scrollVertical(int))); connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(scrollHorizontal(int))); // Connect pass-through signals. connect(sqt, SIGNAL(horizontalRangeChanged(int,int)), this, SIGNAL(horizontalRangeChanged(int,int))); connect(sqt, SIGNAL(verticalRangeChanged(int,int)), this, SIGNAL(verticalRangeChanged(int,int))); connect(sqt, SIGNAL(horizontalScrolled(int)), this, SIGNAL(horizontalScrolled(int))); connect(sqt, SIGNAL(verticalScrolled(int)), this, SIGNAL(verticalScrolled(int))); connect(sqt, SIGNAL(notifyChange()), this, SIGNAL(notifyChange())); connect(sqt, SIGNAL(command(uptr_t, sptr_t)), this, SLOT(event_command(uptr_t, sptr_t))); connect(sqt, SIGNAL(aboutToCopy(QMimeData *)), this, SIGNAL(aboutToCopy(QMimeData *))); } ScintillaEditBase::~ScintillaEditBase() {} sptr_t ScintillaEditBase::send( unsigned int iMessage, uptr_t wParam, sptr_t lParam) const { return sqt->WndProc(iMessage, wParam, lParam); } sptr_t ScintillaEditBase::sends( unsigned int iMessage, uptr_t wParam, const char *s) const { return sqt->WndProc(iMessage, wParam, (sptr_t)s); } void ScintillaEditBase::scrollHorizontal(int value) { sqt->HorizontalScrollTo(value); } void ScintillaEditBase::scrollVertical(int value) { sqt->ScrollTo(value); } bool ScintillaEditBase::event(QEvent *event) { bool result = false; if (event->type() == QEvent::KeyPress) { // Circumvent the tab focus convention. keyPressEvent(static_cast<QKeyEvent *>(event)); result = event->isAccepted(); } else { result = QAbstractScrollArea::event(event); } return result; } void ScintillaEditBase::paintEvent(QPaintEvent *event) { sqt->PartialPaint(PRectFromQRect(event->rect())); } void ScintillaEditBase::wheelEvent(QWheelEvent *event) { if (event->orientation() == Qt::Horizontal) { if (horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOff) event->ignore(); else QAbstractScrollArea::wheelEvent(event); } else { if (event->modifiers() & Qt::ControlModifier) { // Zoom! We play with the font sizes in the styles. // Number of steps/line is ignored, we just care if sizing up or down if (event->delta() > 0) { sqt->KeyCommand(SCI_ZOOMIN); } else { sqt->KeyCommand(SCI_ZOOMOUT); } } else { // Ignore wheel events when the scroll bars are disabled. if (verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOff) { event->ignore(); } else { // Scroll QAbstractScrollArea::wheelEvent(event); } } } } void ScintillaEditBase::focusInEvent(QFocusEvent *event) { sqt->SetFocusState(true); emit updateUi(); QAbstractScrollArea::focusInEvent(event); } void ScintillaEditBase::focusOutEvent(QFocusEvent *event) { sqt->SetFocusState(false); QAbstractScrollArea::focusOutEvent(event); } void ScintillaEditBase::resizeEvent(QResizeEvent *) { sqt->ChangeSize(); emit resized(); } void ScintillaEditBase::keyPressEvent(QKeyEvent *event) { // All keystrokes containing the meta modifier are // assumed to be shortcuts not handled by scintilla. if (event->modifiers() & Qt::MetaModifier) { QAbstractScrollArea::keyPressEvent(event); emit keyPressed(event); return; } int key = 0; switch (event->key()) { case Qt::Key_Down: key = SCK_DOWN; break; case Qt::Key_Up: key = SCK_UP; break; case Qt::Key_Left: key = SCK_LEFT; break; case Qt::Key_Right: key = SCK_RIGHT; break; case Qt::Key_Home: key = SCK_HOME; break; case Qt::Key_End: key = SCK_END; break; case Qt::Key_PageUp: key = SCK_PRIOR; break; case Qt::Key_PageDown: key = SCK_NEXT; break; case Qt::Key_Delete: key = SCK_DELETE; break; case Qt::Key_Insert: key = SCK_INSERT; break; case Qt::Key_Escape: key = SCK_ESCAPE; break; case Qt::Key_Backspace: key = SCK_BACK; break; case Qt::Key_Plus: key = SCK_ADD; break; case Qt::Key_Minus: key = SCK_SUBTRACT; break; case Qt::Key_Backtab: // fall through case Qt::Key_Tab: key = SCK_TAB; break; case Qt::Key_Enter: // fall through case Qt::Key_Return: key = SCK_RETURN; break; case Qt::Key_Control: key = 0; break; case Qt::Key_Alt: key = 0; break; case Qt::Key_Shift: key = 0; break; case Qt::Key_Meta: key = 0; break; default: key = event->key(); break; } bool shift = event->modifiers() & Qt::ShiftModifier; bool ctrl = event->modifiers() & Qt::ControlModifier; bool alt = event->modifiers() & Qt::AltModifier; bool consumed = false; bool added = sqt->KeyDown(key, shift, ctrl, alt, &consumed) != 0; if (!consumed) consumed = added; if (!consumed) { // Don't insert text if the control key was pressed unless // it was pressed in conjunction with alt for AltGr emulation. bool input = (!ctrl || alt); // Additionally, on non-mac platforms, don't insert text // if the alt key was pressed unless control is also present. // On mac alt can be used to insert special characters. #ifndef Q_WS_MAC input &= (!alt || ctrl); #endif QString text = event->text(); if (input && !text.isEmpty() && text[0].isPrint()) { QByteArray utext = sqt->BytesForDocument(text); sqt->AddCharUTF(utext.data(), utext.size()); } else { event->ignore(); } } emit keyPressed(event); } static int modifierTranslated(int sciModifier) { switch (sciModifier) { case SCMOD_SHIFT: return Qt::ShiftModifier; case SCMOD_CTRL: return Qt::ControlModifier; case SCMOD_ALT: return Qt::AltModifier; case SCMOD_SUPER: return Qt::MetaModifier; default: return 0; } } void ScintillaEditBase::mousePressEvent(QMouseEvent *event) { Point pos = PointFromQPoint(event->pos()); emit buttonPressed(event); if (event->button() == Qt::MidButton && QApplication::clipboard()->supportsSelection()) { SelectionPosition selPos = sqt->SPositionFromLocation( pos, false, false, sqt->UserVirtualSpace()); sqt->sel.Clear(); sqt->SetSelection(selPos, selPos); sqt->PasteFromMode(QClipboard::Selection); return; } bool button = event->button() == Qt::LeftButton; if (button) { bool shift = event->modifiers() & Qt::ShiftModifier; bool ctrl = event->modifiers() & Qt::ControlModifier; #ifdef Q_WS_X11 // On X allow choice of rectangular modifier since most window // managers grab alt + click for moving windows. bool alt = event->modifiers() & modifierTranslated(sqt->rectangularSelectionModifier); #else bool alt = event->modifiers() & Qt::AltModifier; #endif sqt->ButtonDown(pos, time.elapsed(), shift, ctrl, alt); } } void ScintillaEditBase::mouseReleaseEvent(QMouseEvent *event) { Point point = PointFromQPoint(event->pos()); bool ctrl = event->modifiers() & Qt::ControlModifier; if (event->button() == Qt::LeftButton) sqt->ButtonUp(point, time.elapsed(), ctrl); int pos = send(SCI_POSITIONFROMPOINT, point.x, point.y); int line = send(SCI_LINEFROMPOSITION, pos); int modifiers = event->modifiers(); emit textAreaClicked(line, modifiers); emit buttonReleased(event); } void ScintillaEditBase::mouseDoubleClickEvent(QMouseEvent *event) { // Scintilla does its own double-click detection. mousePressEvent(event); } void ScintillaEditBase::mouseMoveEvent(QMouseEvent *event) { Point pos = PointFromQPoint(event->pos()); sqt->ButtonMove(pos); } void ScintillaEditBase::contextMenuEvent(QContextMenuEvent *event) { Point pos = PointFromQPoint(event->globalPos()); Point pt = PointFromQPoint(event->pos()); if (!sqt->PointInSelection(pt)) sqt->SetEmptySelection(sqt->PositionFromLocation(pt)); sqt->ContextMenu(pos); } void ScintillaEditBase::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasText()) { event->acceptProposedAction(); Point point = PointFromQPoint(event->pos()); sqt->DragEnter(point); } else { event->ignore(); } } void ScintillaEditBase::dragLeaveEvent(QDragLeaveEvent * /* event */) { sqt->DragLeave(); } void ScintillaEditBase::dragMoveEvent(QDragMoveEvent *event) { if (event->mimeData()->hasText()) { event->acceptProposedAction(); Point point = PointFromQPoint(event->pos()); sqt->DragMove(point); } else { event->ignore(); } } void ScintillaEditBase::dropEvent(QDropEvent *event) { if (event->mimeData()->hasText()) { event->acceptProposedAction(); Point point = PointFromQPoint(event->pos()); bool move = (event->source() == this && event->proposedAction() == Qt::MoveAction); sqt->Drop(point, event->mimeData(), move); } else { event->ignore(); } } void ScintillaEditBase::inputMethodEvent(QInputMethodEvent *event) { // Clear the current selection. sqt->ClearSelection(); if (preeditPos >= 0) sqt->SetSelection(preeditPos, preeditPos); // Insert the commit string. if (!event->commitString().isEmpty() || event->replacementLength()) { // Select the text to be removed. int commitPos = send(SCI_GETCURRENTPOS); int start = commitPos + event->replacementStart(); int end = start + event->replacementLength(); sqt->SetSelection(start, end); // Replace the selection with the commit string. QByteArray commitBytes = sqt->BytesForDocument(event->commitString()); char *commitData = commitBytes.data(); sqt->AddCharUTF(commitData, strlen(commitData)); } // Select the previous preedit string. int pos = send(SCI_GETCURRENTPOS); int length = sqt->BytesForDocument(preeditString).length(); sqt->SetSelection(pos, pos + length); // Replace the selection with the new preedit string. QByteArray bytes = sqt->BytesForDocument(event->preeditString()); char *data = bytes.data(); bool recording = sqt->recordingMacro; sqt->recordingMacro = false; send(SCI_SETUNDOCOLLECTION, false); sqt->AddCharUTF(data, strlen(data)); send(SCI_SETUNDOCOLLECTION, true); sqt->recordingMacro = recording; sqt->SetSelection(pos, pos); // Store the state of the current preedit string. preeditString = event->preeditString(); preeditPos = !preeditString.isEmpty() ? send(SCI_GETCURRENTPOS) : -1; if (!preeditString.isEmpty()) { // Apply attributes to the preedit string. int indicNum = 0; sqt->ShowCaretAtCurrentPosition(); foreach (QInputMethodEvent::Attribute a, event->attributes()) { QString prefix = preeditString.left(a.start); QByteArray prefixBytes = sqt->BytesForDocument(prefix); int prefixLength = prefixBytes.length(); int caretPos = preeditPos + prefixLength; if (a.type == QInputMethodEvent::Cursor) { sqt->SetSelection(caretPos, caretPos); if (!a.length) sqt->DropCaret(); } else if (a.type == QInputMethodEvent::TextFormat) { Q_ASSERT(a.value.canConvert(QVariant::TextFormat)); QTextFormat format = a.value.value<QTextFormat>(); Q_ASSERT(format.isCharFormat()); QTextCharFormat charFormat = format.toCharFormat(); QString sub = preeditString.mid(a.start, a.length); QByteArray subBytes = sqt->BytesForDocument(sub); int subLength = subBytes.length(); if (charFormat.underlineStyle() != QTextCharFormat::NoUnderline) { // Set temporary indicator for underline style. QColor uc = charFormat.underlineColor(); int style = INDIC_PLAIN; if (charFormat.underlineStyle() == QTextCharFormat::DashUnderline) style = INDIC_DASH; send(SCI_INDICSETSTYLE, INDIC_INPUTMETHOD + indicNum, style); send(SCI_INDICSETFORE, INDIC_INPUTMETHOD + indicNum, uc.rgb()); send(SCI_SETINDICATORCURRENT, INDIC_INPUTMETHOD + indicNum); send(SCI_INDICATORFILLRANGE, caretPos, subLength); indicNum++; } } } } } QVariant ScintillaEditBase::inputMethodQuery(Qt::InputMethodQuery query) const { int pos = send(SCI_GETCURRENTPOS); int line = send(SCI_LINEFROMPOSITION, pos); switch (query) { case Qt::ImMicroFocus: { int startPos = (preeditPos >= 0) ? preeditPos : pos; Point pt = sqt->LocationFromPosition(startPos); int width = send(SCI_GETCARETWIDTH); int height = send(SCI_TEXTHEIGHT, line); return QRect(pt.x, pt.y, width, height); } case Qt::ImFont: { char fontName[64]; int style = send(SCI_GETSTYLEAT, pos); int len = send(SCI_STYLEGETFONT, style, (sptr_t)fontName); int size = send(SCI_STYLEGETSIZE, style); bool italic = send(SCI_STYLEGETITALIC, style); int weight = send(SCI_STYLEGETBOLD, style) ? QFont::Bold : -1; return QFont(QString::fromUtf8(fontName, len), size, weight, italic); } case Qt::ImCursorPosition: { int paraStart = sqt->pdoc->ParaUp(pos); return pos - paraStart; } case Qt::ImSurroundingText: { int paraStart = sqt->pdoc->ParaUp(pos); int paraEnd = sqt->pdoc->ParaDown(pos); QVarLengthArray<char,1024> buffer(paraEnd - paraStart + 1); Sci_CharacterRange charRange; charRange.cpMin = paraStart; charRange.cpMax = paraEnd; Sci_TextRange textRange; textRange.chrg = charRange; textRange.lpstrText = buffer.data(); send(SCI_GETTEXTRANGE, 0, (sptr_t)&textRange); return sqt->StringFromDocument(buffer.constData()); } case Qt::ImCurrentSelection: { QVarLengthArray<char,1024> buffer(send(SCI_GETSELTEXT)); send(SCI_GETSELTEXT, 0, (sptr_t)buffer.data()); return sqt->StringFromDocument(buffer.constData()); } default: return QVariant(); } } void ScintillaEditBase::notifyParent(SCNotification scn) { emit notify(&scn); switch (scn.nmhdr.code) { case SCN_STYLENEEDED: emit styleNeeded(scn.position); break; case SCN_CHARADDED: emit charAdded(scn.ch); break; case SCN_SAVEPOINTREACHED: emit savePointChanged(false); break; case SCN_SAVEPOINTLEFT: emit savePointChanged(true); break; case SCN_MODIFYATTEMPTRO: emit modifyAttemptReadOnly(); break; case SCN_KEY: emit key(scn.ch); break; case SCN_DOUBLECLICK: emit doubleClick(scn.position, scn.line); break; case SCN_UPDATEUI: emit updateUi(); break; case SCN_MODIFIED: { bool added = scn.modificationType & SC_MOD_INSERTTEXT; bool deleted = scn.modificationType & SC_MOD_DELETETEXT; int length = send(SCI_GETTEXTLENGTH); bool firstLineAdded = (added && length == 1) || (deleted && length == 0); if (scn.linesAdded != 0) { emit linesAdded(scn.linesAdded); } else if (firstLineAdded) { emit linesAdded(added ? 1 : -1); } const QByteArray bytes = QByteArray::fromRawData(scn.text, scn.length); emit modified(scn.modificationType, scn.position, scn.length, scn.linesAdded, bytes, scn.line, scn.foldLevelNow, scn.foldLevelPrev); break; } case SCN_MACRORECORD: emit macroRecord(scn.message, scn.wParam, scn.lParam); break; case SCN_MARGINCLICK: emit marginClicked(scn.position, scn.modifiers, scn.margin); break; case SCN_NEEDSHOWN: emit needShown(scn.position, scn.length); break; case SCN_PAINTED: emit painted(); break; case SCN_USERLISTSELECTION: emit userListSelection(); break; case SCN_URIDROPPED: emit uriDropped(); break; case SCN_DWELLSTART: emit dwellStart(scn.x, scn.y); break; case SCN_DWELLEND: emit dwellEnd(scn.x, scn.y); break; case SCN_ZOOM: emit zoom(send(SCI_GETZOOM)); break; case SCN_HOTSPOTCLICK: emit hotSpotClick(scn.position, scn.modifiers); break; case SCN_HOTSPOTDOUBLECLICK: emit hotSpotDoubleClick(scn.position, scn.modifiers); break; case SCN_CALLTIPCLICK: emit callTipClick(); break; case SCN_AUTOCSELECTION: emit autoCompleteSelection(scn.lParam, QString::fromUtf8(scn.text)); break; case SCN_AUTOCCANCELLED: emit autoCompleteCancelled(); break; default: return; } } void ScintillaEditBase::event_command(uptr_t wParam, sptr_t lParam) { emit command(wParam, lParam); } |
Added qt/ScintillaEditBase/ScintillaEditBase.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
// // Copyright (c) 1990-2011, Scientific Toolworks, Inc. // // The License.txt file describes the conditions under which this software may be distributed. // // Author: Jason Haslam // // Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware // ScintillaWidget.h - Qt widget that wraps ScintillaQt and provides events and scrolling #ifndef SCINTILLAEDITBASE_H #define SCINTILLAEDITBASE_H #include "Platform.h" #include "Scintilla.h" #include <QAbstractScrollArea> #include <QMimeData> #include <QTime> #ifdef SCI_NAMESPACE namespace Scintilla { #endif class ScintillaQt; class SurfaceImpl; struct SCNotification; #ifdef WIN32 #ifdef MAKING_LIBRARY #define EXPORT_IMPORT_API __declspec(dllexport) #else // Defining dllimport upsets moc #define EXPORT_IMPORT_API __declspec(dllimport) //#define EXPORT_IMPORT_API #endif #else #define EXPORT_IMPORT_API #endif class EXPORT_IMPORT_API ScintillaEditBase : public QAbstractScrollArea { Q_OBJECT public: ScintillaEditBase(QWidget *parent = 0); virtual ~ScintillaEditBase(); virtual sptr_t send( unsigned int iMessage, uptr_t wParam = 0, sptr_t lParam = 0) const; virtual sptr_t sends( unsigned int iMessage, uptr_t wParam = 0, const char *s = 0) const; public slots: // Scroll events coming from GUI to be sent to Scintilla. void scrollHorizontal(int value); void scrollVertical(int value); // Emit Scintilla notifications as signals. void notifyParent(SCNotification scn); void event_command(uptr_t wParam, sptr_t lParam); signals: void horizontalScrolled(int value); void verticalScrolled(int value); void horizontalRangeChanged(int max, int page); void verticalRangeChanged(int max, int page); void notifyChange(); void linesAdded(int linesAdded); // Clients can use this hook to add additional // formats (e.g. rich text) to the MIME data. void aboutToCopy(QMimeData *data); // Scintilla Notifications void styleNeeded(int position); void charAdded(int ch); void savePointChanged(bool dirty); void modifyAttemptReadOnly(); void key(int key); void doubleClick(int position, int line); void updateUi(); void modified(int type, int position, int length, int linesAdded, const QByteArray &text, int line, int foldNow, int foldPrev); void macroRecord(int message, uptr_t wParam, sptr_t lParam); void marginClicked(int position, int modifiers, int margin); void textAreaClicked(int line, int modifiers); void needShown(int position, int length); void painted(); void userListSelection(); // Wants some args. void uriDropped(); // Wants some args. void dwellStart(int x, int y); void dwellEnd(int x, int y); void zoom(int zoom); void hotSpotClick(int position, int modifiers); void hotSpotDoubleClick(int position, int modifiers); void callTipClick(); void autoCompleteSelection(int position, const QString &text); void autoCompleteCancelled(); // Base notifications for compatibility with other Scintilla implementations void notify(SCNotification *pscn); void command(uptr_t wParam, sptr_t lParam); // GUI event notifications needed under Qt void buttonPressed(QMouseEvent *event); void buttonReleased(QMouseEvent *event); void keyPressed(QKeyEvent *event); void resized(); protected: virtual bool event(QEvent *event); virtual void paintEvent(QPaintEvent *event); virtual void wheelEvent(QWheelEvent *event); virtual void focusInEvent(QFocusEvent *event); virtual void focusOutEvent(QFocusEvent *event); virtual void resizeEvent(QResizeEvent *event); virtual void keyPressEvent(QKeyEvent *event); virtual void mousePressEvent(QMouseEvent *event); virtual void mouseReleaseEvent(QMouseEvent *event); virtual void mouseDoubleClickEvent(QMouseEvent *event); virtual void mouseMoveEvent(QMouseEvent *event); virtual void contextMenuEvent(QContextMenuEvent *event); virtual void dragEnterEvent(QDragEnterEvent *event); virtual void dragLeaveEvent(QDragLeaveEvent *event); virtual void dragMoveEvent(QDragMoveEvent *event); virtual void dropEvent(QDropEvent *event); virtual void inputMethodEvent(QInputMethodEvent *event); virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const; virtual void scrollContentsBy(int, int) {} private: ScintillaQt *sqt; QTime time; int preeditPos; QString preeditString; int wheelDelta; }; #ifdef SCI_NAMESPACE } #endif #endif /* SCINTILLAEDITBASE_H */ |
Added qt/ScintillaEditBase/ScintillaEditBase.pro.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
#------------------------------------------------- # # Project created by QtCreator 2011-05-05T12:41:23 # #------------------------------------------------- QT += core gui TARGET = ScintillaEditBase TEMPLATE = lib CONFIG += lib_bundle VERSION = 3.3.0 SOURCES += \ PlatQt.cpp \ ScintillaQt.cpp \ ScintillaEditBase.cpp \ ../../src/XPM.cxx \ ../../src/ViewStyle.cxx \ ../../src/UniConversion.cxx \ ../../src/Style.cxx \ ../../src/Selection.cxx \ ../../src/ScintillaBase.cxx \ ../../src/RunStyles.cxx \ ../../src/RESearch.cxx \ ../../src/PositionCache.cxx \ ../../src/PerLine.cxx \ ../../src/LineMarker.cxx \ ../../src/KeyMap.cxx \ ../../src/Indicator.cxx \ ../../src/ExternalLexer.cxx \ ../../src/Editor.cxx \ ../../src/Document.cxx \ ../../src/Decoration.cxx \ ../../src/ContractionState.cxx \ ../../src/CharClassify.cxx \ ../../src/CellBuffer.cxx \ ../../src/Catalogue.cxx \ ../../src/CallTip.cxx \ ../../src/AutoComplete.cxx \ ../../lexlib/WordList.cxx \ ../../lexlib/StyleContext.cxx \ ../../lexlib/PropSetSimple.cxx \ ../../lexlib/LexerSimple.cxx \ ../../lexlib/LexerNoExceptions.cxx \ ../../lexlib/LexerModule.cxx \ ../../lexlib/LexerBase.cxx \ ../../lexlib/CharacterSet.cxx \ ../../lexlib/Accessor.cxx \ ../../lexers/*.cxx HEADERS += \ PlatQt.h \ ScintillaQt.h \ ScintillaEditBase.h \ ../../src/XPM.h \ ../../src/ViewStyle.h \ ../../src/UniConversion.h \ ../../src/SVector.h \ ../../src/Style.h \ ../../src/SplitVector.h \ ../../src/Selection.h \ ../../src/ScintillaBase.h \ ../../src/RunStyles.h \ ../../src/RESearch.h \ ../../src/PositionCache.h \ ../../src/PerLine.h \ ../../src/Partitioning.h \ ../../src/LineMarker.h \ ../../src/KeyMap.h \ ../../src/Indicator.h \ ../../src/FontQuality.h \ ../../src/ExternalLexer.h \ ../../src/Editor.h \ ../../src/Document.h \ ../../src/Decoration.h \ ../../src/ContractionState.h \ ../../src/CharClassify.h \ ../../src/CellBuffer.h \ ../../src/Catalogue.h \ ../../src/CallTip.h \ ../../src/AutoComplete.h \ ../../include/Scintilla.h \ ../../include/SciLexer.h \ ../../include/Platform.h \ ../../include/ILexer.h \ ../../lexlib/WordList.h \ ../../lexlib/StyleContext.h \ ../../lexlib/SparseState.h \ ../../lexlib/PropSetSimple.h \ ../../lexlib/OptionSet.h \ ../../lexlib/LexerSimple.h \ ../../lexlib/LexerNoExceptions.h \ ../../lexlib/LexerModule.h \ ../../lexlib/LexerBase.h \ ../../lexlib/LexAccessor.h \ ../../lexlib/CharacterSet.h \ ../../lexlib/Accessor.h OTHER_FILES += INCLUDEPATH += ../../include ../../src ../../lexlib DEFINES += SCINTILLA_QT=1 MAKING_LIBRARY=1 SCI_LEXER=1 _CRT_SECURE_NO_DEPRECATE=1 DESTDIR = ../../bin macx { QMAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../Frameworks/ } |
Added qt/ScintillaEditBase/ScintillaQt.cpp.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 |
// // Copyright (c) 1990-2011, Scientific Toolworks, Inc. // // The License.txt file describes the conditions under which this software may be distributed. // // Author: Jason Haslam // // Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware // ScintillaQt.cpp - Qt specific subclass of ScintillaBase #include "PlatQt.h" #include "ScintillaQt.h" #ifdef SCI_LEXER #include "LexerModule.h" #include "ExternalLexer.h" #endif #include <QApplication> #include <QDrag> #include <QInputContext> #include <QMimeData> #include <QMenu> #include <QScrollBar> #include <QTimer> #include <QTextCodec> #ifdef SCI_NAMESPACE using namespace Scintilla; #endif ScintillaQt::ScintillaQt(QAbstractScrollArea *parent) : QObject(parent), scrollArea(parent), vMax(0), hMax(0), vPage(0), hPage(0), haveMouseCapture(false), dragWasDropped(false) { wMain = scrollArea->viewport(); // On OS X drawing text into a pixmap moves it around 1 pixel to // the right compared to drawing it directly onto a window. // Buffered drawing turned off by default to avoid this. WndProc(SCI_SETBUFFEREDDRAW, false, 0); Initialise(); } ScintillaQt::~ScintillaQt() { SetTicking(false); } void ScintillaQt::tick() { Tick(); } void ScintillaQt::execCommand(QAction *action) { int command = action->data().toInt(); Command(command); } #if defined(Q_OS_WIN) static const QString sMSDEVColumnSelect("MSDEVColumnSelect"); static const QString sWrappedMSDEVColumnSelect("application/x-qt-windows-mime;value=\"MSDEVColumnSelect\""); #elif defined(Q_OS_MAC) static const QString sScintillaRecPboardType("com.scintilla.utf16-plain-text.rectangular"); static const QString sScintillaRecMimeType("text/x-scintilla.utf16-plain-text.rectangular"); #else // Linux static const QString sMimeRectangularMarker("text/x-rectangular-marker"); #endif #ifdef Q_OS_MAC class ScintillaRectangularMime : public QMacPasteboardMime { public: ScintillaRectangularMime() : QMacPasteboardMime(MIME_ALL) { } QString convertorName() { return QString("ScintillaRectangularMime"); } bool canConvert(const QString &mime, QString flav) { return mimeFor(flav) == mime; } QString mimeFor(QString flav) { if (flav == sScintillaRecPboardType) return sScintillaRecMimeType; return QString(); } QString flavorFor(const QString &mime) { if (mime == sScintillaRecMimeType) return sScintillaRecPboardType; return QString(); } QVariant convertToMime(const QString & /* mime */, QList<QByteArray> data, QString /* flav */) { QByteArray all; foreach (QByteArray i, data) { all += i; } return QVariant(all); } QList<QByteArray> convertFromMime(const QString & /* mime */, QVariant data, QString /* flav */) { QByteArray a = data.toByteArray(); QList<QByteArray> l; l.append(a); return l; } }; // The Mime object registers itself but only want one for all Scintilla instances. // Should delete at exit to help memory leak detection but that would be extra work // and, since the clipboard exists after last Scintilla instance, may be complex. static ScintillaRectangularMime *singletonMime = 0; #endif void ScintillaQt::Initialise() { #if defined(Q_OS_WIN) || defined(Q_OS_MAC) rectangularSelectionModifier = SCMOD_ALT; #else rectangularSelectionModifier = SCMOD_CTRL; #endif #ifdef Q_OS_MAC if (!singletonMime) { singletonMime = new ScintillaRectangularMime(); QStringList slTypes(sScintillaRecPboardType); qRegisterDraggedTypes(slTypes); } #endif connect(QApplication::clipboard(), SIGNAL(selectionChanged()), this, SLOT(SelectionChanged())); } void ScintillaQt::Finalise() { SetTicking(false); ScintillaBase::Finalise(); } void ScintillaQt::SelectionChanged() { bool nowPrimary = QApplication::clipboard()->ownsSelection(); if (nowPrimary != primarySelection) { primarySelection = nowPrimary; Redraw(); } } bool ScintillaQt::DragThreshold(Point ptStart, Point ptNow) { int xMove = abs(ptStart.x - ptNow.x); int yMove = abs(ptStart.y - ptNow.y); return (xMove > QApplication::startDragDistance()) || (yMove > QApplication::startDragDistance()); } static QString StringFromSelectedText(const SelectionText &selectedText) { if (selectedText.codePage == SC_CP_UTF8) { return QString::fromUtf8(selectedText.s, selectedText.len-1); } else { QTextCodec *codec = QTextCodec::codecForName( CharacterSetID(selectedText.characterSet)); return codec->toUnicode(selectedText.s, selectedText.len-1); } } static void AddRectangularToMime(QMimeData *mimeData, QString su) { #if defined(Q_OS_WIN) // Add an empty marker mimeData->setData(sMSDEVColumnSelect, QByteArray()); #elif defined(Q_OS_MAC) // OS X gets marker + data to work with other implementations. // Don't understand how this works but it does - the // clipboard format is supposed to be UTF-16, not UTF-8. mimeData->setData(sScintillaRecMimeType, su.toUtf8()); #else Q_UNUSED(su); // Linux // Add an empty marker mimeData->setData(sMimeRectangularMarker, QByteArray()); #endif } static bool IsRectangularInMime(const QMimeData *mimeData) { QStringList formats = mimeData->formats(); for (int i = 0; i < formats.size(); ++i) { #if defined(Q_OS_WIN) // Windows rectangular markers // If rectangular copies made by this application, see base name. if (formats[i] == sMSDEVColumnSelect) return true; // Otherwise see wrapped name. if (formats[i] == sWrappedMSDEVColumnSelect) return true; #elif defined(Q_OS_MAC) if (formats[i] == sScintillaRecMimeType) return true; #else // Linux if (formats[i] == sMimeRectangularMarker) return true; #endif } return false; } bool ScintillaQt::ValidCodePage(int codePage) const { return codePage == 0 || codePage == SC_CP_UTF8 || codePage == 932 || codePage == 936 || codePage == 949 || codePage == 950 || codePage == 1361; } void ScintillaQt::ScrollText(int linesToMove) { int dy = vs.lineHeight * (linesToMove); scrollArea->viewport()->scroll(0, dy); } void ScintillaQt::SetVerticalScrollPos() { scrollArea->verticalScrollBar()->setValue(topLine); emit verticalScrolled(topLine); } void ScintillaQt::SetHorizontalScrollPos() { scrollArea->horizontalScrollBar()->setValue(xOffset); emit horizontalScrolled(xOffset); } bool ScintillaQt::ModifyScrollBars(int nMax, int nPage) { bool modified = false; int vNewPage = nPage; int vNewMax = nMax - vNewPage + 1; if (vMax != vNewMax || vPage != vNewPage) { vMax = vNewMax; vPage = vNewPage; modified = true; scrollArea->verticalScrollBar()->setMaximum(vMax); scrollArea->verticalScrollBar()->setPageStep(vPage); emit verticalRangeChanged(vMax, vPage); } int hNewPage = GetTextRectangle().Width(); int hNewMax = (scrollWidth > hNewPage) ? scrollWidth - hNewPage : 0; int charWidth = vs.styles[STYLE_DEFAULT].aveCharWidth; if (hMax != hNewMax || hPage != hNewPage || scrollArea->horizontalScrollBar()->singleStep() != charWidth) { hMax = hNewMax; hPage = hNewPage; modified = true; scrollArea->horizontalScrollBar()->setMaximum(hMax); scrollArea->horizontalScrollBar()->setPageStep(hPage); scrollArea->horizontalScrollBar()->setSingleStep(charWidth); emit horizontalRangeChanged(hMax, hPage); } return modified; } void ScintillaQt::ReconfigureScrollBars() { if (verticalScrollBarVisible) { scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); } else { scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); } if (horizontalScrollBarVisible && (wrapState == eWrapNone)) { scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); } else { scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); } } void ScintillaQt::CopyToModeClipboard(const SelectionText &selectedText, QClipboard::Mode clipboardMode_) { QClipboard *clipboard = QApplication::clipboard(); clipboard->clear(clipboardMode_); QString su = StringFromSelectedText(selectedText); QMimeData *mimeData = new QMimeData(); mimeData->setText(su); if (selectedText.rectangular) { AddRectangularToMime(mimeData, su); } // Allow client code to add additional data (e.g rich text). emit aboutToCopy(mimeData); clipboard->setMimeData(mimeData, clipboardMode_); } void ScintillaQt::Copy() { if (!sel.Empty()) { SelectionText st; CopySelectionRange(&st); CopyToClipboard(st); } } void ScintillaQt::CopyToClipboard(const SelectionText &selectedText) { CopyToModeClipboard(selectedText, QClipboard::Clipboard); } void ScintillaQt::PasteFromMode(QClipboard::Mode clipboardMode_) { QClipboard *clipboard = QApplication::clipboard(); const QMimeData *mimeData = clipboard->mimeData(clipboardMode_); bool isRectangular = IsRectangularInMime(mimeData); QString text = clipboard->text(clipboardMode_); QByteArray utext = BytesForDocument(text); int len = utext.length(); char *dest = Document::TransformLineEnds(&len, utext, len, pdoc->eolMode); SelectionText selText; selText.Set(dest, len, pdoc->dbcsCodePage, CharacterSetOfDocument(), isRectangular, false); UndoGroup ug(pdoc); ClearSelection(multiPasteMode == SC_MULTIPASTE_EACH); SelectionPosition selStart = sel.IsRectangular() ? sel.Rectangular().Start() : sel.Range(sel.Main()).Start(); if (selText.rectangular) { PasteRectangular(selStart, selText.s, selText.len); } else { InsertPaste(selStart, selText.s, selText.len); } EnsureCaretVisible(); } void ScintillaQt::Paste() { PasteFromMode(QClipboard::Clipboard); } void ScintillaQt::ClaimSelection() { if (QApplication::clipboard()->supportsSelection()) { // X Windows has a 'primary selection' as well as the clipboard. // Whenever the user selects some text, we become the primary selection if (!sel.Empty()) { primarySelection = true; SelectionText st; CopySelectionRange(&st); CopyToModeClipboard(st, QClipboard::Selection); } else { primarySelection = false; } } } void ScintillaQt::NotifyChange() { emit notifyChange(); emit command( Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE), reinterpret_cast<sptr_t>(wMain.GetID())); } void ScintillaQt::NotifyFocus(bool focus) { emit command( Platform::LongFromTwoShorts (GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), reinterpret_cast<sptr_t>(wMain.GetID())); } void ScintillaQt::NotifyParent(SCNotification scn) { scn.nmhdr.hwndFrom = wMain.GetID(); scn.nmhdr.idFrom = GetCtrlID(); emit notifyParent(scn); } void ScintillaQt::SetTicking(bool on) { QTimer *qTimer; if (timer.ticking != on) { timer.ticking = on; if (timer.ticking) { qTimer = new QTimer; connect(qTimer, SIGNAL(timeout()), this, SLOT(tick())); qTimer->start(timer.tickSize); timer.tickerID = qTimer; } else { qTimer = static_cast<QTimer *>(timer.tickerID); qTimer->stop(); disconnect(qTimer, SIGNAL(timeout()), 0, 0); delete qTimer; timer.tickerID = 0; } } timer.ticksToWait = caret.period; } void ScintillaQt::onIdle() { bool continueIdling = Idle(); if (!continueIdling) { SetIdle(false); } } bool ScintillaQt::SetIdle(bool on) { QTimer *qIdle; if (on) { // Start idler, if it's not running. if (!idler.state) { idler.state = true; qIdle = new QTimer; connect(qIdle, SIGNAL(timeout()), this, SLOT(onIdle())); qIdle->start(0); idler.idlerID = qIdle; } } else { // Stop idler, if it's running if (idler.state) { idler.state = false; qIdle = static_cast<QTimer *>(idler.idlerID); qIdle->stop(); disconnect(qIdle, SIGNAL(timeout()), 0, 0); delete qIdle; idler.idlerID = 0; } } return true; } int ScintillaQt::CharacterSetOfDocument() const { return vs.styles[STYLE_DEFAULT].characterSet; } const char *ScintillaQt::CharacterSetIDOfDocument() const { return CharacterSetID(CharacterSetOfDocument()); } QString ScintillaQt::StringFromDocument(const char *s) const { if (IsUnicodeMode()) { return QString::fromUtf8(s); } else { QTextCodec *codec = QTextCodec::codecForName( CharacterSetID(CharacterSetOfDocument())); return codec->toUnicode(s); } } QByteArray ScintillaQt::BytesForDocument(const QString &text) const { if (IsUnicodeMode()) { return text.toUtf8(); } else { QTextCodec *codec = QTextCodec::codecForName( CharacterSetID(CharacterSetOfDocument())); return codec->fromUnicode(text); } } class CaseFolderUTF8 : public CaseFolderTable { public: CaseFolderUTF8() { StandardASCII(); } virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) { if ((lenMixed == 1) && (sizeFolded > 0)) { folded[0] = mapping[static_cast<unsigned char>(mixed[0])]; return 1; } else { QString su = QString::fromUtf8(mixed, lenMixed); QString suFolded = su.toCaseFolded(); QByteArray bytesFolded = suFolded.toUtf8(); if (bytesFolded.length() < static_cast<int>(sizeFolded)) { memcpy(folded, bytesFolded, bytesFolded.length()); return bytesFolded.length(); } else { folded[0] = '\0'; return 0; } } } }; class CaseFolderDBCS : public CaseFolderTable { QTextCodec *codec; public: CaseFolderDBCS(QTextCodec *codec_) : codec(codec_) { StandardASCII(); } virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) { if ((lenMixed == 1) && (sizeFolded > 0)) { folded[0] = mapping[static_cast<unsigned char>(mixed[0])]; return 1; } else if (codec) { QString su = codec->toUnicode(mixed, lenMixed); QString suFolded = su.toCaseFolded(); QByteArray bytesFolded = codec->fromUnicode(suFolded); if (bytesFolded.length() < static_cast<int>(sizeFolded)) { memcpy(folded, bytesFolded, bytesFolded.length()); return bytesFolded.length(); } } // Something failed so return a single NUL byte folded[0] = '\0'; return 1; } }; CaseFolder *ScintillaQt::CaseFolderForEncoding() { if (pdoc->dbcsCodePage == SC_CP_UTF8) { return new CaseFolderUTF8(); } else { const char *charSetBuffer = CharacterSetIDOfDocument(); if (charSetBuffer) { if (pdoc->dbcsCodePage == 0) { CaseFolderTable *pcf = new CaseFolderTable(); pcf->StandardASCII(); QTextCodec *codec = QTextCodec::codecForName(charSetBuffer); // Only for single byte encodings for (int i=0x80; i<0x100; i++) { char sCharacter[2] = "A"; sCharacter[0] = i; QString su = codec->toUnicode(sCharacter, 1); QString suFolded = su.toCaseFolded(); QByteArray bytesFolded = codec->fromUnicode(suFolded); if (bytesFolded.length() == 1) { pcf->SetTranslation(sCharacter[0], bytesFolded[0]); } } return pcf; } else { return new CaseFolderDBCS(QTextCodec::codecForName(charSetBuffer)); } } return 0; } } std::string ScintillaQt::CaseMapString(const std::string &s, int caseMapping) { if (s.size() == 0) return std::string(); if (caseMapping == cmSame) return s; QTextCodec *codec = 0; QString text; if (IsUnicodeMode()) { text = QString::fromUtf8(s.c_str(), s.length()); } else { codec = QTextCodec::codecForName(CharacterSetIDOfDocument()); text = codec->toUnicode(s.c_str(), s.length()); } if (caseMapping == cmUpper) { text = text.toUpper(); } else { text = text.toLower(); } QByteArray bytes = BytesForDocument(text); return std::string(bytes.data(), bytes.length()); } void ScintillaQt::SetMouseCapture(bool on) { // This is handled automatically by Qt if (mouseDownCaptures) { haveMouseCapture = on; } } bool ScintillaQt::HaveMouseCapture() { return haveMouseCapture; } void ScintillaQt::StartDrag() { inDragDrop = ddDragging; dropWentOutside = true; if (drag.len) { QMimeData *mimeData = new QMimeData; QString sText = StringFromSelectedText(drag); mimeData->setText(sText); if (drag.rectangular) { AddRectangularToMime(mimeData, sText); } // This QDrag is not freed as that causes a crash on Linux QDrag *dragon = new QDrag(scrollArea); dragon->setMimeData(mimeData); Qt::DropAction dropAction = dragon->exec(Qt::CopyAction|Qt::MoveAction); if ((dropAction == Qt::MoveAction) && dropWentOutside) { // Remove dragged out text ClearSelection(); } } inDragDrop = ddNone; SetDragPosition(SelectionPosition(invalidPosition)); } void ScintillaQt::CreateCallTipWindow(PRectangle rc) { if (!ct.wCallTip.Created()) { QWidget *pCallTip = new QWidget(0, Qt::ToolTip); ct.wCallTip = pCallTip; pCallTip->move(rc.left, rc.top); pCallTip->resize(rc.Width(), rc.Height()); } } void ScintillaQt::AddToPopUp(const char *label, int cmd, bool enabled) { QMenu *menu = static_cast<QMenu *>(popup.GetID()); QString text(label); if (text.isEmpty()) { menu->addSeparator(); } else { QAction *action = menu->addAction(text); action->setData(cmd); action->setEnabled(enabled); } // Make sure the menu's signal is connected only once. menu->disconnect(); connect(menu, SIGNAL(triggered(QAction *)), this, SLOT(execCommand(QAction *))); } sptr_t ScintillaQt::WndProc(unsigned int message, uptr_t wParam, sptr_t lParam) { try { switch (message) { case SCI_GRABFOCUS: scrollArea->setFocus(Qt::OtherFocusReason); break; case SCI_GETDIRECTFUNCTION: return reinterpret_cast<sptr_t>(DirectFunction); case SCI_GETDIRECTPOINTER: return reinterpret_cast<sptr_t>(this); #ifdef SCI_LEXER case SCI_LOADLEXERLIBRARY: LexerManager::GetInstance()->Load(reinterpret_cast<const char *>(lParam)); break; #endif default: return ScintillaBase::WndProc(message, wParam, lParam); } } catch (std::bad_alloc &) { errorStatus = SC_STATUS_BADALLOC; } catch (...) { errorStatus = SC_STATUS_FAILURE; } return 0l; } sptr_t ScintillaQt::DefWndProc(unsigned int, uptr_t, sptr_t) { return 0; } sptr_t ScintillaQt::DirectFunction( ScintillaQt *sciThis, unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return sciThis->WndProc(iMessage, wParam, lParam); } // Additions to merge in Scientific Toolworks widget structure void ScintillaQt::PartialPaint(const PRectangle &rect) { rcPaint = rect; paintState = painting; PRectangle rcClient = GetClientRectangle(); paintingAllText = rcPaint.Contains(rcClient); AutoSurface surface(this); Paint(surface, rcPaint); surface->Release(); if (paintState == paintAbandoned) { // FIXME: Failure to paint the requested rectangle in each // paint event causes flicker on some platforms (Mac?) // Paint rect immediately. paintState = painting; paintingAllText = true; AutoSurface surface(this); Paint(surface, rcPaint); surface->Release(); // Queue a full repaint. scrollArea->viewport()->update(); } paintState = notPainting; } void ScintillaQt::DragEnter(const Point &point) { SetDragPosition(SPositionFromLocation(point, false, false, UserVirtualSpace())); } void ScintillaQt::DragMove(const Point &point) { SetDragPosition(SPositionFromLocation(point, false, false, UserVirtualSpace())); } void ScintillaQt::DragLeave() { SetDragPosition(SelectionPosition(invalidPosition)); } void ScintillaQt::Drop(const Point &point, const QMimeData *data, bool move) { QString text = data->text(); bool rectangular = IsRectangularInMime(data); QByteArray bytes = BytesForDocument(text); int len = bytes.length(); char *dest = Document::TransformLineEnds(&len, bytes, len, pdoc->eolMode); SelectionPosition movePos = SPositionFromLocation(point, false, false, UserVirtualSpace()); DropAt(movePos, dest, move, rectangular); delete []dest; } |
Added qt/ScintillaEditBase/ScintillaQt.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
// // Copyright (c) 1990-2011, Scientific Toolworks, Inc. // // The License.txt file describes the conditions under which this software may be distributed. // // Author: Jason Haslam // // Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware // ScintillaQt.h - Qt specific subclass of ScintillaBase #ifndef SCINTILLAQT_H #define SCINTILLAQT_H #include <stdlib.h> #include <string.h> #include <stdio.h> #include <ctype.h> #include <time.h> #include <string> #include <vector> #include <map> #include "Scintilla.h" #include "Platform.h" #include "ILexer.h" #include "SVector.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" #include "ContractionState.h" #include "CellBuffer.h" #include "CallTip.h" #include "KeyMap.h" #include "Indicator.h" #include "XPM.h" #include "LineMarker.h" #include "Style.h" #include "AutoComplete.h" #include "ViewStyle.h" #include "CharClassify.h" #include "Decoration.h" #include "Document.h" #include "Selection.h" #include "PositionCache.h" #include "Editor.h" #include "ScintillaBase.h" #ifdef SCI_LEXER #include "SciLexer.h" #include "PropSetSimple.h" #endif #include <QObject> #include <QAbstractScrollArea> #include <QAction> #include <QClipboard> #include <QPaintEvent> #ifdef SCI_NAMESPACE namespace Scintilla { #endif class ScintillaQt : public QObject, public ScintillaBase { Q_OBJECT public: ScintillaQt(QAbstractScrollArea *parent); virtual ~ScintillaQt(); signals: void horizontalScrolled(int value); void verticalScrolled(int value); void horizontalRangeChanged(int max, int page); void verticalRangeChanged(int max, int page); void notifyParent(SCNotification scn); void notifyChange(); // Clients can use this hook to add additional // formats (e.g. rich text) to the MIME data. void aboutToCopy(QMimeData *data); void command(uptr_t wParam, sptr_t lParam); private slots: void tick(); void onIdle(); void execCommand(QAction *action); void SelectionChanged(); private: virtual void Initialise(); virtual void Finalise(); virtual bool DragThreshold(Point ptStart, Point ptNow); virtual bool ValidCodePage(int codePage) const; private: virtual void ScrollText(int linesToMove); virtual void SetVerticalScrollPos(); virtual void SetHorizontalScrollPos(); virtual bool ModifyScrollBars(int nMax, int nPage); virtual void ReconfigureScrollBars(); void CopyToModeClipboard(const SelectionText &selectedText, QClipboard::Mode clipboardMode_); virtual void Copy(); virtual void CopyToClipboard(const SelectionText &selectedText); void PasteFromMode(QClipboard::Mode clipboardMode_); virtual void Paste(); virtual void ClaimSelection(); virtual void NotifyChange(); virtual void NotifyFocus(bool focus); virtual void NotifyParent(SCNotification scn); virtual void SetTicking(bool on); virtual bool SetIdle(bool on); virtual void SetMouseCapture(bool on); virtual bool HaveMouseCapture(); virtual void StartDrag(); int CharacterSetOfDocument() const; const char *CharacterSetIDOfDocument() const; QString StringFromDocument(const char *s) const; QByteArray BytesForDocument(const QString &text) const; virtual CaseFolder *CaseFolderForEncoding(); virtual std::string CaseMapString(const std::string &s, int caseMapping); virtual void CreateCallTipWindow(PRectangle rc); virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true); virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); static sptr_t DirectFunction(ScintillaQt *sciThis, unsigned int iMessage, uptr_t wParam, sptr_t lParam); protected: void PartialPaint(const PRectangle &rect); void DragEnter(const Point &point); void DragMove(const Point &point); void DragLeave(); void Drop(const Point &point, const QMimeData *data, bool move); private: QAbstractScrollArea *scrollArea; int vMax, hMax; // Scroll bar maximums. int vPage, hPage; // Scroll bar page sizes. bool haveMouseCapture; bool dragWasDropped; int rectangularSelectionModifier; friend class ScintillaEditBase; }; #ifdef SCI_NAMESPACE } #endif #endif // SCINTILLAQT_H |
Added qt/ScintillaEditPy/README.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
README for building of ScintillaEditPy on Qt with PySide This directory is for building a Python encapsulation of Scintilla for use with PySide. For C++ libraries see the README in the parent directory. Prerequisites PySide and ScintillaEditPy currently only support Python 2.x. CMake may be used to rebuild PySide and is required on Windows. It can be downloaded from http://www.cmake.org/cmake/resources/software.html On Windows, PySide only supports Visual C++ 2008. The "Visual Studio 2008 Command Prompt" should be used to run all build commands. Visual C++ 2008 Express Edition can be downloaded from http://msdn.microsoft.com/en-us/express/future/bb421473 Download and install PySide. Instructions are on the PySide web site http://developer.qt.nokia.com/wiki/Category:LanguageBindings::PySide::Downloads For Linux, there may be both PySide library packages and PySide development files. Both should be installed as ScintillaEditPy needs the headers and libraries from the development package and runs with the normal library package. On apt-based systems, the packages are libshiboken-dev, shiboken, libpyside-dev, and python-pyside. python-dev is also needed for Python language headers. On yum-based systems the packages are shiboken-devel, python-pyside-devel, and python-devel. The qmake program may not be in the path and can be found with "find /usr -name qmake". On Windows, the PySide library packages can be downloaded from http://developer.qt.nokia.com/wiki/PySide_Binaries_Windows The PySide development files must be built from source using CMake as described on the PySide site. This will create a Unix-style set of [bin, include, lib, and share] directories in packaging\setuptools\install-py<ver>-qt<qver>. There is no standard place for the PySide development files so copy them to "\usr", creating it if needed. On OS X, a combined package with PySide libraries and PySide development files can be downloaded from http://developer.qt.nokia.com/wiki/PySide_Binaries_MacOSX This package works best in combination with the Qt libraries for Mac from http://qt.nokia.com/downloads/downloads#qt-lib The path should be modified so that a Python 2.x interpreter and Qt's "qmake" program can be run by typing "python" or "qmake". Building There are several steps to building and they are encapsulated in the sepbuild.py script which is run: python sepbuild.py This script first runs the WidgetGen.py script to fill out the ScintillaEdit.h, ScintillaEdit.cpp and ScintillaConstants.py files. A short file "sepbuild.pri" is written out which contains a series of version and path properties discovered by sepbuild.py which are used by qmake. Then it runs PySide's "shiboken" program to create C++ code that will act as a bridge between Python and the C++ libraries. This code goes into the ScintillaEditPy/ScintillaEditPy directory. Several log files are produced which can help uncover problems in the bridge if it fails to build. The qmake program is run to produce make files from ScintillaEditPy.pro. The system make program is then run to build the library. The library is located in the scintilla/bin directory as ScintillaEditPy.so for Unix systems and ScintillaEditPy.pyd for Windows. A demonstration program can be run: python testsepq.py The individual steps in the script can be run manually if wanted although the shiboken program has complex arguments and differs between systems so run sepbuild.py and copy the section starting with a line containing "generatorrunner" and continuing to "typesystem_ScintillaEdit.xml". On Windows, it is more difficult to set up an environment to debug ScintillaEditPy since all the libraries have to be debug or all have to be release. The easy path is to always build for release with "nmake release". To remove generated code, run "python sepbuild.py --clean". |
Added qt/ScintillaEditPy/ScintillaConstants.py.template.
> > > > > > |
1 2 3 4 5 6 |
# ScintillaConstants.py # Define all the symbolic constants from Scintilla.iface so Python code can use them # Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware # ++Autogenerated -- start of section automatically generated from Scintilla.iface */ # --Autogenerated -- end of section automatically generated from Scintilla.iface */ |
Added qt/ScintillaEditPy/ScintillaEditPy.pro.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
TEMPLATE = lib QT += core gui TARGET = ScintillaEditPy # Clear debug & release so that sepbuild.pri can set one or the other CONFIG -= debug release include(sepbuild.pri) VERSION = $$SCINTILLA_VERSION win32 { DebugBuild { TARGET_EXT = _d.pyd } else { TARGET_EXT = .pyd } } INCLUDEPATH += ../ScintillaEdit INCLUDEPATH += ../ScintillaEditBase INCLUDEPATH += ../../include ../../lexlib ../../src INCLUDEPATH += $$PY_INCLUDES INCLUDEPATH += $$SHIBOKEN_INCLUDES INCLUDEPATH += $$PYSIDE_INCLUDES INCLUDEPATH += $$PYSIDE_INCLUDES/QtCore INCLUDEPATH += $$PYSIDE_INCLUDES/QtGui unix:!mac { LIBS += -ldl LIBS += `pkg-config pyside --libs` QMAKE_CXXFLAGS += -Wno-unused-parameter -Wno-empty-body } macx { # Only build for x64 for now # QMAKE_CFLAGS = -arch i386 -arch x86_64 # QMAKE_CXXFLAGS = -arch i386 -arch x86_64 # QMAKE_LFLAGS = -arch i386 -arch x86_64 LIBS += -L$$PY_LIBDIR -lpython$$PY_VERSION_SUFFIX LIBS += -L$$PYSIDE_LIB debug { LIBS += -lshiboken-python$$PY_VERSION_SUFFIX-dbg LIBS += -lpyside-python$$PY_VERSION_SUFFIX-dbg } else { LIBS += -lshiboken-python$$PY_VERSION_SUFFIX LIBS += -lpyside-python$$PY_VERSION_SUFFIX } } win32 { DebugBuild { DEFINES += DEBUG LIBS += -lQtCored4 } else { LIBS += -lQtCore } LIBS += -L$$PY_PREFIX/libs # Note python lib is pulled in via a #pragma LIBS += -L$$PYSIDE_LIB # PySide uses x.y suffix on Windows even though Python uses xy DebugBuild { LIBS += -lshiboken-python$${PY_VERSION}_d LIBS += -lpyside-python$${PY_VERSION}_d } else { LIBS += -lshiboken-python$${PY_VERSION} LIBS += -lpyside-python$${PY_VERSION} } } # Wrapper sources; notifyheader commented out due to shiboken bug SOURCES += \ ScintillaEditPy/scintillaeditpy_module_wrapper.cpp \ ScintillaEditPy/sci_notifyheader_wrapper.cpp \ ScintillaEditPy/scnotification_wrapper.cpp \ ScintillaEditPy/scintillaeditbase_wrapper.cpp \ ScintillaEditPy/scintillaedit_wrapper.cpp \ ScintillaEditPy/scintilladocument_wrapper.cpp # ScintillaEdit sources SOURCES += \ ../ScintillaEdit/ScintillaEdit.cpp \ ../ScintillaEdit/ScintillaDocument.cpp \ ../ScintillaEditBase/PlatQt.cpp \ ../ScintillaEditBase/ScintillaQt.cpp \ ../ScintillaEditBase/ScintillaEditBase.cpp \ ../../src/*.cxx \ ../../lexlib/*.cxx \ ../../lexers/*.cxx # HEADERS is used to find what needs to be run through moc HEADERS += \ ../ScintillaEdit/ScintillaEdit.h \ ../ScintillaEdit/ScintillaDocument.h \ ../ScintillaEditBase/ScintillaQt.h \ ../ScintillaEditBase/ScintillaEditBase.h DEFINES += SCINTILLA_QT=1 MAKING_LIBRARY=1 SCI_LEXER=1 _CRT_SECURE_NO_DEPRECATE=1 DESTDIR = ../../bin unix:!mac { # Rename to not have 'lib' at start QMAKE_POST_LINK += rm -rf ../../bin/ScintillaEditPy.so && ln -s libScintillaEditPy.so ../../bin/ScintillaEditPy.so } macx { # Rename to .so and not have 'lib' at start QMAKE_POST_LINK += rm -rf ../../bin/ScintillaEditPy.so && ln -s libScintillaEditPy.dylib ../../bin/ScintillaEditPy.so } |
Added qt/ScintillaEditPy/global.h.
> > > > |
1 2 3 4 |
#include "pyside_global.h" #include "ScintillaEditBase.h" #include "ScintillaEdit.h" |
Added qt/ScintillaEditPy/sepbuild.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
import distutils.sysconfig import getopt import glob import os import platform import shutil import subprocess import stat import sys sys.path.append(os.path.join("..", "ScintillaEdit")) import WidgetGen # Decide up front which platform, treat anything other than Windows or OS X as Linux PLAT_WINDOWS = platform.system() == "Windows" PLAT_DARWIN = platform.system() == "Darwin" PLAT_LINUX = not (PLAT_DARWIN or PLAT_WINDOWS) def IsFileNewer(name1, name2): """ Returns whether file with name1 is newer than file with name2. Returns 1 if name2 doesn't exist. """ if not os.path.exists(name1): return 0 if not os.path.exists(name2): return 1 mod_time1 = os.stat(name1)[stat.ST_MTIME] mod_time2 = os.stat(name2)[stat.ST_MTIME] return (mod_time1 > mod_time2) def textFromRun(args): (stdoutdata, stderrdata) = subprocess.Popen(args, shell=True, stdout=subprocess.PIPE).communicate() return stdoutdata def runProgram(args, exitOnFailure): print(" ".join(args)) retcode = subprocess.call(" ".join(args), shell=True, stderr=subprocess.STDOUT) if retcode: print("Failed in " + " ".join(args) + " return code = " + str(retcode)) if exitOnFailure: sys.exit() def usage(): print("sepbuild.py [-h|--help][-c|--clean][-u|--underscore-names]") print("") print("Generate PySide wappers and build them.") print("") print("options:") print("") print("-c --clean remove all object and generated files") print("-b --pyside-base Location of the PySide+Qt4 sandbox to use") print("-h --help display this text") print("-d --debug=yes|no force debug build (or non-debug build)") print("-u --underscore-names use method_names consistent with GTK+ standards") modifyFunctionElement = """ <modify-function signature="%s">%s </modify-function> """ injectCode = """ <inject-code class="target" position="beginning">%s </inject-code>""" injectCheckN = """ if (!cppArg%d) { PyErr_SetString(PyExc_ValueError, "Null string argument"); return 0; }""" def methodSignature(name, v, options): argTypes = "" p1Type = WidgetGen.cppAlias(v["Param1Type"]) if p1Type: argTypes = argTypes + p1Type p2Type = WidgetGen.cppAlias(v["Param2Type"]) if p2Type and v["Param2Type"] != "stringresult": if p1Type: argTypes = argTypes + ", " argTypes = argTypes + p2Type methodName = WidgetGen.normalisedName(name, options, v["FeatureType"]) constDeclarator = " const" if v["FeatureType"] == "get" else "" return methodName + "(" + argTypes + ")" + constDeclarator def printTypeSystemFile(f,out, options): for name in f.order: v = f.features[name] if v["Category"] != "Deprecated": feat = v["FeatureType"] if feat in ["fun", "get", "set"]: checks = "" if v["Param1Type"] == "string": checks = checks + (injectCheckN % 0) if v["Param2Type"] == "string": if v["Param1Type"] == "": # Only arg 2 -> treat as first checks = checks + (injectCheckN % 0) else: checks = checks + (injectCheckN % 1) if checks: inject = injectCode % checks out.write(modifyFunctionElement % (methodSignature(name, v, options), inject)) #if v["Param1Type"] == "string": # out.write("<string-xml>" + name + "</string-xml>\n") def doubleBackSlashes(s): # Quote backslashes so qmake does not produce warnings return s.replace("\\", "\\\\") class SepBuilder: def __init__(self): # Discover configuration parameters self.ScintillaEditIncludes = [".", "../ScintillaEdit", "../ScintillaEditBase", "../../include"] if PLAT_WINDOWS: self.MakeCommand = "nmake" self.MakeTarget = "release" else: self.MakeCommand = "make" self.MakeTarget = "" if PLAT_DARWIN: self.QMakeOptions = "-spec macx-g++" else: self.QMakeOptions = "" # Default to debug build if running in a debug build interpreter self.DebugBuild = hasattr(sys, 'getobjects') # Python self.PyVersion = "%d.%d" % sys.version_info[:2] self.PyVersionSuffix = distutils.sysconfig.get_config_var("VERSION") self.PyIncludes = distutils.sysconfig.get_python_inc() self.PyPrefix = distutils.sysconfig.get_config_var("prefix") self.PyLibDir = distutils.sysconfig.get_config_var( ("LIBDEST" if sys.platform == 'win32' else "LIBDIR")) # Scintilla with open("../../version.txt") as f: version = f.read() self.ScintillaVersion = version[0] + '.' + version[1] + '.' + version[2] # Find out what qmake is called self.QMakeCommand = "qmake" if not PLAT_WINDOWS: # On Unix qmake may not be present but qmake-qt4 may be so check pathToQMake = textFromRun("which qmake-qt4 || which qmake").rstrip() self.QMakeCommand = os.path.basename(pathToQMake) # Qt default location from qmake self._SetQtIncludeBase(textFromRun(self.QMakeCommand + " -query QT_INSTALL_HEADERS").rstrip()) # PySide default location # No standard for installing PySide development headers and libs on Windows so # choose /usr to be like Linux self._setPySideBase('\\usr' if PLAT_WINDOWS else '/usr') self.ProInclude = "sepbuild.pri" self.qtStyleInterface = True def _setPySideBase(self, base): self.PySideBase = base if PLAT_LINUX: self.PySideTypeSystem = textFromRun("pkg-config --variable=typesystemdir pyside").rstrip() self.PySideIncludeBase = textFromRun("pkg-config --variable=includedir pyside").rstrip() self.ShibokenIncludeBase = textFromRun("pkg-config --variable=includedir shiboken").rstrip() else: self.PySideTypeSystem = os.path.join(self.PySideBase, "share", "PySide", "typesystems") self.ShibokenIncludeBase = os.path.join(self.PySideBase, "include", "shiboken") self.PySideIncludeBase = os.path.join(self.PySideBase, "include", "PySide") self.PySideIncludes = [ self.ShibokenIncludeBase, self.PySideIncludeBase, os.path.join(self.PySideIncludeBase, "QtCore"), os.path.join(self.PySideIncludeBase, "QtGui")] self.PySideLibDir = os.path.join(self.PySideBase, "lib") self.AllIncludes = os.pathsep.join(self.QtIncludes + self.ScintillaEditIncludes + self.PySideIncludes) self.ShibokenGenerator = "shiboken" # Is this still needed? It doesn't work with latest shiboken sources #if PLAT_DARWIN: # # On OS X, can not automatically find Shiboken dylib so provide a full path # self.ShibokenGenerator = os.path.join(self.PySideLibDir, "generatorrunner", "shiboken") def generateAPI(self, args): os.chdir(os.path.join("..", "ScintillaEdit")) if not self.qtStyleInterface: args.insert(0, '--underscore-names') WidgetGen.main(args) f = WidgetGen.readInterface(False) os.chdir(os.path.join("..", "ScintillaEditPy")) options = {"qtStyle": self.qtStyleInterface} WidgetGen.Generate("typesystem_ScintillaEdit.xml.template", "typesystem_ScintillaEdit.xml", printTypeSystemFile, f, options) def runGenerator(self): generatorrunner = "shiboken" for name in ('shiboken', 'generatorrunner'): if PLAT_WINDOWS: name += '.exe' name = os.path.join(self.PySideBase, "bin", name) if os.path.exists(name): generatorrunner = name break args = [ generatorrunner, "--generator-set=" + self.ShibokenGenerator, "global.h ", "--avoid-protected-hack", "--enable-pyside-extensions", "--include-paths=" + self.AllIncludes, "--typesystem-paths=" + self.PySideTypeSystem, "--output-directory=.", "typesystem_ScintillaEdit.xml"] print(" ".join(args)) retcode = subprocess.call(" ".join(args), shell=True, stderr=subprocess.STDOUT) if retcode: print("Failed in generatorrunner", retcode) sys.exit() def writeVariables(self): # Write variables needed into file to be included from project so it does not have to discover much with open(self.ProInclude, "w") as f: f.write("SCINTILLA_VERSION=" + self.ScintillaVersion + "\n") f.write("PY_VERSION=" + self.PyVersion + "\n") f.write("PY_VERSION_SUFFIX=" + self.PyVersionSuffix + "\n") f.write("PY_PREFIX=" + doubleBackSlashes(self.PyPrefix) + "\n") f.write("PY_INCLUDES=" + doubleBackSlashes(self.PyIncludes) + "\n") f.write("PY_LIBDIR=" + doubleBackSlashes(self.PyLibDir) + "\n") f.write("PYSIDE_INCLUDES=" + doubleBackSlashes(self.PySideIncludeBase) + "\n") f.write("PYSIDE_LIB=" + doubleBackSlashes(self.PySideLibDir) + "\n") f.write("SHIBOKEN_INCLUDES=" + doubleBackSlashes(self.ShibokenIncludeBase) + "\n") if self.DebugBuild: f.write("CONFIG += debug\n") else: f.write("CONFIG += release\n") def make(self): runProgram([self.QMakeCommand, self.QMakeOptions], exitOnFailure=True) runProgram([self.MakeCommand, self.MakeTarget], exitOnFailure=True) def cleanEverything(self): self.generateAPI(["--clean"]) runProgram([self.MakeCommand, "distclean"], exitOnFailure=False) filesToRemove = [self.ProInclude, "typesystem_ScintillaEdit.xml", "../../bin/ScintillaEditPy.so", "../../bin/ScintillaConstants.py"] for file in filesToRemove: try: os.remove(file) except OSError: pass for logFile in glob.glob("*.log"): try: os.remove(logFile) except OSError: pass shutil.rmtree("debug", ignore_errors=True) shutil.rmtree("release", ignore_errors=True) shutil.rmtree("ScintillaEditPy", ignore_errors=True) def buildEverything(self): cleanGenerated = False opts, args = getopt.getopt(sys.argv[1:], "hcdub", ["help", "clean", "debug=", "underscore-names", "pyside-base="]) for opt, arg in opts: if opt in ("-h", "--help"): usage() sys.exit() elif opt in ("-c", "--clean"): cleanGenerated = True elif opt in ("-d", "--debug"): self.DebugBuild = (arg == '' or arg.lower() == 'yes') if self.DebugBuild and sys.platform == 'win32': self.MakeTarget = 'debug' elif opt in ("-b", '--pyside-base'): self._SetQtIncludeBase(os.path.join(os.path.normpath(arg), 'include')) self._setPySideBase(os.path.normpath(arg)) elif opt in ("-u", "--underscore-names"): self.qtStyleInterface = False if cleanGenerated: self.cleanEverything() else: self.writeVariables() self.generateAPI([""]) self.runGenerator() self.make() self.copyScintillaConstants() def copyScintillaConstants(self): orig = 'ScintillaConstants.py' dest = '../../bin/' + orig if IsFileNewer(dest, orig): return f = open(orig, 'r') contents = f.read() f.close() f = open(dest, 'w') f.write(contents) f.close() def _SetQtIncludeBase(self, base): self.QtIncludeBase = base self.QtIncludes = [self.QtIncludeBase] + [os.path.join(self.QtIncludeBase, sub) for sub in ["QtCore", "QtGui"]] # Set path so correct qmake is found path = os.environ.get('PATH', '').split(os.pathsep) qt_bin_dir = os.path.join(os.path.dirname(base), 'bin') if qt_bin_dir not in path: path.insert(0, qt_bin_dir) os.environ['PATH'] = os.pathsep.join(path) if __name__ == "__main__": sepBuild = SepBuilder() sepBuild.buildEverything() |
Added qt/ScintillaEditPy/testsepq.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
#!/usr/bin/python # -*- coding: utf-8 -*- import sys from PySide.QtCore import * from PySide.QtGui import * import ScintillaConstants as sci sys.path.append("../..") from bin import ScintillaEditPy txtInit = "int main(int argc, char **argv) {\n" \ " // Start up the gnome\n" \ " gnome_init(\"stest\", \"1.0\", argc, argv);\n}\n"; keywords = \ "and and_eq asm auto bitand bitor bool break " \ "case catch char class compl const const_cast continue " \ "default delete do double dynamic_cast else enum explicit export extern false float for " \ "friend goto if inline int long mutable namespace new not not_eq " \ "operator or or_eq private protected public " \ "register reinterpret_cast return short signed sizeof static static_cast struct switch " \ "template this throw true try typedef typeid typename union unsigned using " \ "virtual void volatile wchar_t while xor xor_eq"; def uriDropped(): print "uriDropped" class Form(QDialog): def __init__(self, parent=None): super(Form, self).__init__(parent) self.resize(460,300) # Create widgets self.edit = ScintillaEditPy.ScintillaEdit(self) self.edit.uriDropped.connect(uriDropped) self.edit.command.connect(self.receive_command) self.edit.notify.connect(self.receive_notification) self.edit.styleClearAll() self.edit.setMarginWidthN(0, 35) self.edit.setScrollWidth(200) self.edit.setScrollWidthTracking(1) self.edit.setLexer(sci.SCLEX_CPP) self.edit.styleSetFore(sci.SCE_C_COMMENT, 0x008000) self.edit.styleSetFore(sci.SCE_C_COMMENTLINE, 0x008000) self.edit.styleSetFore(sci.SCE_C_COMMENTDOC, 0x008040) self.edit.styleSetItalic(sci.SCE_C_COMMENTDOC, 1) self.edit.styleSetFore(sci.SCE_C_NUMBER, 0x808000) self.edit.styleSetFore(sci.SCE_C_WORD, 0x800000) self.edit.styleSetBold(sci.SCE_C_WORD, True) self.edit.styleSetFore(sci.SCE_C_STRING, 0x800080) self.edit.styleSetFore(sci.SCE_C_PREPROCESSOR, 0x008080) self.edit.styleSetBold(sci.SCE_C_OPERATOR, True) self.edit.setMultipleSelection(1) self.edit.setVirtualSpaceOptions( sci.SCVS_RECTANGULARSELECTION | sci.SCVS_USERACCESSIBLE) self.edit.setAdditionalSelectionTyping(1) self.edit.styleSetFore(sci.STYLE_INDENTGUIDE, 0x808080) self.edit.setIndentationGuides(sci.SC_IV_LOOKBOTH) self.edit.setKeyWords(0, keywords) self.edit.addText(len(txtInit), txtInit) self.edit.setSel(1,10) retriever = str(self.edit.getLine(1)) print(type(retriever), len(retriever)) print('[' + retriever + ']') someText = str(self.edit.textRange(2,5)) print(len(someText), '[' + someText + ']') someText = self.edit.getCurLine(100) print(len(someText), '[' + someText + ']') someText = self.edit.styleFont(1) print(len(someText), '[' + someText + ']') someText = self.edit.getSelText() print(len(someText), '[' + someText + ']') someText = self.edit.tag(1) print(len(someText), '[' + someText + ']') someText = self.edit.autoCCurrentText() print(len(someText), '[' + someText + ']') someText = self.edit.annotationText(1) print(len(someText), '[' + someText + ']') someText = self.edit.annotationStyles(1) print(len(someText), '[' + someText + ']') someText = self.edit.describeKeyWordSets() print(len(someText), '[' + someText + ']') someText = self.edit.propertyNames() print(len(someText), '[' + someText + ']') self.edit.setProperty("fold", "1") someText = self.edit.property("fold") print(len(someText), '[' + someText + ']') someText = self.edit.propertyExpanded("fold") print(len(someText), '[' + someText + ']') someText = self.edit.lexerLanguage() print(len(someText), '[' + someText + ']') someText = self.edit.describeProperty("styling.within.preprocessor") print(len(someText), '[' + someText + ']') xx = self.edit.findText(0, "main", 0, 25) print(type(xx), xx) print("isBold", self.edit.styleBold(sci.SCE_C_WORD)) # Retrieve the document and write into it doc = self.edit.get_doc() doc.insert_string(40, "***") stars = doc.get_char_range(40,3) assert stars == "***" # Create a new independent document and attach it to the editor doc = ScintillaEditPy.ScintillaDocument() doc.insert_string(0, "/***/\nif(a)\n") self.edit.set_doc(doc) self.edit.setLexer(sci.SCLEX_CPP) def Call(self, message, wParam=0, lParam=0): return self.edit.send(message, wParam, lParam) def resizeEvent(self, e): self.edit.resize(e.size().width(), e.size().height()) def receive_command(self, wParam, lParam): # Show underline at start when focussed notifyCode = wParam >> 16 if (notifyCode == sci.SCEN_SETFOCUS) or (notifyCode == sci.SCEN_KILLFOCUS): self.edit.setIndicatorCurrent(sci.INDIC_CONTAINER); self.edit.indicatorClearRange(0, self.edit.length()) if notifyCode == sci.SCEN_SETFOCUS: self.edit.indicatorFillRange(0, 2); def receive_notification(self, scn): if scn.nmhdr.code == sci.SCN_CHARADDED: print "Char %02X" % scn.ch elif scn.nmhdr.code == sci.SCN_SAVEPOINTREACHED: print "Saved" elif scn.nmhdr.code == sci.SCN_SAVEPOINTLEFT: print "Unsaved" elif scn.nmhdr.code == sci.SCN_MODIFIED: print "Modified" elif scn.nmhdr.code == sci.SCN_UPDATEUI: print "Update UI" elif scn.nmhdr.code == sci.SCN_PAINTED: #print "Painted" pass else: print "Notification", scn.nmhdr.code pass if __name__ == '__main__': # Create the Qt Application app = QApplication(sys.argv) # Create and show the form form = Form() form.show() # Run the main Qt loop sys.exit(app.exec_()) |
Added qt/ScintillaEditPy/typesystem_ScintillaEdit.xml.template.
> > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<?xml version="1.0"?> <typesystem package="ScintillaEditPy"> <load-typesystem name="typesystem_core.xml" generate="no" /> <load-typesystem name="typesystem_gui_common.xml" generate="no"/> <primitive-type name="sptr_t"/> <primitive-type name="uptr_t"/> <value-type name="Sci_NotifyHeader" /> <rejection class="Sci_NotifyHeader" field-name="hwndFrom" /> <value-type name="SCNotification" /> <object-type name="ScintillaEditBase" /> <object-type name="ScintillaEdit"> <!-- ++Autogenerated start of section automatically generated from Scintilla.iface --> <!-- ~~Autogenerated end of section automatically generated from Scintilla.iface --> </object-type> <object-type name="ScintillaDocument" /> </typesystem> |
Added src/AutoComplete.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
// Scintilla source code edit control /** @file AutoComplete.cxx ** Defines the auto completion list box. **/ // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <assert.h> #include <string> #include "Platform.h" #include "CharacterSet.h" #include "AutoComplete.h" #include "Scintilla.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif AutoComplete::AutoComplete() : active(false), separator(' '), typesep('?'), ignoreCase(false), chooseSingle(false), lb(0), posStart(0), startLen(0), cancelAtStartPos(true), autoHide(true), dropRestOfWord(false), ignoreCaseBehaviour(SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE), widthLBDefault(100), heightLBDefault(100) { lb = ListBox::Allocate(); stopChars[0] = '\0'; fillUpChars[0] = '\0'; } AutoComplete::~AutoComplete() { if (lb) { lb->Destroy(); delete lb; lb = 0; } } bool AutoComplete::Active() const { return active; } void AutoComplete::Start(Window &parent, int ctrlID, int position, Point location, int startLen_, int lineHeight, bool unicodeMode, int technology) { if (active) { Cancel(); } lb->Create(parent, ctrlID, location, lineHeight, unicodeMode, technology); lb->Clear(); active = true; startLen = startLen_; posStart = position; } void AutoComplete::SetStopChars(const char *stopChars_) { strncpy(stopChars, stopChars_, sizeof(stopChars)); stopChars[sizeof(stopChars) - 1] = '\0'; } bool AutoComplete::IsStopChar(char ch) { return ch && strchr(stopChars, ch); } void AutoComplete::SetFillUpChars(const char *fillUpChars_) { strncpy(fillUpChars, fillUpChars_, sizeof(fillUpChars)); fillUpChars[sizeof(fillUpChars) - 1] = '\0'; } bool AutoComplete::IsFillUpChar(char ch) { return ch && strchr(fillUpChars, ch); } void AutoComplete::SetSeparator(char separator_) { separator = separator_; } char AutoComplete::GetSeparator() const { return separator; } void AutoComplete::SetTypesep(char separator_) { typesep = separator_; } char AutoComplete::GetTypesep() const { return typesep; } void AutoComplete::SetList(const char *list) { lb->SetList(list, separator, typesep); } int AutoComplete::GetSelection() const { return lb->GetSelection(); } std::string AutoComplete::GetValue(int item) const { char value[maxItemLen]; lb->GetValue(item, value, sizeof(value)); return std::string(value); } void AutoComplete::Show(bool show) { lb->Show(show); if (show) lb->Select(0); } void AutoComplete::Cancel() { if (lb->Created()) { lb->Clear(); lb->Destroy(); active = false; } } void AutoComplete::Move(int delta) { int count = lb->Length(); int current = lb->GetSelection(); current += delta; if (current >= count) current = count - 1; if (current < 0) current = 0; lb->Select(current); } void AutoComplete::Select(const char *word) { size_t lenWord = strlen(word); int location = -1; int start = 0; // lower bound of the api array block to search int end = lb->Length() - 1; // upper bound of the api array block to search while ((start <= end) && (location == -1)) { // Binary searching loop int pivot = (start + end) / 2; char item[maxItemLen]; lb->GetValue(pivot, item, maxItemLen); int cond; if (ignoreCase) cond = CompareNCaseInsensitive(word, item, lenWord); else cond = strncmp(word, item, lenWord); if (!cond) { // Find first match while (pivot > start) { lb->GetValue(pivot-1, item, maxItemLen); if (ignoreCase) cond = CompareNCaseInsensitive(word, item, lenWord); else cond = strncmp(word, item, lenWord); if (0 != cond) break; --pivot; } location = pivot; if (ignoreCase && ignoreCaseBehaviour == SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE) { // Check for exact-case match for (; pivot <= end; pivot++) { lb->GetValue(pivot, item, maxItemLen); if (!strncmp(word, item, lenWord)) { location = pivot; break; } if (CompareNCaseInsensitive(word, item, lenWord)) break; } } } else if (cond < 0) { end = pivot - 1; } else if (cond > 0) { start = pivot + 1; } } if (location == -1 && autoHide) Cancel(); else lb->Select(location); } |
Added src/AutoComplete.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
// Scintilla source code edit control /** @file AutoComplete.h ** Defines the auto completion list box. **/ // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef AUTOCOMPLETE_H #define AUTOCOMPLETE_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif /** */ class AutoComplete { bool active; char stopChars[256]; char fillUpChars[256]; char separator; char typesep; // Type seperator enum { maxItemLen=1000 }; public: bool ignoreCase; bool chooseSingle; ListBox *lb; int posStart; int startLen; /// Should autocompletion be canceled if editor's currentPos <= startPos? bool cancelAtStartPos; bool autoHide; bool dropRestOfWord; unsigned int ignoreCaseBehaviour; int widthLBDefault; int heightLBDefault; AutoComplete(); ~AutoComplete(); /// Is the auto completion list displayed? bool Active() const; /// Display the auto completion list positioned to be near a character position void Start(Window &parent, int ctrlID, int position, Point location, int startLen_, int lineHeight, bool unicodeMode, int technology); /// The stop chars are characters which, when typed, cause the auto completion list to disappear void SetStopChars(const char *stopChars_); bool IsStopChar(char ch); /// The fillup chars are characters which, when typed, fill up the selected word void SetFillUpChars(const char *fillUpChars_); bool IsFillUpChar(char ch); /// The separator character is used when interpreting the list in SetList void SetSeparator(char separator_); char GetSeparator() const; /// The typesep character is used for seperating the word from the type void SetTypesep(char separator_); char GetTypesep() const; /// The list string contains a sequence of words separated by the separator character void SetList(const char *list); /// Return the position of the currently selected list item int GetSelection() const; /// Return the value of an item in the list std::string GetValue(int item) const; void Show(bool show); void Cancel(); /// Move the current list element by delta, scrolling appropriately void Move(int delta); /// Select a list element that starts with word as the current element void Select(const char *word); }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/CallTip.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 |
// Scintilla source code edit control /** @file CallTip.cxx ** Code for displaying call tips. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include "Platform.h" #include "Scintilla.h" #include "CallTip.h" #include <stdio.h> #ifdef SCI_NAMESPACE using namespace Scintilla; #endif CallTip::CallTip() { wCallTip = 0; inCallTipMode = false; posStartCallTip = 0; val = 0; rectUp = PRectangle(0,0,0,0); rectDown = PRectangle(0,0,0,0); lineHeight = 1; offsetMain = 0; startHighlight = 0; endHighlight = 0; tabSize = 0; above = false; useStyleCallTip = false; // for backwards compatibility insetX = 5; widthArrow = 14; borderHeight = 2; // Extra line for border and an empty line at top and bottom. verticalOffset = 1; #ifdef __APPLE__ // proper apple colours for the default colourBG = ColourDesired(0xff, 0xff, 0xc6); colourUnSel = ColourDesired(0, 0, 0); #else colourBG = ColourDesired(0xff, 0xff, 0xff); colourUnSel = ColourDesired(0x80, 0x80, 0x80); #endif colourSel = ColourDesired(0, 0, 0x80); colourShade = ColourDesired(0, 0, 0); colourLight = ColourDesired(0xc0, 0xc0, 0xc0); codePage = 0; clickPlace = 0; } CallTip::~CallTip() { font.Release(); wCallTip.Destroy(); delete []val; val = 0; } // Although this test includes 0, we should never see a \0 character. static bool IsArrowCharacter(char ch) { return (ch == 0) || (ch == '\001') || (ch == '\002'); } // We ignore tabs unless a tab width has been set. bool CallTip::IsTabCharacter(char ch) const { return (tabSize > 0) && (ch == '\t'); } int CallTip::NextTabPos(int x) { if (tabSize > 0) { // paranoia... not called unless this is true x -= insetX; // position relative to text x = (x + tabSize) / tabSize; // tab "number" return tabSize*x + insetX; // position of next tab } else { return x + 1; // arbitrary } } // Draw a section of the call tip that does not include \n in one colour. // The text may include up to numEnds tabs or arrow characters. void CallTip::DrawChunk(Surface *surface, int &x, const char *s, int posStart, int posEnd, int ytext, PRectangle rcClient, bool highlight, bool draw) { s += posStart; int len = posEnd - posStart; // Divide the text into sections that are all text, or that are // single arrows or single tab characters (if tabSize > 0). int maxEnd = 0; const int numEnds = 10; int ends[numEnds + 2]; for (int i=0; i<len; i++) { if ((maxEnd < numEnds) && (IsArrowCharacter(s[i]) || IsTabCharacter(s[i]))) { if (i > 0) ends[maxEnd++] = i; ends[maxEnd++] = i+1; } } ends[maxEnd++] = len; int startSeg = 0; int xEnd; for (int seg = 0; seg<maxEnd; seg++) { int endSeg = ends[seg]; if (endSeg > startSeg) { if (IsArrowCharacter(s[startSeg])) { bool upArrow = s[startSeg] == '\001'; rcClient.left = x; rcClient.right = rcClient.left + widthArrow; if (draw) { const int halfWidth = widthArrow / 2 - 3; const int centreX = rcClient.left + widthArrow / 2 - 1; const int centreY = (rcClient.top + rcClient.bottom) / 2; surface->FillRectangle(rcClient, colourBG); PRectangle rcClientInner(rcClient.left + 1, rcClient.top + 1, rcClient.right - 2, rcClient.bottom - 1); surface->FillRectangle(rcClientInner, colourUnSel); if (upArrow) { // Up arrow Point pts[] = { Point(centreX - halfWidth, centreY + halfWidth / 2), Point(centreX + halfWidth, centreY + halfWidth / 2), Point(centreX, centreY - halfWidth + halfWidth / 2), }; surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), colourBG, colourBG); } else { // Down arrow Point pts[] = { Point(centreX - halfWidth, centreY - halfWidth / 2), Point(centreX + halfWidth, centreY - halfWidth / 2), Point(centreX, centreY + halfWidth - halfWidth / 2), }; surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), colourBG, colourBG); } } xEnd = rcClient.right; offsetMain = xEnd; if (upArrow) { rectUp = rcClient; } else { rectDown = rcClient; } } else if (IsTabCharacter(s[startSeg])) { xEnd = NextTabPos(x); } else { xEnd = x + surface->WidthText(font, s + startSeg, endSeg - startSeg); if (draw) { rcClient.left = x; rcClient.right = xEnd; surface->DrawTextTransparent(rcClient, font, ytext, s+startSeg, endSeg - startSeg, highlight ? colourSel : colourUnSel); } } x = xEnd; startSeg = endSeg; } } } int CallTip::PaintContents(Surface *surfaceWindow, bool draw) { PRectangle rcClientPos = wCallTip.GetClientPosition(); PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left, rcClientPos.bottom - rcClientPos.top); PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1); // To make a nice small call tip window, it is only sized to fit most normal characters without accents int ascent = surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font); // For each line... // Draw the definition in three parts: before highlight, highlighted, after highlight int ytext = rcClient.top + ascent + 1; rcClient.bottom = ytext + surfaceWindow->Descent(font) + 1; char *chunkVal = val; bool moreChunks = true; int maxWidth = 0; while (moreChunks) { char *chunkEnd = strchr(chunkVal, '\n'); if (chunkEnd == NULL) { chunkEnd = chunkVal + strlen(chunkVal); moreChunks = false; } int chunkOffset = chunkVal - val; int chunkLength = chunkEnd - chunkVal; int chunkEndOffset = chunkOffset + chunkLength; int thisStartHighlight = Platform::Maximum(startHighlight, chunkOffset); thisStartHighlight = Platform::Minimum(thisStartHighlight, chunkEndOffset); thisStartHighlight -= chunkOffset; int thisEndHighlight = Platform::Maximum(endHighlight, chunkOffset); thisEndHighlight = Platform::Minimum(thisEndHighlight, chunkEndOffset); thisEndHighlight -= chunkOffset; rcClient.top = ytext - ascent - 1; int x = insetX; // start each line at this inset DrawChunk(surfaceWindow, x, chunkVal, 0, thisStartHighlight, ytext, rcClient, false, draw); DrawChunk(surfaceWindow, x, chunkVal, thisStartHighlight, thisEndHighlight, ytext, rcClient, true, draw); DrawChunk(surfaceWindow, x, chunkVal, thisEndHighlight, chunkLength, ytext, rcClient, false, draw); chunkVal = chunkEnd + 1; ytext += lineHeight; rcClient.bottom += lineHeight; maxWidth = Platform::Maximum(maxWidth, x); } return maxWidth; } void CallTip::PaintCT(Surface *surfaceWindow) { if (!val) return; PRectangle rcClientPos = wCallTip.GetClientPosition(); PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left, rcClientPos.bottom - rcClientPos.top); PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1); surfaceWindow->FillRectangle(rcClient, colourBG); offsetMain = insetX; // initial alignment assuming no arrows PaintContents(surfaceWindow, true); #ifndef __APPLE__ // OSX doesn't put borders on "help tags" // Draw a raised border around the edges of the window surfaceWindow->MoveTo(0, rcClientSize.bottom - 1); surfaceWindow->PenColour(colourShade); surfaceWindow->LineTo(rcClientSize.right - 1, rcClientSize.bottom - 1); surfaceWindow->LineTo(rcClientSize.right - 1, 0); surfaceWindow->PenColour(colourLight); surfaceWindow->LineTo(0, 0); surfaceWindow->LineTo(0, rcClientSize.bottom - 1); #endif } void CallTip::MouseClick(Point pt) { clickPlace = 0; if (rectUp.Contains(pt)) clickPlace = 1; if (rectDown.Contains(pt)) clickPlace = 2; } PRectangle CallTip::CallTipStart(int pos, Point pt, int textHeight, const char *defn, const char *faceName, int size, int codePage_, int characterSet, int technology, Window &wParent) { clickPlace = 0; delete []val; val = 0; val = new char[strlen(defn) + 1]; strcpy(val, defn); codePage = codePage_; Surface *surfaceMeasure = Surface::Allocate(technology); if (!surfaceMeasure) return PRectangle(); surfaceMeasure->Init(wParent.GetID()); surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == codePage); surfaceMeasure->SetDBCSMode(codePage); startHighlight = 0; endHighlight = 0; inCallTipMode = true; posStartCallTip = pos; int deviceHeight = surfaceMeasure->DeviceHeightFont(size); FontParameters fp(faceName, deviceHeight / SC_FONT_SIZE_MULTIPLIER, SC_WEIGHT_NORMAL, false, 0, technology, characterSet); font.Create(fp); // Look for multiple lines in the text // Only support \n here - simply means container must avoid \r! int numLines = 1; const char *newline; const char *look = val; rectUp = PRectangle(0,0,0,0); rectDown = PRectangle(0,0,0,0); offsetMain = insetX; // changed to right edge of any arrows int width = PaintContents(surfaceMeasure, false) + insetX; while ((newline = strchr(look, '\n')) != NULL) { look = newline + 1; numLines++; } lineHeight = surfaceMeasure->Height(font); // The returned // rectangle is aligned to the right edge of the last arrow encountered in // the tip text, else to the tip text left edge. int height = lineHeight * numLines - surfaceMeasure->InternalLeading(font) + borderHeight * 2; delete surfaceMeasure; if (above) { return PRectangle(pt.x - offsetMain, pt.y - verticalOffset - height, pt.x + width - offsetMain, pt.y - verticalOffset); } else { return PRectangle(pt.x - offsetMain, pt.y + verticalOffset + textHeight, pt.x + width - offsetMain, pt.y + verticalOffset + textHeight + height); } } void CallTip::CallTipCancel() { inCallTipMode = false; if (wCallTip.Created()) { wCallTip.Destroy(); } } void CallTip::SetHighlight(int start, int end) { // Avoid flashing by checking something has really changed if ((start != startHighlight) || (end != endHighlight)) { startHighlight = start; endHighlight = (end > start) ? end : start; if (wCallTip.Created()) { wCallTip.InvalidateAll(); } } } // Set the tab size (sizes > 0 enable the use of tabs). This also enables the // use of the STYLE_CALLTIP. void CallTip::SetTabSize(int tabSz) { tabSize = tabSz; useStyleCallTip = true; } // Set the calltip position, below the text by default or if above is false // else above the text. void CallTip::SetPosition(bool aboveText) { above = aboveText; } // It might be better to have two access functions for this and to use // them for all settings of colours. void CallTip::SetForeBack(const ColourDesired &fore, const ColourDesired &back) { colourBG = back; colourUnSel = fore; } |
Added src/CallTip.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
// Scintilla source code edit control /** @file CallTip.h ** Interface to the call tip control. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef CALLTIP_H #define CALLTIP_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif /** */ class CallTip { int startHighlight; // character offset to start and... int endHighlight; // ...end of highlighted text char *val; Font font; PRectangle rectUp; // rectangle of last up angle in the tip PRectangle rectDown; // rectangle of last down arrow in the tip int lineHeight; // vertical line spacing int offsetMain; // The alignment point of the call tip int tabSize; // Tab size in pixels, <=0 no TAB expand bool useStyleCallTip; // if true, STYLE_CALLTIP should be used bool above; // if true, display calltip above text // Private so CallTip objects can not be copied CallTip(const CallTip &); CallTip &operator=(const CallTip &); void DrawChunk(Surface *surface, int &x, const char *s, int posStart, int posEnd, int ytext, PRectangle rcClient, bool highlight, bool draw); int PaintContents(Surface *surfaceWindow, bool draw); bool IsTabCharacter(char c) const; int NextTabPos(int x); public: Window wCallTip; Window wDraw; bool inCallTipMode; int posStartCallTip; ColourDesired colourBG; ColourDesired colourUnSel; ColourDesired colourSel; ColourDesired colourShade; ColourDesired colourLight; int codePage; int clickPlace; int insetX; // text inset in x from calltip border int widthArrow; int borderHeight; int verticalOffset; // pixel offset up or down of the calltip with respect to the line CallTip(); ~CallTip(); void PaintCT(Surface *surfaceWindow); void MouseClick(Point pt); /// Setup the calltip and return a rectangle of the area required. PRectangle CallTipStart(int pos, Point pt, int textHeight, const char *defn, const char *faceName, int size, int codePage_, int characterSet, int technology, Window &wParent); void CallTipCancel(); /// Set a range of characters to be displayed in a highlight style. /// Commonly used to highlight the current parameter. void SetHighlight(int start, int end); /// Set the tab size in pixels for the call tip. 0 or -ve means no tab expand. void SetTabSize(int tabSz); /// Set calltip position. void SetPosition(bool aboveText); /// Used to determine which STYLE_xxxx to use for call tip information bool UseStyleCallTip() const { return useStyleCallTip;} // Modify foreground and background colours void SetForeBack(const ColourDesired &fore, const ColourDesired &back); }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/Catalogue.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
// Scintilla source code edit control /** @file KeyWords.cxx ** Colourise for particular languages. **/ // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <vector> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "LexerModule.h" #include "Catalogue.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static std::vector<LexerModule *> lexerCatalogue; static int nextLanguage = SCLEX_AUTOMATIC+1; const LexerModule *Catalogue::Find(int language) { Scintilla_LinkLexers(); for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin(); it != lexerCatalogue.end(); ++it) { if ((*it)->GetLanguage() == language) { return *it; } } return 0; } const LexerModule *Catalogue::Find(const char *languageName) { Scintilla_LinkLexers(); if (languageName) { for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin(); it != lexerCatalogue.end(); ++it) { if ((*it)->languageName && (0 == strcmp((*it)->languageName, languageName))) { return *it; } } } return 0; } void Catalogue::AddLexerModule(LexerModule *plm) { if (plm->GetLanguage() == SCLEX_AUTOMATIC) { plm->language = nextLanguage; nextLanguage++; } lexerCatalogue.push_back(plm); } // Alternative historical name for Scintilla_LinkLexers int wxForceScintillaLexers(void) { return Scintilla_LinkLexers(); } // To add or remove a lexer, add or remove its file and run LexGen.py. // Force a reference to all of the Scintilla lexers so that the linker will // not remove the code of the lexers. int Scintilla_LinkLexers() { static int initialised = 0; if (initialised) return 0; initialised = 1; // Shorten the code that declares a lexer and ensures it is linked in by calling a method. #define LINK_LEXER(lexer) extern LexerModule lexer; Catalogue::AddLexerModule(&lexer); //++Autogenerated -- run src/LexGen.py to regenerate //**\(\tLINK_LEXER(\*);\n\) LINK_LEXER(lmA68k); LINK_LEXER(lmAbaqus); LINK_LEXER(lmAda); LINK_LEXER(lmAns1); LINK_LEXER(lmAPDL); LINK_LEXER(lmAsm); LINK_LEXER(lmASY); LINK_LEXER(lmAU3); LINK_LEXER(lmAVE); LINK_LEXER(lmAVS); LINK_LEXER(lmBaan); LINK_LEXER(lmBash); LINK_LEXER(lmBatch); LINK_LEXER(lmBlitzBasic); LINK_LEXER(lmBullant); LINK_LEXER(lmCaml); LINK_LEXER(lmClw); LINK_LEXER(lmClwNoCase); LINK_LEXER(lmCmake); LINK_LEXER(lmCOBOL); LINK_LEXER(lmCoffeeScript); LINK_LEXER(lmConf); LINK_LEXER(lmCPP); LINK_LEXER(lmCPPNoCase); LINK_LEXER(lmCsound); LINK_LEXER(lmCss); LINK_LEXER(lmD); LINK_LEXER(lmDiff); LINK_LEXER(lmECL); LINK_LEXER(lmEiffel); LINK_LEXER(lmEiffelkw); LINK_LEXER(lmErlang); LINK_LEXER(lmErrorList); LINK_LEXER(lmESCRIPT); LINK_LEXER(lmF77); LINK_LEXER(lmFlagShip); LINK_LEXER(lmForth); LINK_LEXER(lmFortran); LINK_LEXER(lmFreeBasic); LINK_LEXER(lmGAP); LINK_LEXER(lmGui4Cli); LINK_LEXER(lmHaskell); LINK_LEXER(lmHTML); LINK_LEXER(lmInno); LINK_LEXER(lmKix); LINK_LEXER(lmLatex); LINK_LEXER(lmLISP); LINK_LEXER(lmLot); LINK_LEXER(lmLout); LINK_LEXER(lmLua); LINK_LEXER(lmMagikSF); LINK_LEXER(lmMake); LINK_LEXER(lmMarkdown); LINK_LEXER(lmMatlab); LINK_LEXER(lmMETAPOST); LINK_LEXER(lmMMIXAL); LINK_LEXER(lmModula); LINK_LEXER(lmMSSQL); LINK_LEXER(lmMySQL); LINK_LEXER(lmNimrod); LINK_LEXER(lmNncrontab); LINK_LEXER(lmNsis); LINK_LEXER(lmNull); LINK_LEXER(lmOctave); LINK_LEXER(lmOpal); LINK_LEXER(lmOScript); LINK_LEXER(lmPascal); LINK_LEXER(lmPB); LINK_LEXER(lmPerl); LINK_LEXER(lmPHPSCRIPT); LINK_LEXER(lmPLM); LINK_LEXER(lmPO); LINK_LEXER(lmPOV); LINK_LEXER(lmPowerPro); LINK_LEXER(lmPowerShell); LINK_LEXER(lmProgress); LINK_LEXER(lmProps); LINK_LEXER(lmPS); LINK_LEXER(lmPureBasic); LINK_LEXER(lmPython); LINK_LEXER(lmR); LINK_LEXER(lmREBOL); LINK_LEXER(lmRuby); LINK_LEXER(lmScriptol); LINK_LEXER(lmSmalltalk); LINK_LEXER(lmSML); LINK_LEXER(lmSorc); LINK_LEXER(lmSpecman); LINK_LEXER(lmSpice); LINK_LEXER(lmSQL); LINK_LEXER(lmTACL); LINK_LEXER(lmTADS3); LINK_LEXER(lmTAL); LINK_LEXER(lmTCL); LINK_LEXER(lmTCMD); LINK_LEXER(lmTeX); LINK_LEXER(lmTxt2tags); LINK_LEXER(lmVB); LINK_LEXER(lmVBScript); LINK_LEXER(lmVerilog); LINK_LEXER(lmVHDL); LINK_LEXER(lmVisualProlog); LINK_LEXER(lmXML); LINK_LEXER(lmYAML); //--Autogenerated -- end of automatically generated section return 1; } |
Added src/Catalogue.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// Scintilla source code edit control /** @file Catalogue.h ** Lexer infrastructure. **/ // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef CATALOGUE_H #define CATALOGUE_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif class Catalogue { public: static const LexerModule *Find(int language); static const LexerModule *Find(const char *languageName); static void AddLexerModule(LexerModule *plm); }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/CellBuffer.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 |
// Scintilla source code edit control /** @file CellBuffer.cxx ** Manages a buffer of cells. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdio.h> #include <string.h> #include <stdlib.h> #include <stdarg.h> #include "Platform.h" #include "Scintilla.h" #include "SplitVector.h" #include "Partitioning.h" #include "CellBuffer.h" #include "UniConversion.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif LineVector::LineVector() : starts(256), perLine(0) { Init(); } LineVector::~LineVector() { starts.DeleteAll(); } void LineVector::Init() { starts.DeleteAll(); if (perLine) { perLine->Init(); } } void LineVector::SetPerLine(PerLine *pl) { perLine = pl; } void LineVector::InsertText(int line, int delta) { starts.InsertText(line, delta); } void LineVector::InsertLine(int line, int position, bool lineStart) { starts.InsertPartition(line, position); if (perLine) { if ((line > 0) && lineStart) line--; perLine->InsertLine(line); } } void LineVector::SetLineStart(int line, int position) { starts.SetPartitionStartPosition(line, position); } void LineVector::RemoveLine(int line) { starts.RemovePartition(line); if (perLine) { perLine->RemoveLine(line); } } int LineVector::LineFromPosition(int pos) const { return starts.PartitionFromPosition(pos); } Action::Action() { at = startAction; position = 0; data = 0; lenData = 0; mayCoalesce = false; } Action::~Action() { Destroy(); } void Action::Create(actionType at_, int position_, char *data_, int lenData_, bool mayCoalesce_) { delete []data; position = position_; at = at_; data = data_; lenData = lenData_; mayCoalesce = mayCoalesce_; } void Action::Destroy() { delete []data; data = 0; } void Action::Grab(Action *source) { delete []data; position = source->position; at = source->at; data = source->data; lenData = source->lenData; mayCoalesce = source->mayCoalesce; // Ownership of source data transferred to this source->position = 0; source->at = startAction; source->data = 0; source->lenData = 0; source->mayCoalesce = true; } // The undo history stores a sequence of user operations that represent the user's view of the // commands executed on the text. // Each user operation contains a sequence of text insertion and text deletion actions. // All the user operations are stored in a list of individual actions with 'start' actions used // as delimiters between user operations. // Initially there is one start action in the history. // As each action is performed, it is recorded in the history. The action may either become // part of the current user operation or may start a new user operation. If it is to be part of the // current operation, then it overwrites the current last action. If it is to be part of a new // operation, it is appended after the current last action. // After writing the new action, a new start action is appended at the end of the history. // The decision of whether to start a new user operation is based upon two factors. If a // compound operation has been explicitly started by calling BeginUndoAction and no matching // EndUndoAction (these calls nest) has been called, then the action is coalesced into the current // operation. If there is no outstanding BeginUndoAction call then a new operation is started // unless it looks as if the new action is caused by the user typing or deleting a stream of text. // Sequences that look like typing or deletion are coalesced into a single user operation. UndoHistory::UndoHistory() { lenActions = 100; actions = new Action[lenActions]; maxAction = 0; currentAction = 0; undoSequenceDepth = 0; savePoint = 0; actions[currentAction].Create(startAction); } UndoHistory::~UndoHistory() { delete []actions; actions = 0; } void UndoHistory::EnsureUndoRoom() { // Have to test that there is room for 2 more actions in the array // as two actions may be created by the calling function if (currentAction >= (lenActions - 2)) { // Run out of undo nodes so extend the array int lenActionsNew = lenActions * 2; Action *actionsNew = new Action[lenActionsNew]; for (int act = 0; act <= currentAction; act++) actionsNew[act].Grab(&actions[act]); delete []actions; lenActions = lenActionsNew; actions = actionsNew; } } void UndoHistory::AppendAction(actionType at, int position, char *data, int lengthData, bool &startSequence, bool mayCoalesce) { EnsureUndoRoom(); //Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, lengthData, currentAction); //Platform::DebugPrintf("^ %d action %d %d\n", actions[currentAction - 1].at, // actions[currentAction - 1].position, actions[currentAction - 1].lenData); if (currentAction < savePoint) { savePoint = -1; } int oldCurrentAction = currentAction; if (currentAction >= 1) { if (0 == undoSequenceDepth) { // Top level actions may not always be coalesced int targetAct = -1; const Action *actPrevious = &(actions[currentAction + targetAct]); // Container actions may forward the coalesce state of Scintilla Actions. while ((actPrevious->at == containerAction) && actPrevious->mayCoalesce) { targetAct--; actPrevious = &(actions[currentAction + targetAct]); } // See if current action can be coalesced into previous action // Will work if both are inserts or deletes and position is same if (currentAction == savePoint) { currentAction++; } else if (!actions[currentAction].mayCoalesce) { // Not allowed to coalesce if this set currentAction++; } else if (!mayCoalesce || !actPrevious->mayCoalesce) { currentAction++; } else if (at == containerAction || actions[currentAction].at == containerAction) { ; // A coalescible containerAction } else if ((at != actPrevious->at) && (actPrevious->at != startAction)) { currentAction++; } else if ((at == insertAction) && (position != (actPrevious->position + actPrevious->lenData))) { // Insertions must be immediately after to coalesce currentAction++; } else if (at == removeAction) { if ((lengthData == 1) || (lengthData == 2)) { if ((position + lengthData) == actPrevious->position) { ; // Backspace -> OK } else if (position == actPrevious->position) { ; // Delete -> OK } else { // Removals must be at same position to coalesce currentAction++; } } else { // Removals must be of one character to coalesce currentAction++; } } else { // Action coalesced. } } else { // Actions not at top level are always coalesced unless this is after return to top level if (!actions[currentAction].mayCoalesce) currentAction++; } } else { currentAction++; } startSequence = oldCurrentAction != currentAction; actions[currentAction].Create(at, position, data, lengthData, mayCoalesce); currentAction++; actions[currentAction].Create(startAction); maxAction = currentAction; } void UndoHistory::BeginUndoAction() { EnsureUndoRoom(); if (undoSequenceDepth == 0) { if (actions[currentAction].at != startAction) { currentAction++; actions[currentAction].Create(startAction); maxAction = currentAction; } actions[currentAction].mayCoalesce = false; } undoSequenceDepth++; } void UndoHistory::EndUndoAction() { PLATFORM_ASSERT(undoSequenceDepth > 0); EnsureUndoRoom(); undoSequenceDepth--; if (0 == undoSequenceDepth) { if (actions[currentAction].at != startAction) { currentAction++; actions[currentAction].Create(startAction); maxAction = currentAction; } actions[currentAction].mayCoalesce = false; } } void UndoHistory::DropUndoSequence() { undoSequenceDepth = 0; } void UndoHistory::DeleteUndoHistory() { for (int i = 1; i < maxAction; i++) actions[i].Destroy(); maxAction = 0; currentAction = 0; actions[currentAction].Create(startAction); savePoint = 0; } void UndoHistory::SetSavePoint() { savePoint = currentAction; } bool UndoHistory::IsSavePoint() const { return savePoint == currentAction; } bool UndoHistory::CanUndo() const { return (currentAction > 0) && (maxAction > 0); } int UndoHistory::StartUndo() { // Drop any trailing startAction if (actions[currentAction].at == startAction && currentAction > 0) currentAction--; // Count the steps in this action int act = currentAction; while (actions[act].at != startAction && act > 0) { act--; } return currentAction - act; } const Action &UndoHistory::GetUndoStep() const { return actions[currentAction]; } void UndoHistory::CompletedUndoStep() { currentAction--; } bool UndoHistory::CanRedo() const { return maxAction > currentAction; } int UndoHistory::StartRedo() { // Drop any leading startAction if (actions[currentAction].at == startAction && currentAction < maxAction) currentAction++; // Count the steps in this action int act = currentAction; while (actions[act].at != startAction && act < maxAction) { act++; } return act - currentAction; } const Action &UndoHistory::GetRedoStep() const { return actions[currentAction]; } void UndoHistory::CompletedRedoStep() { currentAction++; } CellBuffer::CellBuffer() { readOnly = false; utf8LineEnds = 0; collectingUndo = true; } CellBuffer::~CellBuffer() { } char CellBuffer::CharAt(int position) const { return substance.ValueAt(position); } void CellBuffer::GetCharRange(char *buffer, int position, int lengthRetrieve) const { if (lengthRetrieve < 0) return; if (position < 0) return; if ((position + lengthRetrieve) > substance.Length()) { Platform::DebugPrintf("Bad GetCharRange %d for %d of %d\n", position, lengthRetrieve, substance.Length()); return; } substance.GetRange(buffer, position, lengthRetrieve); } char CellBuffer::StyleAt(int position) const { return style.ValueAt(position); } void CellBuffer::GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const { if (lengthRetrieve < 0) return; if (position < 0) return; if ((position + lengthRetrieve) > style.Length()) { Platform::DebugPrintf("Bad GetStyleRange %d for %d of %d\n", position, lengthRetrieve, style.Length()); return; } style.GetRange(reinterpret_cast<char *>(buffer), position, lengthRetrieve); } const char *CellBuffer::BufferPointer() { return substance.BufferPointer(); } const char *CellBuffer::RangePointer(int position, int rangeLength) { return substance.RangePointer(position, rangeLength); } int CellBuffer::GapPosition() const { return substance.GapPosition(); } // The char* returned is to an allocation owned by the undo history const char *CellBuffer::InsertString(int position, const char *s, int insertLength, bool &startSequence) { char *data = 0; // InsertString and DeleteChars are the bottleneck though which all changes occur if (!readOnly) { if (collectingUndo) { // Save into the undo/redo stack, but only the characters - not the formatting // This takes up about half load time data = new char[insertLength]; for (int i = 0; i < insertLength; i++) { data[i] = s[i]; } uh.AppendAction(insertAction, position, data, insertLength, startSequence); } BasicInsertString(position, s, insertLength); } return data; } bool CellBuffer::SetStyleAt(int position, char styleValue, char mask) { styleValue &= mask; char curVal = style.ValueAt(position); if ((curVal & mask) != styleValue) { style.SetValueAt(position, static_cast<char>((curVal & ~mask) | styleValue)); return true; } else { return false; } } bool CellBuffer::SetStyleFor(int position, int lengthStyle, char styleValue, char mask) { bool changed = false; PLATFORM_ASSERT(lengthStyle == 0 || (lengthStyle > 0 && lengthStyle + position <= style.Length())); while (lengthStyle--) { char curVal = style.ValueAt(position); if ((curVal & mask) != styleValue) { style.SetValueAt(position, static_cast<char>((curVal & ~mask) | styleValue)); changed = true; } position++; } return changed; } // The char* returned is to an allocation owned by the undo history const char *CellBuffer::DeleteChars(int position, int deleteLength, bool &startSequence) { // InsertString and DeleteChars are the bottleneck though which all changes occur PLATFORM_ASSERT(deleteLength > 0); char *data = 0; if (!readOnly) { if (collectingUndo) { // Save into the undo/redo stack, but only the characters - not the formatting data = new char[deleteLength]; for (int i = 0; i < deleteLength; i++) { data[i] = substance.ValueAt(position + i); } uh.AppendAction(removeAction, position, data, deleteLength, startSequence); } BasicDeleteChars(position, deleteLength); } return data; } int CellBuffer::Length() const { return substance.Length(); } void CellBuffer::Allocate(int newSize) { substance.ReAllocate(newSize); style.ReAllocate(newSize); } void CellBuffer::SetLineEndTypes(int utf8LineEnds_) { if (utf8LineEnds != utf8LineEnds_) { utf8LineEnds = utf8LineEnds_; ResetLineEnds(); } } void CellBuffer::SetPerLine(PerLine *pl) { lv.SetPerLine(pl); } int CellBuffer::Lines() const { return lv.Lines(); } int CellBuffer::LineStart(int line) const { if (line < 0) return 0; else if (line >= Lines()) return Length(); else return lv.LineStart(line); } bool CellBuffer::IsReadOnly() const { return readOnly; } void CellBuffer::SetReadOnly(bool set) { readOnly = set; } void CellBuffer::SetSavePoint() { uh.SetSavePoint(); } bool CellBuffer::IsSavePoint() { return uh.IsSavePoint(); } // Without undo void CellBuffer::InsertLine(int line, int position, bool lineStart) { lv.InsertLine(line, position, lineStart); } void CellBuffer::RemoveLine(int line) { lv.RemoveLine(line); } bool CellBuffer::UTF8LineEndOverlaps(int position) const { unsigned char bytes[] = { static_cast<unsigned char>(substance.ValueAt(position-2)), static_cast<unsigned char>(substance.ValueAt(position-1)), static_cast<unsigned char>(substance.ValueAt(position)), static_cast<unsigned char>(substance.ValueAt(position+1)), }; return UTF8IsSeparator(bytes) || UTF8IsSeparator(bytes+1) || UTF8IsNEL(bytes+1); } void CellBuffer::ResetLineEnds() { // Reinitialize line data -- too much work to preserve lv.Init(); int position = 0; int length = Length(); int lineInsert = 1; bool atLineStart = true; lv.InsertText(lineInsert-1, length); unsigned char chBeforePrev = 0; unsigned char chPrev = 0; for (int i = 0; i < length; i++) { unsigned char ch = substance.ValueAt(position + i); if (ch == '\r') { InsertLine(lineInsert, (position + i) + 1, atLineStart); lineInsert++; } else if (ch == '\n') { if (chPrev == '\r') { // Patch up what was end of line lv.SetLineStart(lineInsert - 1, (position + i) + 1); } else { InsertLine(lineInsert, (position + i) + 1, atLineStart); lineInsert++; } } else if (utf8LineEnds) { unsigned char back3[3] = {chBeforePrev, chPrev, ch}; if (UTF8IsSeparator(back3) || UTF8IsNEL(back3+1)) { InsertLine(lineInsert, (position + i) + 1, atLineStart); lineInsert++; } } chBeforePrev = chPrev; chPrev = ch; } } void CellBuffer::BasicInsertString(int position, const char *s, int insertLength) { if (insertLength == 0) return; PLATFORM_ASSERT(insertLength > 0); unsigned char chAfter = substance.ValueAt(position); bool breakingUTF8LineEnd = false; if (utf8LineEnds && UTF8IsTrailByte(chAfter)) { breakingUTF8LineEnd = UTF8LineEndOverlaps(position); } substance.InsertFromArray(position, s, 0, insertLength); style.InsertValue(position, insertLength, 0); int lineInsert = lv.LineFromPosition(position) + 1; bool atLineStart = lv.LineStart(lineInsert-1) == position; // Point all the lines after the insertion point further along in the buffer lv.InsertText(lineInsert-1, insertLength); unsigned char chBeforePrev = substance.ValueAt(position - 2); unsigned char chPrev = substance.ValueAt(position - 1); if (chPrev == '\r' && chAfter == '\n') { // Splitting up a crlf pair at position InsertLine(lineInsert, position, false); lineInsert++; } if (breakingUTF8LineEnd) { RemoveLine(lineInsert); } unsigned char ch = ' '; for (int i = 0; i < insertLength; i++) { ch = s[i]; if (ch == '\r') { InsertLine(lineInsert, (position + i) + 1, atLineStart); lineInsert++; } else if (ch == '\n') { if (chPrev == '\r') { // Patch up what was end of line lv.SetLineStart(lineInsert - 1, (position + i) + 1); } else { InsertLine(lineInsert, (position + i) + 1, atLineStart); lineInsert++; } } else if (utf8LineEnds) { unsigned char back3[3] = {chBeforePrev, chPrev, ch}; if (UTF8IsSeparator(back3) || UTF8IsNEL(back3+1)) { InsertLine(lineInsert, (position + i) + 1, atLineStart); lineInsert++; } } chBeforePrev = chPrev; chPrev = ch; } // Joining two lines where last insertion is cr and following substance starts with lf if (chAfter == '\n') { if (ch == '\r') { // End of line already in buffer so drop the newly created one RemoveLine(lineInsert - 1); } } else if (utf8LineEnds && !UTF8IsAscii(chAfter)) { // May have end of UTF-8 line end in buffer and start in insertion for (int j = 0; j < UTF8SeparatorLength-1; j++) { unsigned char chAt = substance.ValueAt(position + insertLength + j); unsigned char back3[3] = {chBeforePrev, chPrev, chAt}; if (UTF8IsSeparator(back3)) { InsertLine(lineInsert, (position + insertLength + j) + 1, atLineStart); lineInsert++; } if ((j == 0) && UTF8IsNEL(back3+1)) { InsertLine(lineInsert, (position + insertLength + j) + 1, atLineStart); lineInsert++; } chBeforePrev = chPrev; chPrev = chAt; } } } void CellBuffer::BasicDeleteChars(int position, int deleteLength) { if (deleteLength == 0) return; if ((position == 0) && (deleteLength == substance.Length())) { // If whole buffer is being deleted, faster to reinitialise lines data // than to delete each line. lv.Init(); } else { // Have to fix up line positions before doing deletion as looking at text in buffer // to work out which lines have been removed int lineRemove = lv.LineFromPosition(position) + 1; lv.InsertText(lineRemove-1, - (deleteLength)); unsigned char chPrev = substance.ValueAt(position - 1); unsigned char chBefore = chPrev; unsigned char chNext = substance.ValueAt(position); bool ignoreNL = false; if (chPrev == '\r' && chNext == '\n') { // Move back one lv.SetLineStart(lineRemove, position); lineRemove++; ignoreNL = true; // First \n is not real deletion } if (utf8LineEnds && UTF8IsTrailByte(chNext)) { if (UTF8LineEndOverlaps(position)) { RemoveLine(lineRemove); } } unsigned char ch = chNext; for (int i = 0; i < deleteLength; i++) { chNext = substance.ValueAt(position + i + 1); if (ch == '\r') { if (chNext != '\n') { RemoveLine(lineRemove); } } else if (ch == '\n') { if (ignoreNL) { ignoreNL = false; // Further \n are real deletions } else { RemoveLine(lineRemove); } } else if (utf8LineEnds) { if (!UTF8IsAscii(ch)) { unsigned char next3[3] = {ch, chNext, static_cast<unsigned char>(substance.ValueAt(position + i + 2))}; if (UTF8IsSeparator(next3) || UTF8IsNEL(next3)) { RemoveLine(lineRemove); } } } ch = chNext; } // May have to fix up end if last deletion causes cr to be next to lf // or removes one of a crlf pair char chAfter = substance.ValueAt(position + deleteLength); if (chBefore == '\r' && chAfter == '\n') { // Using lineRemove-1 as cr ended line before start of deletion RemoveLine(lineRemove - 1); lv.SetLineStart(lineRemove - 1, position + 1); } } substance.DeleteRange(position, deleteLength); style.DeleteRange(position, deleteLength); } bool CellBuffer::SetUndoCollection(bool collectUndo) { collectingUndo = collectUndo; uh.DropUndoSequence(); return collectingUndo; } bool CellBuffer::IsCollectingUndo() const { return collectingUndo; } void CellBuffer::BeginUndoAction() { uh.BeginUndoAction(); } void CellBuffer::EndUndoAction() { uh.EndUndoAction(); } void CellBuffer::AddUndoAction(int token, bool mayCoalesce) { bool startSequence; uh.AppendAction(containerAction, token, 0, 0, startSequence, mayCoalesce); } void CellBuffer::DeleteUndoHistory() { uh.DeleteUndoHistory(); } bool CellBuffer::CanUndo() { return uh.CanUndo(); } int CellBuffer::StartUndo() { return uh.StartUndo(); } const Action &CellBuffer::GetUndoStep() const { return uh.GetUndoStep(); } void CellBuffer::PerformUndoStep() { const Action &actionStep = uh.GetUndoStep(); if (actionStep.at == insertAction) { BasicDeleteChars(actionStep.position, actionStep.lenData); } else if (actionStep.at == removeAction) { BasicInsertString(actionStep.position, actionStep.data, actionStep.lenData); } uh.CompletedUndoStep(); } bool CellBuffer::CanRedo() { return uh.CanRedo(); } int CellBuffer::StartRedo() { return uh.StartRedo(); } const Action &CellBuffer::GetRedoStep() const { return uh.GetRedoStep(); } void CellBuffer::PerformRedoStep() { const Action &actionStep = uh.GetRedoStep(); if (actionStep.at == insertAction) { BasicInsertString(actionStep.position, actionStep.data, actionStep.lenData); } else if (actionStep.at == removeAction) { BasicDeleteChars(actionStep.position, actionStep.lenData); } uh.CompletedRedoStep(); } |
Added src/CellBuffer.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
// Scintilla source code edit control /** @file CellBuffer.h ** Manages the text of the document. **/ // Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef CELLBUFFER_H #define CELLBUFFER_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif // Interface to per-line data that wants to see each line insertion and deletion class PerLine { public: virtual ~PerLine() {} virtual void Init()=0; virtual void InsertLine(int)=0; virtual void RemoveLine(int)=0; }; /** * The line vector contains information about each of the lines in a cell buffer. */ class LineVector { Partitioning starts; PerLine *perLine; public: LineVector(); ~LineVector(); void Init(); void SetPerLine(PerLine *pl); void InsertText(int line, int delta); void InsertLine(int line, int position, bool lineStart); void SetLineStart(int line, int position); void RemoveLine(int line); int Lines() const { return starts.Partitions(); } int LineFromPosition(int pos) const; int LineStart(int line) const { return starts.PositionFromPartition(line); } int MarkValue(int line); int AddMark(int line, int marker); void MergeMarkers(int pos); void DeleteMark(int line, int markerNum, bool all); void DeleteMarkFromHandle(int markerHandle); int LineFromHandle(int markerHandle); void ClearLevels(); int SetLevel(int line, int level); int GetLevel(int line); int SetLineState(int line, int state); int GetLineState(int line); int GetMaxLineState(); }; enum actionType { insertAction, removeAction, startAction, containerAction }; /** * Actions are used to store all the information required to perform one undo/redo step. */ class Action { public: actionType at; int position; char *data; int lenData; bool mayCoalesce; Action(); ~Action(); void Create(actionType at_, int position_=0, char *data_=0, int lenData_=0, bool mayCoalesce_=true); void Destroy(); void Grab(Action *source); }; /** * */ class UndoHistory { Action *actions; int lenActions; int maxAction; int currentAction; int undoSequenceDepth; int savePoint; void EnsureUndoRoom(); // Private so UndoHistory objects can not be copied UndoHistory(const UndoHistory &); public: UndoHistory(); ~UndoHistory(); void AppendAction(actionType at, int position, char *data, int length, bool &startSequence, bool mayCoalesce=true); void BeginUndoAction(); void EndUndoAction(); void DropUndoSequence(); void DeleteUndoHistory(); /// The save point is a marker in the undo stack where the container has stated that /// the buffer was saved. Undo and redo can move over the save point. void SetSavePoint(); bool IsSavePoint() const; /// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is /// called that many times. Similarly for redo. bool CanUndo() const; int StartUndo(); const Action &GetUndoStep() const; void CompletedUndoStep(); bool CanRedo() const; int StartRedo(); const Action &GetRedoStep() const; void CompletedRedoStep(); }; /** * Holder for an expandable array of characters that supports undo and line markers. * Based on article "Data Structures in a Bit-Mapped Text Editor" * by Wilfred J. Hansen, Byte January 1987, page 183. */ class CellBuffer { private: SplitVector<char> substance; SplitVector<char> style; bool readOnly; int utf8LineEnds; bool collectingUndo; UndoHistory uh; LineVector lv; bool UTF8LineEndOverlaps(int position) const; void ResetLineEnds(); /// Actions without undo void BasicInsertString(int position, const char *s, int insertLength); void BasicDeleteChars(int position, int deleteLength); public: CellBuffer(); ~CellBuffer(); /// Retrieving positions outside the range of the buffer works and returns 0 char CharAt(int position) const; void GetCharRange(char *buffer, int position, int lengthRetrieve) const; char StyleAt(int position) const; void GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const; const char *BufferPointer(); const char *RangePointer(int position, int rangeLength); int GapPosition() const; int Length() const; void Allocate(int newSize); int GetLineEndTypes() const { return utf8LineEnds; } void SetLineEndTypes(int utf8LineEnds_); void SetPerLine(PerLine *pl); int Lines() const; int LineStart(int line) const; int LineFromPosition(int pos) const { return lv.LineFromPosition(pos); } void InsertLine(int line, int position, bool lineStart); void RemoveLine(int line); const char *InsertString(int position, const char *s, int insertLength, bool &startSequence); /// Setting styles for positions outside the range of the buffer is safe and has no effect. /// @return true if the style of a character is changed. bool SetStyleAt(int position, char styleValue, char mask='\377'); bool SetStyleFor(int position, int length, char styleValue, char mask); const char *DeleteChars(int position, int deleteLength, bool &startSequence); bool IsReadOnly() const; void SetReadOnly(bool set); /// The save point is a marker in the undo stack where the container has stated that /// the buffer was saved. Undo and redo can move over the save point. void SetSavePoint(); bool IsSavePoint(); bool SetUndoCollection(bool collectUndo); bool IsCollectingUndo() const; void BeginUndoAction(); void EndUndoAction(); void AddUndoAction(int token, bool mayCoalesce); void DeleteUndoHistory(); /// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is /// called that many times. Similarly for redo. bool CanUndo(); int StartUndo(); const Action &GetUndoStep() const; void PerformUndoStep(); bool CanRedo(); int StartRedo(); const Action &GetRedoStep() const; void PerformRedoStep(); }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/CharClassify.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
// Scintilla source code edit control /** @file CharClassify.cxx ** Character classifications used by Document and RESearch. **/ // Copyright 2006 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <ctype.h> #include "CharClassify.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // Shut up annoying Visual C++ warnings: #ifdef _MSC_VER #pragma warning(disable: 4514) #endif CharClassify::CharClassify() { SetDefaultCharClasses(true); } void CharClassify::SetDefaultCharClasses(bool includeWordClass) { // Initialize all char classes to default values for (int ch = 0; ch < 256; ch++) { if (ch == '\r' || ch == '\n') charClass[ch] = ccNewLine; else if (ch < 0x20 || ch == ' ') charClass[ch] = ccSpace; else if (includeWordClass && (ch >= 0x80 || isalnum(ch) || ch == '_')) charClass[ch] = ccWord; else charClass[ch] = ccPunctuation; } } void CharClassify::SetCharClasses(const unsigned char *chars, cc newCharClass) { // Apply the newCharClass to the specifed chars if (chars) { while (*chars) { charClass[*chars] = static_cast<unsigned char>(newCharClass); chars++; } } } int CharClassify::GetCharsOfClass(cc characterClass, unsigned char *buffer) { // Get characters belonging to the given char class; return the number // of characters (if the buffer is NULL, don't write to it). int count = 0; for (int ch = maxChar - 1; ch >= 0; --ch) { if (charClass[ch] == characterClass) { ++count; if (buffer) { *buffer = static_cast<unsigned char>(ch); buffer++; } } } return count; } |
Added src/CharClassify.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
// Scintilla source code edit control /** @file CharClassify.h ** Character classifications used by Document and RESearch. **/ // Copyright 2006-2009 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef CHARCLASSIFY_H #define CHARCLASSIFY_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif class CharClassify { public: CharClassify(); enum cc { ccSpace, ccNewLine, ccWord, ccPunctuation }; void SetDefaultCharClasses(bool includeWordClass); void SetCharClasses(const unsigned char *chars, cc newCharClass); int GetCharsOfClass(cc charClass, unsigned char *buffer); cc GetClass(unsigned char ch) const { return static_cast<cc>(charClass[ch]);} bool IsWord(unsigned char ch) const { return static_cast<cc>(charClass[ch]) == ccWord;} private: enum { maxChar=256 }; unsigned char charClass[maxChar]; // not type cc to save space }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/ContractionState.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
// Scintilla source code edit control /** @file ContractionState.cxx ** Manages visibility of lines for folding and wrapping. **/ // Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <string.h> #include "Platform.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" #include "ContractionState.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif ContractionState::ContractionState() : visible(0), expanded(0), heights(0), displayLines(0), linesInDocument(1) { //InsertLine(0); } ContractionState::~ContractionState() { Clear(); } void ContractionState::EnsureData() { if (OneToOne()) { visible = new RunStyles(); expanded = new RunStyles(); heights = new RunStyles(); displayLines = new Partitioning(4); InsertLines(0, linesInDocument); } } void ContractionState::Clear() { delete visible; visible = 0; delete expanded; expanded = 0; delete heights; heights = 0; delete displayLines; displayLines = 0; linesInDocument = 1; } int ContractionState::LinesInDoc() const { if (OneToOne()) { return linesInDocument; } else { return displayLines->Partitions() - 1; } } int ContractionState::LinesDisplayed() const { if (OneToOne()) { return linesInDocument; } else { return displayLines->PositionFromPartition(LinesInDoc()); } } int ContractionState::DisplayFromDoc(int lineDoc) const { if (OneToOne()) { return (lineDoc <= linesInDocument) ? lineDoc : linesInDocument; } else { if (lineDoc > displayLines->Partitions()) lineDoc = displayLines->Partitions(); return displayLines->PositionFromPartition(lineDoc); } } int ContractionState::DocFromDisplay(int lineDisplay) const { if (OneToOne()) { return lineDisplay; } else { if (lineDisplay <= 0) { return 0; } if (lineDisplay > LinesDisplayed()) { return displayLines->PartitionFromPosition(LinesDisplayed()); } int lineDoc = displayLines->PartitionFromPosition(lineDisplay); PLATFORM_ASSERT(GetVisible(lineDoc)); return lineDoc; } } void ContractionState::InsertLine(int lineDoc) { if (OneToOne()) { linesInDocument++; } else { visible->InsertSpace(lineDoc, 1); visible->SetValueAt(lineDoc, 1); expanded->InsertSpace(lineDoc, 1); expanded->SetValueAt(lineDoc, 1); heights->InsertSpace(lineDoc, 1); heights->SetValueAt(lineDoc, 1); int lineDisplay = DisplayFromDoc(lineDoc); displayLines->InsertPartition(lineDoc, lineDisplay); displayLines->InsertText(lineDoc, 1); } } void ContractionState::InsertLines(int lineDoc, int lineCount) { for (int l = 0; l < lineCount; l++) { InsertLine(lineDoc + l); } Check(); } void ContractionState::DeleteLine(int lineDoc) { if (OneToOne()) { linesInDocument--; } else { if (GetVisible(lineDoc)) { displayLines->InsertText(lineDoc, -heights->ValueAt(lineDoc)); } displayLines->RemovePartition(lineDoc); visible->DeleteRange(lineDoc, 1); expanded->DeleteRange(lineDoc, 1); heights->DeleteRange(lineDoc, 1); } } void ContractionState::DeleteLines(int lineDoc, int lineCount) { for (int l = 0; l < lineCount; l++) { DeleteLine(lineDoc); } Check(); } bool ContractionState::GetVisible(int lineDoc) const { if (OneToOne()) { return true; } else { if (lineDoc >= visible->Length()) return true; return visible->ValueAt(lineDoc) == 1; } } bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible_) { if (OneToOne() && visible_) { return false; } else { EnsureData(); int delta = 0; Check(); if ((lineDocStart <= lineDocEnd) && (lineDocStart >= 0) && (lineDocEnd < LinesInDoc())) { for (int line = lineDocStart; line <= lineDocEnd; line++) { if (GetVisible(line) != visible_) { int difference = visible_ ? heights->ValueAt(line) : -heights->ValueAt(line); visible->SetValueAt(line, visible_ ? 1 : 0); displayLines->InsertText(line, difference); delta += difference; } } } else { return false; } Check(); return delta != 0; } } bool ContractionState::HiddenLines() const { if (OneToOne()) { return false; } else { return !visible->AllSameAs(1); } } bool ContractionState::GetExpanded(int lineDoc) const { if (OneToOne()) { return true; } else { Check(); return expanded->ValueAt(lineDoc) == 1; } } bool ContractionState::SetExpanded(int lineDoc, bool expanded_) { if (OneToOne() && expanded_) { return false; } else { EnsureData(); if (expanded_ != (expanded->ValueAt(lineDoc) == 1)) { expanded->SetValueAt(lineDoc, expanded_ ? 1 : 0); Check(); return true; } else { Check(); return false; } } } int ContractionState::ContractedNext(int lineDocStart) const { if (OneToOne()) { return -1; } else { Check(); if (!expanded->ValueAt(lineDocStart)) { return lineDocStart; } else { int lineDocNextChange = expanded->EndRun(lineDocStart); if (lineDocNextChange < LinesInDoc()) return lineDocNextChange; else return -1; } } } int ContractionState::GetHeight(int lineDoc) const { if (OneToOne()) { return 1; } else { return heights->ValueAt(lineDoc); } } // Set the number of display lines needed for this line. // Return true if this is a change. bool ContractionState::SetHeight(int lineDoc, int height) { if (OneToOne() && (height == 1)) { return false; } else if (lineDoc < LinesInDoc()) { EnsureData(); if (GetHeight(lineDoc) != height) { if (GetVisible(lineDoc)) { displayLines->InsertText(lineDoc, height - GetHeight(lineDoc)); } heights->SetValueAt(lineDoc, height); Check(); return true; } else { Check(); return false; } } else { return false; } } void ContractionState::ShowAll() { int lines = LinesInDoc(); Clear(); linesInDocument = lines; } // Debugging checks void ContractionState::Check() const { #ifdef CHECK_CORRECTNESS for (int vline = 0; vline < LinesDisplayed(); vline++) { const int lineDoc = DocFromDisplay(vline); PLATFORM_ASSERT(GetVisible(lineDoc)); } for (int lineDoc = 0; lineDoc < LinesInDoc(); lineDoc++) { const int displayThis = DisplayFromDoc(lineDoc); const int displayNext = DisplayFromDoc(lineDoc + 1); const int height = displayNext - displayThis; PLATFORM_ASSERT(height >= 0); if (GetVisible(lineDoc)) { PLATFORM_ASSERT(GetHeight(lineDoc) == height); } else { PLATFORM_ASSERT(0 == height); } } #endif } |
Added src/ContractionState.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
// Scintilla source code edit control /** @file ContractionState.h ** Manages visibility of lines for folding and wrapping. **/ // Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef CONTRACTIONSTATE_H #define CONTRACTIONSTATE_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif /** */ class ContractionState { // These contain 1 element for every document line. RunStyles *visible; RunStyles *expanded; RunStyles *heights; Partitioning *displayLines; int linesInDocument; void EnsureData(); bool OneToOne() const { // True when each document line is exactly one display line so need for // complex data structures. return visible == 0; } public: ContractionState(); virtual ~ContractionState(); void Clear(); int LinesInDoc() const; int LinesDisplayed() const; int DisplayFromDoc(int lineDoc) const; int DocFromDisplay(int lineDisplay) const; void InsertLine(int lineDoc); void InsertLines(int lineDoc, int lineCount); void DeleteLine(int lineDoc); void DeleteLines(int lineDoc, int lineCount); bool GetVisible(int lineDoc) const; bool SetVisible(int lineDocStart, int lineDocEnd, bool visible); bool HiddenLines() const; bool GetExpanded(int lineDoc) const; bool SetExpanded(int lineDoc, bool expanded); int ContractedNext(int lineDocStart) const; int GetHeight(int lineDoc) const; bool SetHeight(int lineDoc, int height); void ShowAll(); void Check() const; }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/Decoration.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
/** @file Decoration.cxx ** Visual elements added over text. **/ // Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdio.h> #include <string.h> #include <stdlib.h> #include <stdarg.h> #include "Platform.h" #include "Scintilla.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" #include "Decoration.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif Decoration::Decoration(int indicator_) : next(0), indicator(indicator_) { } Decoration::~Decoration() { } bool Decoration::Empty() { return (rs.Runs() == 1) && (rs.AllSameAs(0)); } DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(0), lengthDocument(0), root(0), clickNotified(false) { } DecorationList::~DecorationList() { Decoration *deco = root; while (deco) { Decoration *decoNext = deco->next; delete deco; deco = decoNext; } root = 0; current = 0; } Decoration *DecorationList::DecorationFromIndicator(int indicator) { for (Decoration *deco=root; deco; deco = deco->next) { if (deco->indicator == indicator) { return deco; } } return 0; } Decoration *DecorationList::Create(int indicator, int length) { currentIndicator = indicator; Decoration *decoNew = new Decoration(indicator); decoNew->rs.InsertSpace(0, length); Decoration *decoPrev = 0; Decoration *deco = root; while (deco && (deco->indicator < indicator)) { decoPrev = deco; deco = deco->next; } if (decoPrev == 0) { decoNew->next = root; root = decoNew; } else { decoNew->next = deco; decoPrev->next = decoNew; } return decoNew; } void DecorationList::Delete(int indicator) { Decoration *decoToDelete = 0; if (root) { if (root->indicator == indicator) { decoToDelete = root; root = root->next; } else { Decoration *deco=root; while (deco->next && !decoToDelete) { if (deco->next && deco->next->indicator == indicator) { decoToDelete = deco->next; deco->next = decoToDelete->next; } else { deco = deco->next; } } } } if (decoToDelete) { delete decoToDelete; current = 0; } } void DecorationList::SetCurrentIndicator(int indicator) { currentIndicator = indicator; current = DecorationFromIndicator(indicator); currentValue = 1; } void DecorationList::SetCurrentValue(int value) { currentValue = value ? value : 1; } bool DecorationList::FillRange(int &position, int value, int &fillLength) { if (!current) { current = DecorationFromIndicator(currentIndicator); if (!current) { current = Create(currentIndicator, lengthDocument); } } bool changed = current->rs.FillRange(position, value, fillLength); if (current->Empty()) { Delete(currentIndicator); } return changed; } void DecorationList::InsertSpace(int position, int insertLength) { const bool atEnd = position == lengthDocument; lengthDocument += insertLength; for (Decoration *deco=root; deco; deco = deco->next) { deco->rs.InsertSpace(position, insertLength); if (atEnd) { deco->rs.FillRange(position, 0, insertLength); } } } void DecorationList::DeleteRange(int position, int deleteLength) { lengthDocument -= deleteLength; Decoration *deco; for (deco=root; deco; deco = deco->next) { deco->rs.DeleteRange(position, deleteLength); } DeleteAnyEmpty(); } void DecorationList::DeleteAnyEmpty() { Decoration *deco = root; while (deco) { if ((lengthDocument == 0) || deco->Empty()) { Delete(deco->indicator); deco = root; } else { deco = deco->next; } } } int DecorationList::AllOnFor(int position) { int mask = 0; for (Decoration *deco=root; deco; deco = deco->next) { if (deco->rs.ValueAt(position)) { mask |= 1 << deco->indicator; } } return mask; } int DecorationList::ValueAt(int indicator, int position) { Decoration *deco = DecorationFromIndicator(indicator); if (deco) { return deco->rs.ValueAt(position); } return 0; } int DecorationList::Start(int indicator, int position) { Decoration *deco = DecorationFromIndicator(indicator); if (deco) { return deco->rs.StartRun(position); } return 0; } int DecorationList::End(int indicator, int position) { Decoration *deco = DecorationFromIndicator(indicator); if (deco) { return deco->rs.EndRun(position); } return 0; } |
Added src/Decoration.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
/** @file Decoration.h ** Visual elements added over text. **/ // Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef DECORATION_H #define DECORATION_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif class Decoration { public: Decoration *next; RunStyles rs; int indicator; Decoration(int indicator_); ~Decoration(); bool Empty(); }; class DecorationList { int currentIndicator; int currentValue; Decoration *current; int lengthDocument; Decoration *DecorationFromIndicator(int indicator); Decoration *Create(int indicator, int length); void Delete(int indicator); void DeleteAnyEmpty(); public: Decoration *root; bool clickNotified; DecorationList(); ~DecorationList(); void SetCurrentIndicator(int indicator); int GetCurrentIndicator() const { return currentIndicator; } void SetCurrentValue(int value); int GetCurrentValue() const { return currentValue; } // Returns true if some values may have changed bool FillRange(int &position, int value, int &fillLength); void InsertSpace(int position, int insertLength); void DeleteRange(int position, int deleteLength); int AllOnFor(int position); int ValueAt(int indicator, int position); int Start(int indicator, int position); int End(int indicator, int position); }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/Document.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 |
// Scintilla source code edit control /** @file Document.cxx ** Text document that handles notifications, DBCS, styling, words and end of line. **/ // Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <ctype.h> #include <assert.h> #include <string> #include <vector> #include "Platform.h" #include "ILexer.h" #include "Scintilla.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" #include "CellBuffer.h" #include "PerLine.h" #include "CharClassify.h" #include "CharacterSet.h" #include "Decoration.h" #include "Document.h" #include "RESearch.h" #include "UniConversion.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsPunctuation(char ch) { return isascii(ch) && ispunct(ch); } void LexInterface::Colourise(int start, int end) { if (pdoc && instance && !performingStyle) { // Protect against reentrance, which may occur, for example, when // fold points are discovered while performing styling and the folding // code looks for child lines which may trigger styling. performingStyle = true; int lengthDoc = pdoc->Length(); if (end == -1) end = lengthDoc; int len = end - start; PLATFORM_ASSERT(len >= 0); PLATFORM_ASSERT(start + len <= lengthDoc); int styleStart = 0; if (start > 0) styleStart = pdoc->StyleAt(start - 1) & pdoc->stylingBitsMask; if (len > 0) { instance->Lex(start, len, styleStart, pdoc); instance->Fold(start, len, styleStart, pdoc); } performingStyle = false; } } int LexInterface::LineEndTypesSupported() { if (instance) { int interfaceVersion = instance->Version(); if (interfaceVersion >= lvSubStyles) { ILexerWithSubStyles *ssinstance = static_cast<ILexerWithSubStyles *>(instance); return ssinstance->LineEndTypesSupported(); } } return 0; } Document::Document() { refCount = 0; pcf = NULL; #ifdef _WIN32 eolMode = SC_EOL_CRLF; #else eolMode = SC_EOL_LF; #endif dbcsCodePage = 0; lineEndBitSet = SC_LINE_END_TYPE_DEFAULT; stylingBits = 5; stylingBitsMask = 0x1F; stylingMask = 0; endStyled = 0; styleClock = 0; enteredModification = 0; enteredStyling = 0; enteredReadOnlyCount = 0; tabInChars = 8; indentInChars = 0; actualIndentInChars = 8; useTabs = true; tabIndents = true; backspaceUnindents = false; watchers = 0; lenWatchers = 0; matchesValid = false; regex = 0; UTF8BytesOfLeadInitialise(); perLineData[ldMarkers] = new LineMarkers(); perLineData[ldLevels] = new LineLevels(); perLineData[ldState] = new LineState(); perLineData[ldMargin] = new LineAnnotation(); perLineData[ldAnnotation] = new LineAnnotation(); cb.SetPerLine(this); pli = 0; } Document::~Document() { for (int i = 0; i < lenWatchers; i++) { watchers[i].watcher->NotifyDeleted(this, watchers[i].userData); } delete []watchers; for (int j=0; j<ldSize; j++) { delete perLineData[j]; perLineData[j] = 0; } watchers = 0; lenWatchers = 0; delete regex; regex = 0; delete pli; pli = 0; delete pcf; pcf = 0; } void Document::Init() { for (int j=0; j<ldSize; j++) { if (perLineData[j]) perLineData[j]->Init(); } } int Document::LineEndTypesSupported() const { if ((SC_CP_UTF8 == dbcsCodePage) && pli) return pli->LineEndTypesSupported(); else return 0; } bool Document::SetDBCSCodePage(int dbcsCodePage_) { if (dbcsCodePage != dbcsCodePage_) { dbcsCodePage = dbcsCodePage_; SetCaseFolder(NULL); cb.SetLineEndTypes(lineEndBitSet & LineEndTypesSupported()); return true; } else { return false; } } bool Document::SetLineEndTypesAllowed(int lineEndBitSet_) { if (lineEndBitSet != lineEndBitSet_) { lineEndBitSet = lineEndBitSet_; int lineEndBitSetActive = lineEndBitSet & LineEndTypesSupported(); if (lineEndBitSetActive != cb.GetLineEndTypes()) { ModifiedAt(0); cb.SetLineEndTypes(lineEndBitSetActive); return true; } else { return false; } } else { return false; } } void Document::InsertLine(int line) { for (int j=0; j<ldSize; j++) { if (perLineData[j]) perLineData[j]->InsertLine(line); } } void Document::RemoveLine(int line) { for (int j=0; j<ldSize; j++) { if (perLineData[j]) perLineData[j]->RemoveLine(line); } } // Increase reference count and return its previous value. int Document::AddRef() { return refCount++; } // Decrease reference count and return its previous value. // Delete the document if reference count reaches zero. int SCI_METHOD Document::Release() { int curRefCount = --refCount; if (curRefCount == 0) delete this; return curRefCount; } void Document::SetSavePoint() { cb.SetSavePoint(); NotifySavePoint(true); } int Document::GetMark(int line) { return static_cast<LineMarkers *>(perLineData[ldMarkers])->MarkValue(line); } int Document::MarkerNext(int lineStart, int mask) const { return static_cast<LineMarkers *>(perLineData[ldMarkers])->MarkerNext(lineStart, mask); } int Document::AddMark(int line, int markerNum) { if (line >= 0 && line <= LinesTotal()) { int prev = static_cast<LineMarkers *>(perLineData[ldMarkers])-> AddMark(line, markerNum, LinesTotal()); DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line); NotifyModified(mh); return prev; } else { return 0; } } void Document::AddMarkSet(int line, int valueSet) { if (line < 0 || line > LinesTotal()) { return; } unsigned int m = valueSet; for (int i = 0; m; i++, m >>= 1) if (m & 1) static_cast<LineMarkers *>(perLineData[ldMarkers])-> AddMark(line, i, LinesTotal()); DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line); NotifyModified(mh); } void Document::DeleteMark(int line, int markerNum) { static_cast<LineMarkers *>(perLineData[ldMarkers])->DeleteMark(line, markerNum, false); DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line); NotifyModified(mh); } void Document::DeleteMarkFromHandle(int markerHandle) { static_cast<LineMarkers *>(perLineData[ldMarkers])->DeleteMarkFromHandle(markerHandle); DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0); mh.line = -1; NotifyModified(mh); } void Document::DeleteAllMarks(int markerNum) { bool someChanges = false; for (int line = 0; line < LinesTotal(); line++) { if (static_cast<LineMarkers *>(perLineData[ldMarkers])->DeleteMark(line, markerNum, true)) someChanges = true; } if (someChanges) { DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0); mh.line = -1; NotifyModified(mh); } } int Document::LineFromHandle(int markerHandle) { return static_cast<LineMarkers *>(perLineData[ldMarkers])->LineFromHandle(markerHandle); } int SCI_METHOD Document::LineStart(int line) const { return cb.LineStart(line); } int SCI_METHOD Document::LineEnd(int line) const { if (line == LinesTotal() - 1) { return LineStart(line + 1); } else { int position = LineStart(line + 1); if (SC_CP_UTF8 == dbcsCodePage) { unsigned char bytes[] = { static_cast<unsigned char>(cb.CharAt(position-3)), static_cast<unsigned char>(cb.CharAt(position-2)), static_cast<unsigned char>(cb.CharAt(position-1)), }; if (UTF8IsSeparator(bytes)) { return position - UTF8SeparatorLength; } if (UTF8IsNEL(bytes+1)) { return position - UTF8NELLength; } } position--; // Back over CR or LF // When line terminator is CR+LF, may need to go back one more if ((position > LineStart(line)) && (cb.CharAt(position - 1) == '\r')) { position--; } return position; } } void SCI_METHOD Document::SetErrorStatus(int status) { // Tell the watchers the lexer has changed. for (int i = 0; i < lenWatchers; i++) { watchers[i].watcher->NotifyErrorOccurred(this, watchers[i].userData, status); } } int SCI_METHOD Document::LineFromPosition(int pos) const { return cb.LineFromPosition(pos); } int Document::LineEndPosition(int position) const { return LineEnd(LineFromPosition(position)); } bool Document::IsLineEndPosition(int position) const { return LineEnd(LineFromPosition(position)) == position; } bool Document::IsPositionInLineEnd(int position) const { return position >= LineEnd(LineFromPosition(position)); } int Document::VCHomePosition(int position) const { int line = LineFromPosition(position); int startPosition = LineStart(line); int endLine = LineEnd(line); int startText = startPosition; while (startText < endLine && (cb.CharAt(startText) == ' ' || cb.CharAt(startText) == '\t')) startText++; if (position == startText) return startPosition; else return startText; } int SCI_METHOD Document::SetLevel(int line, int level) { int prev = static_cast<LineLevels *>(perLineData[ldLevels])->SetLevel(line, level, LinesTotal()); if (prev != level) { DocModification mh(SC_MOD_CHANGEFOLD | SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line); mh.foldLevelNow = level; mh.foldLevelPrev = prev; NotifyModified(mh); } return prev; } int SCI_METHOD Document::GetLevel(int line) const { return static_cast<LineLevels *>(perLineData[ldLevels])->GetLevel(line); } void Document::ClearLevels() { static_cast<LineLevels *>(perLineData[ldLevels])->ClearLevels(); } static bool IsSubordinate(int levelStart, int levelTry) { if (levelTry & SC_FOLDLEVELWHITEFLAG) return true; else return (levelStart & SC_FOLDLEVELNUMBERMASK) < (levelTry & SC_FOLDLEVELNUMBERMASK); } int Document::GetLastChild(int lineParent, int level, int lastLine) { if (level == -1) level = GetLevel(lineParent) & SC_FOLDLEVELNUMBERMASK; int maxLine = LinesTotal(); int lookLastLine = (lastLine != -1) ? Platform::Minimum(LinesTotal() - 1, lastLine) : -1; int lineMaxSubord = lineParent; while (lineMaxSubord < maxLine - 1) { EnsureStyledTo(LineStart(lineMaxSubord + 2)); if (!IsSubordinate(level, GetLevel(lineMaxSubord + 1))) break; if ((lookLastLine != -1) && (lineMaxSubord >= lookLastLine) && !(GetLevel(lineMaxSubord) & SC_FOLDLEVELWHITEFLAG)) break; lineMaxSubord++; } if (lineMaxSubord > lineParent) { if (level > (GetLevel(lineMaxSubord + 1) & SC_FOLDLEVELNUMBERMASK)) { // Have chewed up some whitespace that belongs to a parent so seek back if (GetLevel(lineMaxSubord) & SC_FOLDLEVELWHITEFLAG) { lineMaxSubord--; } } } return lineMaxSubord; } int Document::GetFoldParent(int line) { int level = GetLevel(line) & SC_FOLDLEVELNUMBERMASK; int lineLook = line - 1; while ((lineLook > 0) && ( (!(GetLevel(lineLook) & SC_FOLDLEVELHEADERFLAG)) || ((GetLevel(lineLook) & SC_FOLDLEVELNUMBERMASK) >= level)) ) { lineLook--; } if ((GetLevel(lineLook) & SC_FOLDLEVELHEADERFLAG) && ((GetLevel(lineLook) & SC_FOLDLEVELNUMBERMASK) < level)) { return lineLook; } else { return -1; } } void Document::GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, int line, int lastLine) { int level = GetLevel(line); int lookLastLine = Platform::Maximum(line, lastLine) + 1; int lookLine = line; int lookLineLevel = level; int lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK; while ((lookLine > 0) && ((lookLineLevel & SC_FOLDLEVELWHITEFLAG) || ((lookLineLevel & SC_FOLDLEVELHEADERFLAG) && (lookLineLevelNum >= (GetLevel(lookLine + 1) & SC_FOLDLEVELNUMBERMASK))))) { lookLineLevel = GetLevel(--lookLine); lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK; } int beginFoldBlock = (lookLineLevel & SC_FOLDLEVELHEADERFLAG) ? lookLine : GetFoldParent(lookLine); if (beginFoldBlock == -1) { highlightDelimiter.Clear(); return; } int endFoldBlock = GetLastChild(beginFoldBlock, -1, lookLastLine); int firstChangeableLineBefore = -1; if (endFoldBlock < line) { lookLine = beginFoldBlock - 1; lookLineLevel = GetLevel(lookLine); lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK; while ((lookLine >= 0) && (lookLineLevelNum >= SC_FOLDLEVELBASE)) { if (lookLineLevel & SC_FOLDLEVELHEADERFLAG) { if (GetLastChild(lookLine, -1, lookLastLine) == line) { beginFoldBlock = lookLine; endFoldBlock = line; firstChangeableLineBefore = line - 1; } } if ((lookLine > 0) && (lookLineLevelNum == SC_FOLDLEVELBASE) && ((GetLevel(lookLine - 1) & SC_FOLDLEVELNUMBERMASK) > lookLineLevelNum)) break; lookLineLevel = GetLevel(--lookLine); lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK; } } if (firstChangeableLineBefore == -1) { for (lookLine = line - 1, lookLineLevel = GetLevel(lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK; lookLine >= beginFoldBlock; lookLineLevel = GetLevel(--lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK) { if ((lookLineLevel & SC_FOLDLEVELWHITEFLAG) || (lookLineLevelNum > (level & SC_FOLDLEVELNUMBERMASK))) { firstChangeableLineBefore = lookLine; break; } } } if (firstChangeableLineBefore == -1) firstChangeableLineBefore = beginFoldBlock - 1; int firstChangeableLineAfter = -1; for (lookLine = line + 1, lookLineLevel = GetLevel(lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK; lookLine <= endFoldBlock; lookLineLevel = GetLevel(++lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK) { if ((lookLineLevel & SC_FOLDLEVELHEADERFLAG) && (lookLineLevelNum < (GetLevel(lookLine + 1) & SC_FOLDLEVELNUMBERMASK))) { firstChangeableLineAfter = lookLine; break; } } if (firstChangeableLineAfter == -1) firstChangeableLineAfter = endFoldBlock + 1; highlightDelimiter.beginFoldBlock = beginFoldBlock; highlightDelimiter.endFoldBlock = endFoldBlock; highlightDelimiter.firstChangeableLineBefore = firstChangeableLineBefore; highlightDelimiter.firstChangeableLineAfter = firstChangeableLineAfter; } int Document::ClampPositionIntoDocument(int pos) { return Platform::Clamp(pos, 0, Length()); } bool Document::IsCrLf(int pos) { if (pos < 0) return false; if (pos >= (Length() - 1)) return false; return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n'); } int Document::LenChar(int pos) { if (pos < 0) { return 1; } else if (IsCrLf(pos)) { return 2; } else if (SC_CP_UTF8 == dbcsCodePage) { const unsigned char leadByte = static_cast<unsigned char>(cb.CharAt(pos)); const int widthCharBytes = UTF8BytesOfLead[leadByte]; int lengthDoc = Length(); if ((pos + widthCharBytes) > lengthDoc) return lengthDoc - pos; else return widthCharBytes; } else if (dbcsCodePage) { return IsDBCSLeadByte(cb.CharAt(pos)) ? 2 : 1; } else { return 1; } } bool Document::InGoodUTF8(int pos, int &start, int &end) const { int trail = pos; while ((trail>0) && (pos-trail < UTF8MaxBytes) && UTF8IsTrailByte(static_cast<unsigned char>(cb.CharAt(trail-1)))) trail--; start = (trail > 0) ? trail-1 : trail; const unsigned char leadByte = static_cast<unsigned char>(cb.CharAt(start)); const int widthCharBytes = UTF8BytesOfLead[leadByte]; if (widthCharBytes == 1) { return false; } else { int trailBytes = widthCharBytes - 1; int len = pos - start; if (len > trailBytes) // pos too far from lead return false; char charBytes[UTF8MaxBytes] = {static_cast<char>(leadByte),0,0,0}; for (int b=1; b<widthCharBytes && ((start+b) < Length()); b++) charBytes[b] = cb.CharAt(static_cast<int>(start+b)); int utf8status = UTF8Classify(reinterpret_cast<const unsigned char *>(charBytes), widthCharBytes); if (utf8status & UTF8MaskInvalid) return false; end = start + widthCharBytes; return true; } } // Normalise a position so that it is not halfway through a two byte character. // This can occur in two situations - // When lines are terminated with \r\n pairs which should be treated as one character. // When displaying DBCS text such as Japanese. // If moving, move the position in the indicated direction. int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) { //Platform::DebugPrintf("NoCRLF %d %d\n", pos, moveDir); // If out of range, just return minimum/maximum value. if (pos <= 0) return 0; if (pos >= Length()) return Length(); // PLATFORM_ASSERT(pos > 0 && pos < Length()); if (checkLineEnd && IsCrLf(pos - 1)) { if (moveDir > 0) return pos + 1; else return pos - 1; } if (dbcsCodePage) { if (SC_CP_UTF8 == dbcsCodePage) { unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos)); // If ch is not a trail byte then pos is valid intercharacter position if (UTF8IsTrailByte(ch)) { int startUTF = pos; int endUTF = pos; if (InGoodUTF8(pos, startUTF, endUTF)) { // ch is a trail byte within a UTF-8 character if (moveDir > 0) pos = endUTF; else pos = startUTF; } // Else invalid UTF-8 so return position of isolated trail byte } } else { // Anchor DBCS calculations at start of line because start of line can // not be a DBCS trail byte. int posStartLine = LineStart(LineFromPosition(pos)); if (pos == posStartLine) return pos; // Step back until a non-lead-byte is found. int posCheck = pos; while ((posCheck > posStartLine) && IsDBCSLeadByte(cb.CharAt(posCheck-1))) posCheck--; // Check from known start of character. while (posCheck < pos) { int mbsize = IsDBCSLeadByte(cb.CharAt(posCheck)) ? 2 : 1; if (posCheck + mbsize == pos) { return pos; } else if (posCheck + mbsize > pos) { if (moveDir > 0) { return posCheck + mbsize; } else { return posCheck; } } posCheck += mbsize; } } } return pos; } // NextPosition moves between valid positions - it can not handle a position in the middle of a // multi-byte character. It is used to iterate through text more efficiently than MovePositionOutsideChar. // A \r\n pair is treated as two characters. int Document::NextPosition(int pos, int moveDir) const { // If out of range, just return minimum/maximum value. int increment = (moveDir > 0) ? 1 : -1; if (pos + increment <= 0) return 0; if (pos + increment >= Length()) return Length(); if (dbcsCodePage) { if (SC_CP_UTF8 == dbcsCodePage) { if (increment == 1) { // Simple forward movement case so can avoid some checks const unsigned char leadByte = static_cast<unsigned char>(cb.CharAt(pos)); if (UTF8IsAscii(leadByte)) { // Single byte character or invalid pos++; } else { const int widthCharBytes = UTF8BytesOfLead[leadByte]; char charBytes[UTF8MaxBytes] = {static_cast<char>(leadByte),0,0,0}; for (int b=1; b<widthCharBytes; b++) charBytes[b] = cb.CharAt(static_cast<int>(pos+b)); int utf8status = UTF8Classify(reinterpret_cast<const unsigned char *>(charBytes), widthCharBytes); if (utf8status & UTF8MaskInvalid) pos++; else pos += utf8status & UTF8MaskWidth; } } else { // Examine byte before position pos--; unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos)); // If ch is not a trail byte then pos is valid intercharacter position if (UTF8IsTrailByte(ch)) { // If ch is a trail byte in a valid UTF-8 character then return start of character int startUTF = pos; int endUTF = pos; if (InGoodUTF8(pos, startUTF, endUTF)) { pos = startUTF; } // Else invalid UTF-8 so return position of isolated trail byte } } } else { if (moveDir > 0) { int mbsize = IsDBCSLeadByte(cb.CharAt(pos)) ? 2 : 1; pos += mbsize; if (pos > Length()) pos = Length(); } else { // Anchor DBCS calculations at start of line because start of line can // not be a DBCS trail byte. int posStartLine = LineStart(LineFromPosition(pos)); // See http://msdn.microsoft.com/en-us/library/cc194792%28v=MSDN.10%29.aspx // http://msdn.microsoft.com/en-us/library/cc194790.aspx if ((pos - 1) <= posStartLine) { return pos - 1; } else if (IsDBCSLeadByte(cb.CharAt(pos - 1))) { // Must actually be trail byte return pos - 2; } else { // Otherwise, step back until a non-lead-byte is found. int posTemp = pos - 1; while (posStartLine <= --posTemp && IsDBCSLeadByte(cb.CharAt(posTemp))) ; // Now posTemp+1 must point to the beginning of a character, // so figure out whether we went back an even or an odd // number of bytes and go back 1 or 2 bytes, respectively. return (pos - 1 - ((pos - posTemp) & 1)); } } } } else { pos += increment; } return pos; } bool Document::NextCharacter(int &pos, int moveDir) { // Returns true if pos changed int posNext = NextPosition(pos, moveDir); if (posNext == pos) { return false; } else { pos = posNext; return true; } } int SCI_METHOD Document::CodePage() const { return dbcsCodePage; } bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const { // Byte ranges found in Wikipedia articles with relevant search strings in each case unsigned char uch = static_cast<unsigned char>(ch); switch (dbcsCodePage) { case 932: // Shift_jis return ((uch >= 0x81) && (uch <= 0x9F)) || ((uch >= 0xE0) && (uch <= 0xFC)); // Lead bytes F0 to FC may be a Microsoft addition. case 936: // GBK return (uch >= 0x81) && (uch <= 0xFE); case 949: // Korean Wansung KS C-5601-1987 return (uch >= 0x81) && (uch <= 0xFE); case 950: // Big5 return (uch >= 0x81) && (uch <= 0xFE); case 1361: // Korean Johab KS C-5601-1992 return ((uch >= 0x84) && (uch <= 0xD3)) || ((uch >= 0xD8) && (uch <= 0xDE)) || ((uch >= 0xE0) && (uch <= 0xF9)); } return false; } static inline bool IsSpaceOrTab(int ch) { return ch == ' ' || ch == '\t'; } // Need to break text into segments near lengthSegment but taking into // account the encoding to not break inside a UTF-8 or DBCS character // and also trying to avoid breaking inside a pair of combining characters. // The segment length must always be long enough (more than 4 bytes) // so that there will be at least one whole character to make a segment. // For UTF-8, text must consist only of valid whole characters. // In preference order from best to worst: // 1) Break after space // 2) Break before punctuation // 3) Break after whole character int Document::SafeSegment(const char *text, int length, int lengthSegment) { if (length <= lengthSegment) return length; int lastSpaceBreak = -1; int lastPunctuationBreak = -1; int lastEncodingAllowedBreak = -1; for (int j=0; j < lengthSegment;) { unsigned char ch = static_cast<unsigned char>(text[j]); if (j > 0) { if (IsSpaceOrTab(text[j - 1]) && !IsSpaceOrTab(text[j])) { lastSpaceBreak = j; } if (ch < 'A') { lastPunctuationBreak = j; } } lastEncodingAllowedBreak = j; if (dbcsCodePage == SC_CP_UTF8) { j += UTF8BytesOfLead[ch]; } else if (dbcsCodePage) { j += IsDBCSLeadByte(ch) ? 2 : 1; } else { j++; } } if (lastSpaceBreak >= 0) { return lastSpaceBreak; } else if (lastPunctuationBreak >= 0) { return lastPunctuationBreak; } return lastEncodingAllowedBreak; } void Document::ModifiedAt(int pos) { if (endStyled > pos) endStyled = pos; } void Document::CheckReadOnly() { if (cb.IsReadOnly() && enteredReadOnlyCount == 0) { enteredReadOnlyCount++; NotifyModifyAttempt(); enteredReadOnlyCount--; } } // Document only modified by gateways DeleteChars, InsertString, Undo, Redo, and SetStyleAt. // SetStyleAt does not change the persistent state of a document bool Document::DeleteChars(int pos, int len) { if (len <= 0) return false; if ((pos + len) > Length()) return false; CheckReadOnly(); if (enteredModification != 0) { return false; } else { enteredModification++; if (!cb.IsReadOnly()) { NotifyModified( DocModification( SC_MOD_BEFOREDELETE | SC_PERFORMED_USER, pos, len, 0, 0)); int prevLinesTotal = LinesTotal(); bool startSavePoint = cb.IsSavePoint(); bool startSequence = false; const char *text = cb.DeleteChars(pos, len, startSequence); if (startSavePoint && cb.IsCollectingUndo()) NotifySavePoint(!startSavePoint); if ((pos < Length()) || (pos == 0)) ModifiedAt(pos); else ModifiedAt(pos-1); NotifyModified( DocModification( SC_MOD_DELETETEXT | SC_PERFORMED_USER | (startSequence?SC_STARTACTION:0), pos, len, LinesTotal() - prevLinesTotal, text)); } enteredModification--; } return !cb.IsReadOnly(); } /** * Insert a string with a length. */ bool Document::InsertString(int position, const char *s, int insertLength) { if (insertLength <= 0) { return false; } CheckReadOnly(); if (enteredModification != 0) { return false; } else { enteredModification++; if (!cb.IsReadOnly()) { NotifyModified( DocModification( SC_MOD_BEFOREINSERT | SC_PERFORMED_USER, position, insertLength, 0, s)); int prevLinesTotal = LinesTotal(); bool startSavePoint = cb.IsSavePoint(); bool startSequence = false; const char *text = cb.InsertString(position, s, insertLength, startSequence); if (startSavePoint && cb.IsCollectingUndo()) NotifySavePoint(!startSavePoint); ModifiedAt(position); NotifyModified( DocModification( SC_MOD_INSERTTEXT | SC_PERFORMED_USER | (startSequence?SC_STARTACTION:0), position, insertLength, LinesTotal() - prevLinesTotal, text)); } enteredModification--; } return !cb.IsReadOnly(); } int SCI_METHOD Document::AddData(char *data, int length) { try { int position = Length(); InsertString(position,data, length); } catch (std::bad_alloc &) { return SC_STATUS_BADALLOC; } catch (...) { return SC_STATUS_FAILURE; } return 0; } void * SCI_METHOD Document::ConvertToDocument() { return this; } int Document::Undo() { int newPos = -1; CheckReadOnly(); if (enteredModification == 0) { enteredModification++; if (!cb.IsReadOnly()) { bool startSavePoint = cb.IsSavePoint(); bool multiLine = false; int steps = cb.StartUndo(); //Platform::DebugPrintf("Steps=%d\n", steps); int coalescedRemovePos = -1; int coalescedRemoveLen = 0; int prevRemoveActionPos = -1; int prevRemoveActionLen = 0; for (int step = 0; step < steps; step++) { const int prevLinesTotal = LinesTotal(); const Action &action = cb.GetUndoStep(); if (action.at == removeAction) { NotifyModified(DocModification( SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action)); } else if (action.at == containerAction) { DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_UNDO); dm.token = action.position; NotifyModified(dm); if (!action.mayCoalesce) { coalescedRemovePos = -1; coalescedRemoveLen = 0; prevRemoveActionPos = -1; prevRemoveActionLen = 0; } } else { NotifyModified(DocModification( SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action)); } cb.PerformUndoStep(); if (action.at != containerAction) { ModifiedAt(action.position); newPos = action.position; } int modFlags = SC_PERFORMED_UNDO; // With undo, an insertion action becomes a deletion notification if (action.at == removeAction) { newPos += action.lenData; modFlags |= SC_MOD_INSERTTEXT; if ((coalescedRemoveLen > 0) && (action.position == prevRemoveActionPos || action.position == (prevRemoveActionPos + prevRemoveActionLen))) { coalescedRemoveLen += action.lenData; newPos = coalescedRemovePos + coalescedRemoveLen; } else { coalescedRemovePos = action.position; coalescedRemoveLen = action.lenData; } prevRemoveActionPos = action.position; prevRemoveActionLen = action.lenData; } else if (action.at == insertAction) { modFlags |= SC_MOD_DELETETEXT; coalescedRemovePos = -1; coalescedRemoveLen = 0; prevRemoveActionPos = -1; prevRemoveActionLen = 0; } if (steps > 1) modFlags |= SC_MULTISTEPUNDOREDO; const int linesAdded = LinesTotal() - prevLinesTotal; if (linesAdded != 0) multiLine = true; if (step == steps - 1) { modFlags |= SC_LASTSTEPINUNDOREDO; if (multiLine) modFlags |= SC_MULTILINEUNDOREDO; } NotifyModified(DocModification(modFlags, action.position, action.lenData, linesAdded, action.data)); } bool endSavePoint = cb.IsSavePoint(); if (startSavePoint != endSavePoint) NotifySavePoint(endSavePoint); } enteredModification--; } return newPos; } int Document::Redo() { int newPos = -1; CheckReadOnly(); if (enteredModification == 0) { enteredModification++; if (!cb.IsReadOnly()) { bool startSavePoint = cb.IsSavePoint(); bool multiLine = false; int steps = cb.StartRedo(); for (int step = 0; step < steps; step++) { const int prevLinesTotal = LinesTotal(); const Action &action = cb.GetRedoStep(); if (action.at == insertAction) { NotifyModified(DocModification( SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action)); } else if (action.at == containerAction) { DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_REDO); dm.token = action.position; NotifyModified(dm); } else { NotifyModified(DocModification( SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action)); } cb.PerformRedoStep(); if (action.at != containerAction) { ModifiedAt(action.position); newPos = action.position; } int modFlags = SC_PERFORMED_REDO; if (action.at == insertAction) { newPos += action.lenData; modFlags |= SC_MOD_INSERTTEXT; } else if (action.at == removeAction) { modFlags |= SC_MOD_DELETETEXT; } if (steps > 1) modFlags |= SC_MULTISTEPUNDOREDO; const int linesAdded = LinesTotal() - prevLinesTotal; if (linesAdded != 0) multiLine = true; if (step == steps - 1) { modFlags |= SC_LASTSTEPINUNDOREDO; if (multiLine) modFlags |= SC_MULTILINEUNDOREDO; } NotifyModified( DocModification(modFlags, action.position, action.lenData, linesAdded, action.data)); } bool endSavePoint = cb.IsSavePoint(); if (startSavePoint != endSavePoint) NotifySavePoint(endSavePoint); } enteredModification--; } return newPos; } /** * Insert a single character. */ bool Document::InsertChar(int pos, char ch) { char chs[1]; chs[0] = ch; return InsertString(pos, chs, 1); } /** * Insert a null terminated string. */ bool Document::InsertCString(int position, const char *s) { return InsertString(position, s, static_cast<int>(s ? strlen(s) : 0)); } void Document::ChangeChar(int pos, char ch) { DeleteChars(pos, 1); InsertChar(pos, ch); } void Document::DelChar(int pos) { DeleteChars(pos, LenChar(pos)); } void Document::DelCharBack(int pos) { if (pos <= 0) { return; } else if (IsCrLf(pos - 2)) { DeleteChars(pos - 2, 2); } else if (dbcsCodePage) { int startChar = NextPosition(pos, -1); DeleteChars(startChar, pos - startChar); } else { DeleteChars(pos - 1, 1); } } static int NextTab(int pos, int tabSize) { return ((pos / tabSize) + 1) * tabSize; } static std::string CreateIndentation(int indent, int tabSize, bool insertSpaces) { std::string indentation; if (!insertSpaces) { while (indent >= tabSize) { indentation += '\t'; indent -= tabSize; } } while (indent > 0) { indentation += ' '; indent--; } return indentation; } int SCI_METHOD Document::GetLineIndentation(int line) { int indent = 0; if ((line >= 0) && (line < LinesTotal())) { int lineStart = LineStart(line); int length = Length(); for (int i = lineStart; i < length; i++) { char ch = cb.CharAt(i); if (ch == ' ') indent++; else if (ch == '\t') indent = NextTab(indent, tabInChars); else return indent; } } return indent; } void Document::SetLineIndentation(int line, int indent) { int indentOfLine = GetLineIndentation(line); if (indent < 0) indent = 0; if (indent != indentOfLine) { std::string linebuf = CreateIndentation(indent, tabInChars, !useTabs); int thisLineStart = LineStart(line); int indentPos = GetLineIndentPosition(line); UndoGroup ug(this); DeleteChars(thisLineStart, indentPos - thisLineStart); InsertCString(thisLineStart, linebuf.c_str()); } } int Document::GetLineIndentPosition(int line) const { if (line < 0) return 0; int pos = LineStart(line); int length = Length(); while ((pos < length) && IsSpaceOrTab(cb.CharAt(pos))) { pos++; } return pos; } int Document::GetColumn(int pos) { int column = 0; int line = LineFromPosition(pos); if ((line >= 0) && (line < LinesTotal())) { for (int i = LineStart(line); i < pos;) { char ch = cb.CharAt(i); if (ch == '\t') { column = NextTab(column, tabInChars); i++; } else if (ch == '\r') { return column; } else if (ch == '\n') { return column; } else if (i >= Length()) { return column; } else { column++; i = NextPosition(i, 1); } } } return column; } int Document::CountCharacters(int startPos, int endPos) { startPos = MovePositionOutsideChar(startPos, 1, false); endPos = MovePositionOutsideChar(endPos, -1, false); int count = 0; int i = startPos; while (i < endPos) { count++; if (IsCrLf(i)) i++; i = NextPosition(i, 1); } return count; } int Document::FindColumn(int line, int column) { int position = LineStart(line); if ((line >= 0) && (line < LinesTotal())) { int columnCurrent = 0; while ((columnCurrent < column) && (position < Length())) { char ch = cb.CharAt(position); if (ch == '\t') { columnCurrent = NextTab(columnCurrent, tabInChars); if (columnCurrent > column) return position; position++; } else if (ch == '\r') { return position; } else if (ch == '\n') { return position; } else { columnCurrent++; position = NextPosition(position, 1); } } } return position; } void Document::Indent(bool forwards, int lineBottom, int lineTop) { // Dedent - suck white space off the front of the line to dedent by equivalent of a tab for (int line = lineBottom; line >= lineTop; line--) { int indentOfLine = GetLineIndentation(line); if (forwards) { if (LineStart(line) < LineEnd(line)) { SetLineIndentation(line, indentOfLine + IndentSize()); } } else { SetLineIndentation(line, indentOfLine - IndentSize()); } } } // Convert line endings for a piece of text to a particular mode. // Stop at len or when a NUL is found. // Caller must delete the returned pointer. char *Document::TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolModeWanted) { char *dest = new char[2 * len + 1]; const char *sptr = s; char *dptr = dest; for (size_t i = 0; (i < len) && (*sptr != '\0'); i++) { if (*sptr == '\n' || *sptr == '\r') { if (eolModeWanted == SC_EOL_CR) { *dptr++ = '\r'; } else if (eolModeWanted == SC_EOL_LF) { *dptr++ = '\n'; } else { // eolModeWanted == SC_EOL_CRLF *dptr++ = '\r'; *dptr++ = '\n'; } if ((*sptr == '\r') && (i+1 < len) && (*(sptr+1) == '\n')) { i++; sptr++; } sptr++; } else { *dptr++ = *sptr++; } } *dptr++ = '\0'; *pLenOut = (dptr - dest) - 1; return dest; } void Document::ConvertLineEnds(int eolModeSet) { UndoGroup ug(this); for (int pos = 0; pos < Length(); pos++) { if (cb.CharAt(pos) == '\r') { if (cb.CharAt(pos + 1) == '\n') { // CRLF if (eolModeSet == SC_EOL_CR) { DeleteChars(pos + 1, 1); // Delete the LF } else if (eolModeSet == SC_EOL_LF) { DeleteChars(pos, 1); // Delete the CR } else { pos++; } } else { // CR if (eolModeSet == SC_EOL_CRLF) { InsertString(pos + 1, "\n", 1); // Insert LF pos++; } else if (eolModeSet == SC_EOL_LF) { InsertString(pos, "\n", 1); // Insert LF DeleteChars(pos + 1, 1); // Delete CR } } } else if (cb.CharAt(pos) == '\n') { // LF if (eolModeSet == SC_EOL_CRLF) { InsertString(pos, "\r", 1); // Insert CR pos++; } else if (eolModeSet == SC_EOL_CR) { InsertString(pos, "\r", 1); // Insert CR DeleteChars(pos + 1, 1); // Delete LF } } } } bool Document::IsWhiteLine(int line) const { int currentChar = LineStart(line); int endLine = LineEnd(line); while (currentChar < endLine) { if (cb.CharAt(currentChar) != ' ' && cb.CharAt(currentChar) != '\t') { return false; } ++currentChar; } return true; } int Document::ParaUp(int pos) { int line = LineFromPosition(pos); line--; while (line >= 0 && IsWhiteLine(line)) { // skip empty lines line--; } while (line >= 0 && !IsWhiteLine(line)) { // skip non-empty lines line--; } line++; return LineStart(line); } int Document::ParaDown(int pos) { int line = LineFromPosition(pos); while (line < LinesTotal() && !IsWhiteLine(line)) { // skip non-empty lines line++; } while (line < LinesTotal() && IsWhiteLine(line)) { // skip empty lines line++; } if (line < LinesTotal()) return LineStart(line); else // end of a document return LineEnd(line-1); } CharClassify::cc Document::WordCharClass(unsigned char ch) { if ((SC_CP_UTF8 == dbcsCodePage) && (!UTF8IsAscii(ch))) return CharClassify::ccWord; return charClass.GetClass(ch); } /** * Used by commmands that want to select whole words. * Finds the start of word at pos when delta < 0 or the end of the word when delta >= 0. */ int Document::ExtendWordSelect(int pos, int delta, bool onlyWordCharacters) { CharClassify::cc ccStart = CharClassify::ccWord; if (delta < 0) { if (!onlyWordCharacters) ccStart = WordCharClass(cb.CharAt(pos-1)); while (pos > 0 && (WordCharClass(cb.CharAt(pos - 1)) == ccStart)) pos--; } else { if (!onlyWordCharacters && pos < Length()) ccStart = WordCharClass(cb.CharAt(pos)); while (pos < (Length()) && (WordCharClass(cb.CharAt(pos)) == ccStart)) pos++; } return MovePositionOutsideChar(pos, delta, true); } /** * Find the start of the next word in either a forward (delta >= 0) or backwards direction * (delta < 0). * This is looking for a transition between character classes although there is also some * additional movement to transit white space. * Used by cursor movement by word commands. */ int Document::NextWordStart(int pos, int delta) { if (delta < 0) { while (pos > 0 && (WordCharClass(cb.CharAt(pos - 1)) == CharClassify::ccSpace)) pos--; if (pos > 0) { CharClassify::cc ccStart = WordCharClass(cb.CharAt(pos-1)); while (pos > 0 && (WordCharClass(cb.CharAt(pos - 1)) == ccStart)) { pos--; } } } else { CharClassify::cc ccStart = WordCharClass(cb.CharAt(pos)); while (pos < (Length()) && (WordCharClass(cb.CharAt(pos)) == ccStart)) pos++; while (pos < (Length()) && (WordCharClass(cb.CharAt(pos)) == CharClassify::ccSpace)) pos++; } return pos; } /** * Find the end of the next word in either a forward (delta >= 0) or backwards direction * (delta < 0). * This is looking for a transition between character classes although there is also some * additional movement to transit white space. * Used by cursor movement by word commands. */ int Document::NextWordEnd(int pos, int delta) { if (delta < 0) { if (pos > 0) { CharClassify::cc ccStart = WordCharClass(cb.CharAt(pos-1)); if (ccStart != CharClassify::ccSpace) { while (pos > 0 && WordCharClass(cb.CharAt(pos - 1)) == ccStart) { pos--; } } while (pos > 0 && WordCharClass(cb.CharAt(pos - 1)) == CharClassify::ccSpace) { pos--; } } } else { while (pos < Length() && WordCharClass(cb.CharAt(pos)) == CharClassify::ccSpace) { pos++; } if (pos < Length()) { CharClassify::cc ccStart = WordCharClass(cb.CharAt(pos)); while (pos < Length() && WordCharClass(cb.CharAt(pos)) == ccStart) { pos++; } } } return pos; } /** * Check that the character at the given position is a word or punctuation character and that * the previous character is of a different character class. */ bool Document::IsWordStartAt(int pos) { if (pos > 0) { CharClassify::cc ccPos = WordCharClass(CharAt(pos)); return (ccPos == CharClassify::ccWord || ccPos == CharClassify::ccPunctuation) && (ccPos != WordCharClass(CharAt(pos - 1))); } return true; } /** * Check that the character at the given position is a word or punctuation character and that * the next character is of a different character class. */ bool Document::IsWordEndAt(int pos) { if (pos < Length()) { CharClassify::cc ccPrev = WordCharClass(CharAt(pos-1)); return (ccPrev == CharClassify::ccWord || ccPrev == CharClassify::ccPunctuation) && (ccPrev != WordCharClass(CharAt(pos))); } return true; } /** * Check that the given range is has transitions between character classes at both * ends and where the characters on the inside are word or punctuation characters. */ bool Document::IsWordAt(int start, int end) { return IsWordStartAt(start) && IsWordEndAt(end); } static inline char MakeLowerCase(char ch) { if (ch < 'A' || ch > 'Z') return ch; else return static_cast<char>(ch - 'A' + 'a'); } CaseFolderTable::CaseFolderTable() { for (size_t iChar=0; iChar<sizeof(mapping); iChar++) { mapping[iChar] = static_cast<char>(iChar); } } CaseFolderTable::~CaseFolderTable() { } size_t CaseFolderTable::Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) { if (lenMixed > sizeFolded) { return 0; } else { for (size_t i=0; i<lenMixed; i++) { folded[i] = mapping[static_cast<unsigned char>(mixed[i])]; } return lenMixed; } } void CaseFolderTable::SetTranslation(char ch, char chTranslation) { mapping[static_cast<unsigned char>(ch)] = chTranslation; } void CaseFolderTable::StandardASCII() { for (size_t iChar=0; iChar<sizeof(mapping); iChar++) { if (iChar >= 'A' && iChar <= 'Z') { mapping[iChar] = static_cast<char>(iChar - 'A' + 'a'); } else { mapping[iChar] = static_cast<char>(iChar); } } } bool Document::MatchesWordOptions(bool word, bool wordStart, int pos, int length) { return (!word && !wordStart) || (word && IsWordAt(pos, pos + length)) || (wordStart && IsWordStartAt(pos)); } bool Document::HasCaseFolder(void) const { return pcf != 0; } void Document::SetCaseFolder(CaseFolder *pcf_) { delete pcf; pcf = pcf_; } /** * Find text in document, supporting both forward and backward * searches (just pass minPos > maxPos to do a backward search) * Has not been tested with backwards DBCS searches yet. */ long Document::FindText(int minPos, int maxPos, const char *search, bool caseSensitive, bool word, bool wordStart, bool regExp, int flags, int *length) { if (*length <= 0) return minPos; if (regExp) { if (!regex) regex = CreateRegexSearch(&charClass); return regex->FindText(this, minPos, maxPos, search, caseSensitive, word, wordStart, flags, length); } else { const bool forward = minPos <= maxPos; const int increment = forward ? 1 : -1; // Range endpoints should not be inside DBCS characters, but just in case, move them. const int startPos = MovePositionOutsideChar(minPos, increment, false); const int endPos = MovePositionOutsideChar(maxPos, increment, false); // Compute actual search ranges needed const int lengthFind = *length; //Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind); const int limitPos = Platform::Maximum(startPos, endPos); int pos = startPos; if (!forward) { // Back all of a character pos = NextPosition(pos, increment); } if (caseSensitive) { const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos; const char charStartSearch = search[0]; while (forward ? (pos < endSearch) : (pos >= endSearch)) { if (CharAt(pos) == charStartSearch) { bool found = (pos + lengthFind) <= limitPos; for (int indexSearch = 1; (indexSearch < lengthFind) && found; indexSearch++) { found = CharAt(pos + indexSearch) == search[indexSearch]; } if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) { return pos; } } if (!NextCharacter(pos, increment)) break; } } else if (SC_CP_UTF8 == dbcsCodePage) { const size_t maxFoldingExpansion = 4; std::vector<char> searchThing(lengthFind * UTF8MaxBytes * maxFoldingExpansion + 1); const int lenSearch = static_cast<int>( pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind)); char bytes[UTF8MaxBytes + 1]; char folded[UTF8MaxBytes * maxFoldingExpansion + 1]; while (forward ? (pos < endPos) : (pos >= endPos)) { int widthFirstCharacter = 0; int posIndexDocument = pos; int indexSearch = 0; bool characterMatches = true; for (;;) { const unsigned char leadByte = static_cast<unsigned char>(cb.CharAt(posIndexDocument)); bytes[0] = leadByte; int widthChar = 1; if (!UTF8IsAscii(leadByte)) { const int widthCharBytes = UTF8BytesOfLead[leadByte]; for (int b=1; b<widthCharBytes; b++) { bytes[b] = cb.CharAt(posIndexDocument+b); } widthChar = UTF8Classify(reinterpret_cast<const unsigned char *>(bytes), widthCharBytes) & UTF8MaskWidth; } if (!widthFirstCharacter) widthFirstCharacter = widthChar; if ((posIndexDocument + widthChar) > limitPos) break; const int lenFlat = static_cast<int>(pcf->Fold(folded, sizeof(folded), bytes, widthChar)); folded[lenFlat] = 0; // Does folded match the buffer characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat); if (!characterMatches) break; posIndexDocument += widthChar; indexSearch += lenFlat; if (indexSearch >= lenSearch) break; } if (characterMatches && (indexSearch == static_cast<int>(lenSearch))) { if (MatchesWordOptions(word, wordStart, pos, posIndexDocument - pos)) { *length = posIndexDocument - pos; return pos; } } if (forward) { pos += widthFirstCharacter; } else { if (!NextCharacter(pos, increment)) break; } } } else if (dbcsCodePage) { const size_t maxBytesCharacter = 2; const size_t maxFoldingExpansion = 4; std::vector<char> searchThing(lengthFind * maxBytesCharacter * maxFoldingExpansion + 1); const int lenSearch = static_cast<int>( pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind)); while (forward ? (pos < endPos) : (pos >= endPos)) { int indexDocument = 0; int indexSearch = 0; bool characterMatches = true; while (characterMatches && ((pos + indexDocument) < limitPos) && (indexSearch < lenSearch)) { char bytes[maxBytesCharacter + 1]; bytes[0] = cb.CharAt(pos + indexDocument); const int widthChar = IsDBCSLeadByte(bytes[0]) ? 2 : 1; if (widthChar == 2) bytes[1] = cb.CharAt(pos + indexDocument + 1); if ((pos + indexDocument + widthChar) > limitPos) break; char folded[maxBytesCharacter * maxFoldingExpansion + 1]; const int lenFlat = static_cast<int>(pcf->Fold(folded, sizeof(folded), bytes, widthChar)); folded[lenFlat] = 0; // Does folded match the buffer characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat); indexDocument += widthChar; indexSearch += lenFlat; } if (characterMatches && (indexSearch == static_cast<int>(lenSearch))) { if (MatchesWordOptions(word, wordStart, pos, indexDocument)) { *length = indexDocument; return pos; } } if (!NextCharacter(pos, increment)) break; } } else { const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos; std::vector<char> searchThing(lengthFind + 1); pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind); while (forward ? (pos < endSearch) : (pos >= endSearch)) { bool found = (pos + lengthFind) <= limitPos; for (int indexSearch = 0; (indexSearch < lengthFind) && found; indexSearch++) { char ch = CharAt(pos + indexSearch); char folded[2]; pcf->Fold(folded, sizeof(folded), &ch, 1); found = folded[0] == searchThing[indexSearch]; } if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) { return pos; } if (!NextCharacter(pos, increment)) break; } } } //Platform::DebugPrintf("Not found\n"); return -1; } const char *Document::SubstituteByPosition(const char *text, int *length) { if (regex) return regex->SubstituteByPosition(this, text, length); else return 0; } int Document::LinesTotal() const { return cb.Lines(); } void Document::ChangeCase(Range r, bool makeUpperCase) { for (int pos = r.start; pos < r.end;) { int len = LenChar(pos); if (len == 1) { char ch = CharAt(pos); if (makeUpperCase) { if (IsLowerCase(ch)) { ChangeChar(pos, static_cast<char>(MakeUpperCase(ch))); } } else { if (IsUpperCase(ch)) { ChangeChar(pos, static_cast<char>(MakeLowerCase(ch))); } } } pos += len; } } void Document::SetDefaultCharClasses(bool includeWordClass) { charClass.SetDefaultCharClasses(includeWordClass); } void Document::SetCharClasses(const unsigned char *chars, CharClassify::cc newCharClass) { charClass.SetCharClasses(chars, newCharClass); } int Document::GetCharsOfClass(CharClassify::cc characterClass, unsigned char *buffer) { return charClass.GetCharsOfClass(characterClass, buffer); } void Document::SetStylingBits(int bits) { stylingBits = bits; stylingBitsMask = (1 << stylingBits) - 1; } void SCI_METHOD Document::StartStyling(int position, char mask) { stylingMask = mask; endStyled = position; } bool SCI_METHOD Document::SetStyleFor(int length, char style) { if (enteredStyling != 0) { return false; } else { enteredStyling++; style &= stylingMask; int prevEndStyled = endStyled; if (cb.SetStyleFor(endStyled, length, style, stylingMask)) { DocModification mh(SC_MOD_CHANGESTYLE | SC_PERFORMED_USER, prevEndStyled, length); NotifyModified(mh); } endStyled += length; enteredStyling--; return true; } } bool SCI_METHOD Document::SetStyles(int length, const char *styles) { if (enteredStyling != 0) { return false; } else { enteredStyling++; bool didChange = false; int startMod = 0; int endMod = 0; for (int iPos = 0; iPos < length; iPos++, endStyled++) { PLATFORM_ASSERT(endStyled < Length()); if (cb.SetStyleAt(endStyled, styles[iPos], stylingMask)) { if (!didChange) { startMod = endStyled; } didChange = true; endMod = endStyled; } } if (didChange) { DocModification mh(SC_MOD_CHANGESTYLE | SC_PERFORMED_USER, startMod, endMod - startMod + 1); NotifyModified(mh); } enteredStyling--; return true; } } void Document::EnsureStyledTo(int pos) { if ((enteredStyling == 0) && (pos > GetEndStyled())) { IncrementStyleClock(); if (pli && !pli->UseContainerLexing()) { int lineEndStyled = LineFromPosition(GetEndStyled()); int endStyledTo = LineStart(lineEndStyled); pli->Colourise(endStyledTo, pos); } else { // Ask the watchers to style, and stop as soon as one responds. for (int i = 0; pos > GetEndStyled() && i < lenWatchers; i++) { watchers[i].watcher->NotifyStyleNeeded(this, watchers[i].userData, pos); } } } } void Document::LexerChanged() { // Tell the watchers the lexer has changed. for (int i = 0; i < lenWatchers; i++) { watchers[i].watcher->NotifyLexerChanged(this, watchers[i].userData); } } int SCI_METHOD Document::SetLineState(int line, int state) { int statePrevious = static_cast<LineState *>(perLineData[ldState])->SetLineState(line, state); if (state != statePrevious) { DocModification mh(SC_MOD_CHANGELINESTATE, LineStart(line), 0, 0, 0, line); NotifyModified(mh); } return statePrevious; } int SCI_METHOD Document::GetLineState(int line) const { return static_cast<LineState *>(perLineData[ldState])->GetLineState(line); } int Document::GetMaxLineState() { return static_cast<LineState *>(perLineData[ldState])->GetMaxLineState(); } void SCI_METHOD Document::ChangeLexerState(int start, int end) { DocModification mh(SC_MOD_LEXERSTATE, start, end-start, 0, 0, 0); NotifyModified(mh); } StyledText Document::MarginStyledText(int line) { LineAnnotation *pla = static_cast<LineAnnotation *>(perLineData[ldMargin]); return StyledText(pla->Length(line), pla->Text(line), pla->MultipleStyles(line), pla->Style(line), pla->Styles(line)); } void Document::MarginSetText(int line, const char *text) { static_cast<LineAnnotation *>(perLineData[ldMargin])->SetText(line, text); DocModification mh(SC_MOD_CHANGEMARGIN, LineStart(line), 0, 0, 0, line); NotifyModified(mh); } void Document::MarginSetStyle(int line, int style) { static_cast<LineAnnotation *>(perLineData[ldMargin])->SetStyle(line, style); NotifyModified(DocModification(SC_MOD_CHANGEMARGIN, LineStart(line), 0, 0, 0, line)); } void Document::MarginSetStyles(int line, const unsigned char *styles) { static_cast<LineAnnotation *>(perLineData[ldMargin])->SetStyles(line, styles); NotifyModified(DocModification(SC_MOD_CHANGEMARGIN, LineStart(line), 0, 0, 0, line)); } int Document::MarginLength(int line) const { return static_cast<LineAnnotation *>(perLineData[ldMargin])->Length(line); } void Document::MarginClearAll() { int maxEditorLine = LinesTotal(); for (int l=0; l<maxEditorLine; l++) MarginSetText(l, 0); // Free remaining data static_cast<LineAnnotation *>(perLineData[ldMargin])->ClearAll(); } bool Document::AnnotationAny() const { return static_cast<LineAnnotation *>(perLineData[ldAnnotation])->AnySet(); } StyledText Document::AnnotationStyledText(int line) { LineAnnotation *pla = static_cast<LineAnnotation *>(perLineData[ldAnnotation]); return StyledText(pla->Length(line), pla->Text(line), pla->MultipleStyles(line), pla->Style(line), pla->Styles(line)); } void Document::AnnotationSetText(int line, const char *text) { if (line >= 0 && line < LinesTotal()) { const int linesBefore = AnnotationLines(line); static_cast<LineAnnotation *>(perLineData[ldAnnotation])->SetText(line, text); const int linesAfter = AnnotationLines(line); DocModification mh(SC_MOD_CHANGEANNOTATION, LineStart(line), 0, 0, 0, line); mh.annotationLinesAdded = linesAfter - linesBefore; NotifyModified(mh); } } void Document::AnnotationSetStyle(int line, int style) { static_cast<LineAnnotation *>(perLineData[ldAnnotation])->SetStyle(line, style); DocModification mh(SC_MOD_CHANGEANNOTATION, LineStart(line), 0, 0, 0, line); NotifyModified(mh); } void Document::AnnotationSetStyles(int line, const unsigned char *styles) { if (line >= 0 && line < LinesTotal()) { static_cast<LineAnnotation *>(perLineData[ldAnnotation])->SetStyles(line, styles); } } int Document::AnnotationLength(int line) const { return static_cast<LineAnnotation *>(perLineData[ldAnnotation])->Length(line); } int Document::AnnotationLines(int line) const { return static_cast<LineAnnotation *>(perLineData[ldAnnotation])->Lines(line); } void Document::AnnotationClearAll() { int maxEditorLine = LinesTotal(); for (int l=0; l<maxEditorLine; l++) AnnotationSetText(l, 0); // Free remaining data static_cast<LineAnnotation *>(perLineData[ldAnnotation])->ClearAll(); } void Document::IncrementStyleClock() { styleClock = (styleClock + 1) % 0x100000; } void SCI_METHOD Document::DecorationFillRange(int position, int value, int fillLength) { if (decorations.FillRange(position, value, fillLength)) { DocModification mh(SC_MOD_CHANGEINDICATOR | SC_PERFORMED_USER, position, fillLength); NotifyModified(mh); } } bool Document::AddWatcher(DocWatcher *watcher, void *userData) { for (int i = 0; i < lenWatchers; i++) { if ((watchers[i].watcher == watcher) && (watchers[i].userData == userData)) return false; } WatcherWithUserData *pwNew = new WatcherWithUserData[lenWatchers + 1]; for (int j = 0; j < lenWatchers; j++) pwNew[j] = watchers[j]; pwNew[lenWatchers].watcher = watcher; pwNew[lenWatchers].userData = userData; delete []watchers; watchers = pwNew; lenWatchers++; return true; } bool Document::RemoveWatcher(DocWatcher *watcher, void *userData) { for (int i = 0; i < lenWatchers; i++) { if ((watchers[i].watcher == watcher) && (watchers[i].userData == userData)) { if (lenWatchers == 1) { delete []watchers; watchers = 0; lenWatchers = 0; } else { WatcherWithUserData *pwNew = new WatcherWithUserData[lenWatchers]; for (int j = 0; j < lenWatchers - 1; j++) { pwNew[j] = (j < i) ? watchers[j] : watchers[j + 1]; } delete []watchers; watchers = pwNew; lenWatchers--; } return true; } } return false; } void Document::NotifyModifyAttempt() { for (int i = 0; i < lenWatchers; i++) { watchers[i].watcher->NotifyModifyAttempt(this, watchers[i].userData); } } void Document::NotifySavePoint(bool atSavePoint) { for (int i = 0; i < lenWatchers; i++) { watchers[i].watcher->NotifySavePoint(this, watchers[i].userData, atSavePoint); } } void Document::NotifyModified(DocModification mh) { if (mh.modificationType & SC_MOD_INSERTTEXT) { decorations.InsertSpace(mh.position, mh.length); } else if (mh.modificationType & SC_MOD_DELETETEXT) { decorations.DeleteRange(mh.position, mh.length); } for (int i = 0; i < lenWatchers; i++) { watchers[i].watcher->NotifyModified(this, mh, watchers[i].userData); } } bool Document::IsWordPartSeparator(char ch) { return (WordCharClass(ch) == CharClassify::ccWord) && IsPunctuation(ch); } int Document::WordPartLeft(int pos) { if (pos > 0) { --pos; char startChar = cb.CharAt(pos); if (IsWordPartSeparator(startChar)) { while (pos > 0 && IsWordPartSeparator(cb.CharAt(pos))) { --pos; } } if (pos > 0) { startChar = cb.CharAt(pos); --pos; if (IsLowerCase(startChar)) { while (pos > 0 && IsLowerCase(cb.CharAt(pos))) --pos; if (!IsUpperCase(cb.CharAt(pos)) && !IsLowerCase(cb.CharAt(pos))) ++pos; } else if (IsUpperCase(startChar)) { while (pos > 0 && IsUpperCase(cb.CharAt(pos))) --pos; if (!IsUpperCase(cb.CharAt(pos))) ++pos; } else if (IsADigit(startChar)) { while (pos > 0 && IsADigit(cb.CharAt(pos))) --pos; if (!IsADigit(cb.CharAt(pos))) ++pos; } else if (IsPunctuation(startChar)) { while (pos > 0 && IsPunctuation(cb.CharAt(pos))) --pos; if (!IsPunctuation(cb.CharAt(pos))) ++pos; } else if (isspacechar(startChar)) { while (pos > 0 && isspacechar(cb.CharAt(pos))) --pos; if (!isspacechar(cb.CharAt(pos))) ++pos; } else if (!isascii(startChar)) { while (pos > 0 && !isascii(cb.CharAt(pos))) --pos; if (isascii(cb.CharAt(pos))) ++pos; } else { ++pos; } } } return pos; } int Document::WordPartRight(int pos) { char startChar = cb.CharAt(pos); int length = Length(); if (IsWordPartSeparator(startChar)) { while (pos < length && IsWordPartSeparator(cb.CharAt(pos))) ++pos; startChar = cb.CharAt(pos); } if (!isascii(startChar)) { while (pos < length && !isascii(cb.CharAt(pos))) ++pos; } else if (IsLowerCase(startChar)) { while (pos < length && IsLowerCase(cb.CharAt(pos))) ++pos; } else if (IsUpperCase(startChar)) { if (IsLowerCase(cb.CharAt(pos + 1))) { ++pos; while (pos < length && IsLowerCase(cb.CharAt(pos))) ++pos; } else { while (pos < length && IsUpperCase(cb.CharAt(pos))) ++pos; } if (IsLowerCase(cb.CharAt(pos)) && IsUpperCase(cb.CharAt(pos - 1))) --pos; } else if (IsADigit(startChar)) { while (pos < length && IsADigit(cb.CharAt(pos))) ++pos; } else if (IsPunctuation(startChar)) { while (pos < length && IsPunctuation(cb.CharAt(pos))) ++pos; } else if (isspacechar(startChar)) { while (pos < length && isspacechar(cb.CharAt(pos))) ++pos; } else { ++pos; } return pos; } bool IsLineEndChar(char c) { return (c == '\n' || c == '\r'); } int Document::ExtendStyleRange(int pos, int delta, bool singleLine) { int sStart = cb.StyleAt(pos); if (delta < 0) { while (pos > 0 && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos)))) pos--; pos++; } else { while (pos < (Length()) && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos)))) pos++; } return pos; } static char BraceOpposite(char ch) { switch (ch) { case '(': return ')'; case ')': return '('; case '[': return ']'; case ']': return '['; case '{': return '}'; case '}': return '{'; case '<': return '>'; case '>': return '<'; default: return '\0'; } } // TODO: should be able to extend styled region to find matching brace int Document::BraceMatch(int position, int /*maxReStyle*/) { char chBrace = CharAt(position); char chSeek = BraceOpposite(chBrace); if (chSeek == '\0') return - 1; char styBrace = static_cast<char>(StyleAt(position) & stylingBitsMask); int direction = -1; if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<') direction = 1; int depth = 1; position = NextPosition(position, direction); while ((position >= 0) && (position < Length())) { char chAtPos = CharAt(position); char styAtPos = static_cast<char>(StyleAt(position) & stylingBitsMask); if ((position > GetEndStyled()) || (styAtPos == styBrace)) { if (chAtPos == chBrace) depth++; if (chAtPos == chSeek) depth--; if (depth == 0) return position; } int positionBeforeMove = position; position = NextPosition(position, direction); if (position == positionBeforeMove) break; } return - 1; } /** * Implementation of RegexSearchBase for the default built-in regular expression engine */ class BuiltinRegex : public RegexSearchBase { public: BuiltinRegex(CharClassify *charClassTable) : search(charClassTable), substituted(NULL) {} virtual ~BuiltinRegex() { delete substituted; } virtual long FindText(Document *doc, int minPos, int maxPos, const char *s, bool caseSensitive, bool word, bool wordStart, int flags, int *length); virtual const char *SubstituteByPosition(Document *doc, const char *text, int *length); private: RESearch search; char *substituted; }; // Define a way for the Regular Expression code to access the document class DocumentIndexer : public CharacterIndexer { Document *pdoc; int end; public: DocumentIndexer(Document *pdoc_, int end_) : pdoc(pdoc_), end(end_) { } virtual ~DocumentIndexer() { } virtual char CharAt(int index) { if (index < 0 || index >= end) return 0; else return pdoc->CharAt(index); } }; long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s, bool caseSensitive, bool, bool, int flags, int *length) { bool posix = (flags & SCFIND_POSIX) != 0; int increment = (minPos <= maxPos) ? 1 : -1; int startPos = minPos; int endPos = maxPos; // Range endpoints should not be inside DBCS characters, but just in case, move them. startPos = doc->MovePositionOutsideChar(startPos, 1, false); endPos = doc->MovePositionOutsideChar(endPos, 1, false); const char *errmsg = search.Compile(s, *length, caseSensitive, posix); if (errmsg) { return -1; } // Find a variable in a property file: \$(\([A-Za-z0-9_.]+\)) // Replace first '.' with '-' in each property file variable reference: // Search: \$(\([A-Za-z0-9_-]+\)\.\([A-Za-z0-9_.]+\)) // Replace: $(\1-\2) int lineRangeStart = doc->LineFromPosition(startPos); int lineRangeEnd = doc->LineFromPosition(endPos); if ((increment == 1) && (startPos >= doc->LineEnd(lineRangeStart)) && (lineRangeStart < lineRangeEnd)) { // the start position is at end of line or between line end characters. lineRangeStart++; startPos = doc->LineStart(lineRangeStart); } else if ((increment == -1) && (startPos <= doc->LineStart(lineRangeStart)) && (lineRangeStart > lineRangeEnd)) { // the start position is at beginning of line. lineRangeStart--; startPos = doc->LineEnd(lineRangeStart); } int pos = -1; int lenRet = 0; char searchEnd = s[*length - 1]; char searchEndPrev = (*length > 1) ? s[*length - 2] : '\0'; int lineRangeBreak = lineRangeEnd + increment; for (int line = lineRangeStart; line != lineRangeBreak; line += increment) { int startOfLine = doc->LineStart(line); int endOfLine = doc->LineEnd(line); if (increment == 1) { if (line == lineRangeStart) { if ((startPos != startOfLine) && (s[0] == '^')) continue; // Can't match start of line if start position after start of line startOfLine = startPos; } if (line == lineRangeEnd) { if ((endPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\')) continue; // Can't match end of line if end position before end of line endOfLine = endPos; } } else { if (line == lineRangeEnd) { if ((endPos != startOfLine) && (s[0] == '^')) continue; // Can't match start of line if end position after start of line startOfLine = endPos; } if (line == lineRangeStart) { if ((startPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\')) continue; // Can't match end of line if start position before end of line endOfLine = startPos; } } DocumentIndexer di(doc, endOfLine); int success = search.Execute(di, startOfLine, endOfLine); if (success) { pos = search.bopat[0]; lenRet = search.eopat[0] - search.bopat[0]; // There can be only one start of a line, so no need to look for last match in line if ((increment == -1) && (s[0] != '^')) { // Check for the last match on this line. int repetitions = 1000; // Break out of infinite loop while (success && (search.eopat[0] <= endOfLine) && (repetitions--)) { success = search.Execute(di, pos+1, endOfLine); if (success) { if (search.eopat[0] <= minPos) { pos = search.bopat[0]; lenRet = search.eopat[0] - search.bopat[0]; } else { success = 0; } } } } break; } } *length = lenRet; return pos; } const char *BuiltinRegex::SubstituteByPosition(Document *doc, const char *text, int *length) { delete []substituted; substituted = 0; DocumentIndexer di(doc, doc->Length()); if (!search.GrabMatches(di)) return 0; unsigned int lenResult = 0; for (int i = 0; i < *length; i++) { if (text[i] == '\\') { if (text[i + 1] >= '0' && text[i + 1] <= '9') { unsigned int patNum = text[i + 1] - '0'; lenResult += search.eopat[patNum] - search.bopat[patNum]; i++; } else { switch (text[i + 1]) { case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v': case '\\': i++; } lenResult++; } } else { lenResult++; } } substituted = new char[lenResult + 1]; char *o = substituted; for (int j = 0; j < *length; j++) { if (text[j] == '\\') { if (text[j + 1] >= '0' && text[j + 1] <= '9') { unsigned int patNum = text[j + 1] - '0'; unsigned int len = search.eopat[patNum] - search.bopat[patNum]; if (search.pat[patNum]) // Will be null if try for a match that did not occur memcpy(o, search.pat[patNum], len); o += len; j++; } else { j++; switch (text[j]) { case 'a': *o++ = '\a'; break; case 'b': *o++ = '\b'; break; case 'f': *o++ = '\f'; break; case 'n': *o++ = '\n'; break; case 'r': *o++ = '\r'; break; case 't': *o++ = '\t'; break; case 'v': *o++ = '\v'; break; case '\\': *o++ = '\\'; break; default: *o++ = '\\'; j--; } } } else { *o++ = text[j]; } } *o = '\0'; *length = lenResult; return substituted; } #ifndef SCI_OWNREGEX #ifdef SCI_NAMESPACE RegexSearchBase *Scintilla::CreateRegexSearch(CharClassify *charClassTable) { return new BuiltinRegex(charClassTable); } #else RegexSearchBase *CreateRegexSearch(CharClassify *charClassTable) { return new BuiltinRegex(charClassTable); } #endif #endif |
Added src/Document.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 |
// Scintilla source code edit control /** @file Document.h ** Text document that handles notifications, DBCS, styling, words and end of line. **/ // Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef DOCUMENT_H #define DOCUMENT_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif /** * A Position is a position within a document between two characters or at the beginning or end. * Sometimes used as a character index where it identifies the character after the position. */ typedef int Position; const Position invalidPosition = -1; /** * The range class represents a range of text in a document. * The two values are not sorted as one end may be more significant than the other * as is the case for the selection where the end position is the position of the caret. * If either position is invalidPosition then the range is invalid and most operations will fail. */ class Range { public: Position start; Position end; Range(Position pos=0) : start(pos), end(pos) { } Range(Position start_, Position end_) : start(start_), end(end_) { } bool Valid() const { return (start != invalidPosition) && (end != invalidPosition); } // Is the position within the range? bool Contains(Position pos) const { if (start < end) { return (pos >= start && pos <= end); } else { return (pos <= start && pos >= end); } } // Is the character after pos within the range? bool ContainsCharacter(Position pos) const { if (start < end) { return (pos >= start && pos < end); } else { return (pos < start && pos >= end); } } bool Contains(Range other) const { return Contains(other.start) && Contains(other.end); } bool Overlaps(Range other) const { return Contains(other.start) || Contains(other.end) || other.Contains(start) || other.Contains(end); } }; class DocWatcher; class DocModification; class Document; /** * Interface class for regular expression searching */ class RegexSearchBase { public: virtual ~RegexSearchBase() {} virtual long FindText(Document *doc, int minPos, int maxPos, const char *s, bool caseSensitive, bool word, bool wordStart, int flags, int *length) = 0; ///@return String with the substitutions, must remain valid until the next call or destruction virtual const char *SubstituteByPosition(Document *doc, const char *text, int *length) = 0; }; /// Factory function for RegexSearchBase extern RegexSearchBase *CreateRegexSearch(CharClassify *charClassTable); struct StyledText { size_t length; const char *text; bool multipleStyles; size_t style; const unsigned char *styles; StyledText(size_t length_, const char *text_, bool multipleStyles_, int style_, const unsigned char *styles_) : length(length_), text(text_), multipleStyles(multipleStyles_), style(style_), styles(styles_) { } // Return number of bytes from start to before '\n' or end of text. // Return 1 when start is outside text size_t LineLength(size_t start) const { size_t cur = start; while ((cur < length) && (text[cur] != '\n')) cur++; return cur-start; } size_t StyleAt(size_t i) const { return multipleStyles ? styles[i] : style; } }; class HighlightDelimiter { public: HighlightDelimiter() : isEnabled(false) { Clear(); } void Clear() { beginFoldBlock = -1; endFoldBlock = -1; firstChangeableLineBefore = -1; firstChangeableLineAfter = -1; } bool NeedsDrawing(int line) { return isEnabled && (line <= firstChangeableLineBefore || line >= firstChangeableLineAfter); } bool IsFoldBlockHighlighted(int line) { return isEnabled && beginFoldBlock != -1 && beginFoldBlock <= line && line <= endFoldBlock; } bool IsHeadOfFoldBlock(int line) { return beginFoldBlock == line && line < endFoldBlock; } bool IsBodyOfFoldBlock(int line) { return beginFoldBlock != -1 && beginFoldBlock < line && line < endFoldBlock; } bool IsTailOfFoldBlock(int line) { return beginFoldBlock != -1 && beginFoldBlock < line && line == endFoldBlock; } int beginFoldBlock; // Begin of current fold block int endFoldBlock; // End of current fold block int firstChangeableLineBefore; // First line that triggers repaint before starting line that determined current fold block int firstChangeableLineAfter; // First line that triggers repaint after starting line that determined current fold block bool isEnabled; }; class CaseFolder { public: virtual ~CaseFolder() { } virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) = 0; }; class CaseFolderTable : public CaseFolder { protected: char mapping[256]; public: CaseFolderTable(); virtual ~CaseFolderTable(); virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed); void SetTranslation(char ch, char chTranslation); void StandardASCII(); }; class Document; class LexInterface { protected: Document *pdoc; ILexer *instance; bool performingStyle; ///< Prevent reentrance public: LexInterface(Document *pdoc_) : pdoc(pdoc_), instance(0), performingStyle(false) { } virtual ~LexInterface() { } void Colourise(int start, int end); int LineEndTypesSupported(); bool UseContainerLexing() const { return instance == 0; } }; /** */ class Document : PerLine, public IDocumentWithLineEnd, public ILoader { public: /** Used to pair watcher pointer with user data. */ class WatcherWithUserData { public: DocWatcher *watcher; void *userData; WatcherWithUserData() { watcher = 0; userData = 0; } }; enum charClassification { ccSpace, ccNewLine, ccWord, ccPunctuation }; private: int refCount; CellBuffer cb; CharClassify charClass; CaseFolder *pcf; char stylingMask; int endStyled; int styleClock; int enteredModification; int enteredStyling; int enteredReadOnlyCount; WatcherWithUserData *watchers; int lenWatchers; // ldSize is not real data - it is for dimensions and loops enum lineData { ldMarkers, ldLevels, ldState, ldMargin, ldAnnotation, ldSize }; PerLine *perLineData[ldSize]; bool matchesValid; RegexSearchBase *regex; public: LexInterface *pli; int stylingBits; int stylingBitsMask; int eolMode; /// Can also be SC_CP_UTF8 to enable UTF-8 mode int dbcsCodePage; int lineEndBitSet; int tabInChars; int indentInChars; int actualIndentInChars; bool useTabs; bool tabIndents; bool backspaceUnindents; DecorationList decorations; Document(); virtual ~Document(); int AddRef(); int SCI_METHOD Release(); virtual void Init(); int LineEndTypesSupported() const; bool SetDBCSCodePage(int dbcsCodePage_); int GetLineEndTypesAllowed() { return cb.GetLineEndTypes(); } bool SetLineEndTypesAllowed(int lineEndBitSet_); int GetLineEndTypesActive() { return cb.GetLineEndTypes(); } virtual void InsertLine(int line); virtual void RemoveLine(int line); int SCI_METHOD Version() const { return dvLineEnd; } void SCI_METHOD SetErrorStatus(int status); int SCI_METHOD LineFromPosition(int pos) const; int ClampPositionIntoDocument(int pos); bool IsCrLf(int pos); int LenChar(int pos); bool InGoodUTF8(int pos, int &start, int &end) const; int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true); int NextPosition(int pos, int moveDir) const; bool NextCharacter(int &pos, int moveDir); // Returns true if pos changed int SCI_METHOD CodePage() const; bool SCI_METHOD IsDBCSLeadByte(char ch) const; int SafeSegment(const char *text, int length, int lengthSegment); // Gateways to modifying document void ModifiedAt(int pos); void CheckReadOnly(); bool DeleteChars(int pos, int len); bool InsertString(int position, const char *s, int insertLength); int SCI_METHOD AddData(char *data, int length); void * SCI_METHOD ConvertToDocument(); int Undo(); int Redo(); bool CanUndo() { return cb.CanUndo(); } bool CanRedo() { return cb.CanRedo(); } void DeleteUndoHistory() { cb.DeleteUndoHistory(); } bool SetUndoCollection(bool collectUndo) { return cb.SetUndoCollection(collectUndo); } bool IsCollectingUndo() { return cb.IsCollectingUndo(); } void BeginUndoAction() { cb.BeginUndoAction(); } void EndUndoAction() { cb.EndUndoAction(); } void AddUndoAction(int token, bool mayCoalesce) { cb.AddUndoAction(token, mayCoalesce); } void SetSavePoint(); bool IsSavePoint() { return cb.IsSavePoint(); } const char * SCI_METHOD BufferPointer() { return cb.BufferPointer(); } const char *RangePointer(int position, int rangeLength) { return cb.RangePointer(position, rangeLength); } int GapPosition() const { return cb.GapPosition(); } int SCI_METHOD GetLineIndentation(int line); void SetLineIndentation(int line, int indent); int GetLineIndentPosition(int line) const; int GetColumn(int position); int CountCharacters(int startPos, int endPos); int FindColumn(int line, int column); void Indent(bool forwards, int lineBottom, int lineTop); static char *TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolModeWanted); void ConvertLineEnds(int eolModeSet); void SetReadOnly(bool set) { cb.SetReadOnly(set); } bool IsReadOnly() { return cb.IsReadOnly(); } bool InsertChar(int pos, char ch); bool InsertCString(int position, const char *s); void ChangeChar(int pos, char ch); void DelChar(int pos); void DelCharBack(int pos); char CharAt(int position) { return cb.CharAt(position); } void SCI_METHOD GetCharRange(char *buffer, int position, int lengthRetrieve) const { cb.GetCharRange(buffer, position, lengthRetrieve); } char SCI_METHOD StyleAt(int position) const { return cb.StyleAt(position); } void GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const { cb.GetStyleRange(buffer, position, lengthRetrieve); } int GetMark(int line); int MarkerNext(int lineStart, int mask) const; int AddMark(int line, int markerNum); void AddMarkSet(int line, int valueSet); void DeleteMark(int line, int markerNum); void DeleteMarkFromHandle(int markerHandle); void DeleteAllMarks(int markerNum); int LineFromHandle(int markerHandle); int SCI_METHOD LineStart(int line) const; int SCI_METHOD LineEnd(int line) const; int LineEndPosition(int position) const; bool IsLineEndPosition(int position) const; bool IsPositionInLineEnd(int position) const; int VCHomePosition(int position) const; int SCI_METHOD SetLevel(int line, int level); int SCI_METHOD GetLevel(int line) const; void ClearLevels(); int GetLastChild(int lineParent, int level=-1, int lastLine=-1); int GetFoldParent(int line); void GetHighlightDelimiters(HighlightDelimiter &hDelimiter, int line, int lastLine); void Indent(bool forwards); int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false); int NextWordStart(int pos, int delta); int NextWordEnd(int pos, int delta); int SCI_METHOD Length() const { return cb.Length(); } void Allocate(int newSize) { cb.Allocate(newSize); } bool MatchesWordOptions(bool word, bool wordStart, int pos, int length); bool HasCaseFolder(void) const; void SetCaseFolder(CaseFolder *pcf_); long FindText(int minPos, int maxPos, const char *search, bool caseSensitive, bool word, bool wordStart, bool regExp, int flags, int *length); const char *SubstituteByPosition(const char *text, int *length); int LinesTotal() const; void ChangeCase(Range r, bool makeUpperCase); void SetDefaultCharClasses(bool includeWordClass); void SetCharClasses(const unsigned char *chars, CharClassify::cc newCharClass); int GetCharsOfClass(CharClassify::cc charClass, unsigned char *buffer); void SetStylingBits(int bits); void SCI_METHOD StartStyling(int position, char mask); bool SCI_METHOD SetStyleFor(int length, char style); bool SCI_METHOD SetStyles(int length, const char *styles); int GetEndStyled() { return endStyled; } void EnsureStyledTo(int pos); void LexerChanged(); int GetStyleClock() { return styleClock; } void IncrementStyleClock(); void SCI_METHOD DecorationSetCurrentIndicator(int indicator) { decorations.SetCurrentIndicator(indicator); } void SCI_METHOD DecorationFillRange(int position, int value, int fillLength); int SCI_METHOD SetLineState(int line, int state); int SCI_METHOD GetLineState(int line) const; int GetMaxLineState(); void SCI_METHOD ChangeLexerState(int start, int end); StyledText MarginStyledText(int line); void MarginSetStyle(int line, int style); void MarginSetStyles(int line, const unsigned char *styles); void MarginSetText(int line, const char *text); int MarginLength(int line) const; void MarginClearAll(); bool AnnotationAny() const; StyledText AnnotationStyledText(int line); void AnnotationSetText(int line, const char *text); void AnnotationSetStyle(int line, int style); void AnnotationSetStyles(int line, const unsigned char *styles); int AnnotationLength(int line) const; int AnnotationLines(int line) const; void AnnotationClearAll(); bool AddWatcher(DocWatcher *watcher, void *userData); bool RemoveWatcher(DocWatcher *watcher, void *userData); const WatcherWithUserData *GetWatchers() const { return watchers; } int GetLenWatchers() const { return lenWatchers; } CharClassify::cc WordCharClass(unsigned char ch); bool IsWordPartSeparator(char ch); int WordPartLeft(int pos); int WordPartRight(int pos); int ExtendStyleRange(int pos, int delta, bool singleLine = false); bool IsWhiteLine(int line) const; int ParaUp(int pos); int ParaDown(int pos); int IndentSize() { return actualIndentInChars; } int BraceMatch(int position, int maxReStyle); private: bool IsWordStartAt(int pos); bool IsWordEndAt(int pos); bool IsWordAt(int start, int end); void NotifyModifyAttempt(); void NotifySavePoint(bool atSavePoint); void NotifyModified(DocModification mh); }; class UndoGroup { Document *pdoc; bool groupNeeded; public: UndoGroup(Document *pdoc_, bool groupNeeded_=true) : pdoc(pdoc_), groupNeeded(groupNeeded_) { if (groupNeeded) { pdoc->BeginUndoAction(); } } ~UndoGroup() { if (groupNeeded) { pdoc->EndUndoAction(); } } bool Needed() const { return groupNeeded; } }; /** * To optimise processing of document modifications by DocWatchers, a hint is passed indicating the * scope of the change. * If the DocWatcher is a document view then this can be used to optimise screen updating. */ class DocModification { public: int modificationType; int position; int length; int linesAdded; /**< Negative if lines deleted. */ const char *text; /**< Only valid for changes to text, not for changes to style. */ int line; int foldLevelNow; int foldLevelPrev; int annotationLinesAdded; int token; DocModification(int modificationType_, int position_=0, int length_=0, int linesAdded_=0, const char *text_=0, int line_=0) : modificationType(modificationType_), position(position_), length(length_), linesAdded(linesAdded_), text(text_), line(line_), foldLevelNow(0), foldLevelPrev(0), annotationLinesAdded(0), token(0) {} DocModification(int modificationType_, const Action &act, int linesAdded_=0) : modificationType(modificationType_), position(act.position), length(act.lenData), linesAdded(linesAdded_), text(act.data), line(0), foldLevelNow(0), foldLevelPrev(0), annotationLinesAdded(0), token(0) {} }; /** * A class that wants to receive notifications from a Document must be derived from DocWatcher * and implement the notification methods. It can then be added to the watcher list with AddWatcher. */ class DocWatcher { public: virtual ~DocWatcher() {} virtual void NotifyModifyAttempt(Document *doc, void *userData) = 0; virtual void NotifySavePoint(Document *doc, void *userData, bool atSavePoint) = 0; virtual void NotifyModified(Document *doc, DocModification mh, void *userData) = 0; virtual void NotifyDeleted(Document *doc, void *userData) = 0; virtual void NotifyStyleNeeded(Document *doc, void *userData, int endPos) = 0; virtual void NotifyLexerChanged(Document *doc, void *userData) = 0; virtual void NotifyErrorOccurred(Document *doc, void *userData, int status) = 0; }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/Editor.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 7049 7050 7051 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164 7165 7166 7167 7168 7169 7170 7171 7172 7173 7174 7175 7176 7177 7178 7179 7180 7181 7182 7183 7184 7185 7186 7187 7188 7189 7190 7191 7192 7193 7194 7195 7196 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315 7316 7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 7327 7328 7329 7330 7331 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 7358 7359 7360 7361 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 7392 7393 7394 7395 7396 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 7407 7408 7409 7410 7411 7412 7413 7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512 7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593 7594 7595 7596 7597 7598 7599 7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646 7647 7648 7649 7650 7651 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669 7670 7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752 7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 7820 7821 7822 7823 7824 7825 7826 7827 7828 7829 7830 7831 7832 7833 7834 7835 7836 7837 7838 7839 7840 7841 7842 7843 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 7936 7937 7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968 7969 7970 7971 7972 7973 7974 7975 7976 7977 7978 7979 7980 7981 7982 7983 7984 7985 7986 7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093 8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 8143 8144 8145 8146 8147 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213 8214 8215 8216 8217 8218 8219 8220 8221 8222 8223 8224 8225 8226 8227 8228 8229 8230 8231 8232 8233 8234 8235 8236 8237 8238 8239 8240 8241 8242 8243 8244 8245 8246 8247 8248 8249 8250 8251 8252 8253 8254 8255 8256 8257 8258 8259 8260 8261 8262 8263 8264 8265 8266 8267 8268 8269 8270 8271 8272 8273 8274 8275 8276 8277 8278 8279 8280 8281 8282 8283 8284 8285 8286 8287 8288 8289 8290 8291 8292 8293 8294 8295 8296 8297 8298 8299 8300 8301 8302 8303 8304 8305 8306 8307 8308 8309 8310 8311 8312 8313 8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 8335 8336 8337 8338 8339 8340 8341 8342 8343 8344 8345 8346 8347 8348 8349 8350 8351 8352 8353 8354 8355 8356 8357 8358 8359 8360 8361 8362 8363 8364 8365 8366 8367 8368 8369 8370 8371 8372 8373 8374 8375 8376 8377 8378 8379 8380 8381 8382 8383 8384 8385 8386 8387 8388 8389 8390 8391 8392 8393 8394 8395 8396 8397 8398 8399 8400 8401 8402 8403 8404 8405 8406 8407 8408 8409 8410 8411 8412 8413 8414 8415 8416 8417 8418 8419 8420 8421 8422 8423 8424 8425 8426 8427 8428 8429 8430 8431 8432 8433 8434 8435 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449 8450 8451 8452 8453 8454 8455 8456 8457 8458 8459 8460 8461 8462 8463 8464 8465 8466 8467 8468 8469 8470 8471 8472 8473 8474 8475 8476 8477 8478 8479 8480 8481 8482 8483 8484 8485 8486 8487 8488 8489 8490 8491 8492 8493 8494 8495 8496 8497 8498 8499 8500 8501 8502 8503 8504 8505 8506 8507 8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 8532 8533 8534 8535 8536 8537 8538 8539 8540 8541 8542 8543 8544 8545 8546 8547 8548 8549 8550 8551 8552 8553 8554 8555 8556 8557 8558 8559 8560 8561 8562 8563 8564 8565 8566 8567 8568 8569 8570 8571 8572 8573 8574 8575 8576 8577 8578 8579 8580 8581 8582 8583 8584 8585 8586 8587 8588 8589 8590 8591 8592 8593 8594 8595 8596 8597 8598 8599 8600 8601 8602 8603 8604 8605 8606 8607 8608 8609 8610 8611 8612 8613 8614 8615 8616 8617 8618 8619 8620 8621 8622 8623 8624 8625 8626 8627 8628 8629 8630 8631 8632 8633 8634 8635 8636 8637 8638 8639 8640 8641 8642 8643 8644 8645 8646 8647 8648 8649 8650 8651 8652 8653 8654 8655 8656 8657 8658 8659 8660 8661 8662 8663 8664 8665 8666 8667 8668 8669 8670 8671 8672 8673 8674 8675 8676 8677 8678 8679 8680 8681 8682 8683 8684 8685 8686 8687 8688 8689 8690 8691 8692 8693 8694 8695 8696 8697 8698 8699 8700 8701 8702 8703 8704 8705 8706 8707 8708 8709 8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 8732 8733 8734 8735 8736 8737 8738 8739 8740 8741 8742 8743 8744 8745 8746 8747 8748 8749 8750 8751 8752 8753 8754 8755 8756 8757 8758 8759 8760 8761 8762 8763 8764 8765 8766 8767 8768 8769 8770 8771 8772 8773 8774 8775 8776 8777 8778 8779 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 8813 8814 8815 8816 8817 8818 8819 8820 8821 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 8846 8847 8848 8849 8850 8851 8852 8853 8854 8855 8856 8857 8858 8859 8860 8861 8862 8863 8864 8865 8866 8867 8868 8869 8870 8871 8872 8873 8874 8875 8876 8877 8878 8879 8880 8881 8882 8883 8884 8885 8886 8887 8888 8889 8890 8891 8892 8893 8894 8895 8896 8897 8898 8899 8900 8901 8902 8903 8904 8905 8906 8907 8908 8909 8910 8911 8912 8913 8914 8915 8916 8917 8918 8919 8920 8921 8922 8923 8924 8925 8926 8927 8928 8929 8930 8931 8932 8933 8934 8935 8936 8937 8938 8939 8940 8941 8942 8943 8944 8945 8946 8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 8966 8967 8968 8969 8970 8971 8972 8973 8974 8975 8976 8977 8978 8979 8980 8981 8982 8983 8984 8985 8986 8987 8988 8989 8990 8991 8992 8993 8994 8995 8996 8997 8998 8999 9000 9001 9002 9003 9004 9005 9006 9007 9008 9009 9010 9011 9012 9013 9014 9015 9016 9017 9018 9019 9020 9021 9022 9023 9024 9025 9026 9027 9028 9029 9030 9031 9032 9033 9034 9035 9036 9037 9038 9039 9040 9041 9042 9043 9044 9045 9046 9047 9048 9049 9050 9051 9052 9053 9054 9055 9056 9057 9058 9059 9060 9061 9062 9063 9064 9065 9066 9067 9068 9069 9070 9071 9072 9073 9074 9075 9076 9077 9078 9079 9080 9081 9082 9083 9084 9085 9086 9087 9088 9089 9090 9091 9092 9093 9094 9095 9096 9097 9098 9099 9100 9101 9102 9103 9104 9105 9106 9107 9108 9109 9110 9111 9112 9113 9114 9115 9116 9117 9118 9119 9120 9121 9122 9123 9124 9125 9126 9127 9128 9129 9130 9131 9132 9133 9134 9135 9136 9137 9138 9139 9140 9141 9142 9143 9144 9145 9146 9147 9148 9149 9150 9151 9152 9153 9154 9155 9156 9157 9158 9159 9160 9161 9162 9163 9164 9165 9166 9167 9168 9169 9170 9171 9172 9173 9174 9175 9176 9177 9178 9179 9180 9181 9182 9183 9184 9185 9186 9187 9188 9189 9190 9191 9192 9193 9194 9195 9196 9197 9198 9199 9200 9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 9220 9221 9222 9223 9224 9225 9226 9227 9228 9229 9230 9231 9232 9233 9234 9235 9236 9237 9238 9239 9240 9241 9242 9243 9244 9245 9246 9247 9248 9249 9250 9251 9252 9253 9254 9255 9256 9257 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 9268 9269 9270 9271 9272 9273 9274 9275 9276 9277 9278 9279 9280 9281 9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295 9296 9297 9298 9299 9300 9301 9302 9303 9304 9305 9306 9307 9308 9309 9310 9311 9312 9313 9314 9315 9316 9317 9318 9319 9320 9321 9322 9323 9324 9325 9326 9327 9328 9329 9330 9331 9332 9333 9334 9335 9336 9337 9338 9339 9340 9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 9358 9359 9360 9361 9362 9363 9364 9365 9366 9367 9368 9369 9370 9371 9372 9373 9374 9375 9376 9377 9378 9379 9380 9381 9382 9383 9384 9385 9386 9387 9388 9389 9390 9391 9392 9393 9394 9395 9396 9397 9398 9399 9400 9401 9402 9403 9404 9405 9406 9407 9408 9409 9410 9411 9412 9413 9414 9415 9416 9417 9418 9419 9420 9421 9422 9423 9424 9425 9426 9427 9428 9429 9430 9431 9432 9433 9434 9435 9436 9437 9438 9439 9440 9441 9442 9443 9444 9445 9446 9447 9448 9449 9450 9451 9452 9453 9454 9455 9456 9457 9458 9459 9460 9461 9462 9463 9464 9465 9466 9467 9468 9469 9470 9471 9472 9473 9474 9475 9476 9477 9478 9479 9480 9481 9482 9483 9484 9485 9486 9487 9488 9489 9490 9491 9492 9493 9494 9495 9496 9497 9498 9499 9500 9501 9502 9503 9504 9505 9506 9507 9508 9509 9510 9511 9512 9513 9514 9515 9516 9517 9518 9519 9520 9521 9522 9523 |
// Scintilla source code edit control /** @file Editor.cxx ** Main code for the edit control. **/ // Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <ctype.h> #include <math.h> #include <assert.h> #include <string> #include <vector> #include <map> #include <algorithm> #include <memory> #include "Platform.h" #include "ILexer.h" #include "Scintilla.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" #include "ContractionState.h" #include "CellBuffer.h" #include "KeyMap.h" #include "Indicator.h" #include "XPM.h" #include "LineMarker.h" #include "Style.h" #include "ViewStyle.h" #include "CharClassify.h" #include "Decoration.h" #include "Document.h" #include "UniConversion.h" #include "Selection.h" #include "PositionCache.h" #include "Editor.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif /* return whether this modification represents an operation that may reasonably be deferred (not done now OR [possibly] at all) */ static bool CanDeferToLastStep(const DocModification &mh) { if (mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) return true; // CAN skip if (!(mh.modificationType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO))) return false; // MUST do if (mh.modificationType & SC_MULTISTEPUNDOREDO) return true; // CAN skip return false; // PRESUMABLY must do } static bool CanEliminate(const DocModification &mh) { return (mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) != 0; } /* return whether this modification represents the FINAL step in a [possibly lengthy] multi-step Undo/Redo sequence */ static bool IsLastStep(const DocModification &mh) { return (mh.modificationType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO)) != 0 && (mh.modificationType & SC_MULTISTEPUNDOREDO) != 0 && (mh.modificationType & SC_LASTSTEPINUNDOREDO) != 0 && (mh.modificationType & SC_MULTILINEUNDOREDO) != 0; } Caret::Caret() : active(false), on(false), period(500) {} Timer::Timer() : ticking(false), ticksToWait(0), tickerID(0) {} Idler::Idler() : state(false), idlerID(0) {} static inline bool IsControlCharacter(int ch) { // iscntrl returns true for lots of chars > 127 which are displayable return ch >= 0 && ch < ' '; } static inline bool IsAllSpacesOrTabs(char *s, unsigned int len) { for (unsigned int i = 0; i < len; i++) { // This is safe because IsSpaceOrTab() will return false for null terminators if (!IsSpaceOrTab(s[i])) return false; } return true; } Editor::Editor() { ctrlID = 0; stylesValid = false; technology = SC_TECHNOLOGY_DEFAULT; scaleRGBAImage = 100; printMagnification = 0; printColourMode = SC_PRINT_NORMAL; printWrapState = eWrapWord; cursorMode = SC_CURSORNORMAL; controlCharSymbol = 0; /* Draw the control characters */ hasFocus = false; hideSelection = false; inOverstrike = false; errorStatus = 0; mouseDownCaptures = true; bufferedDraw = true; twoPhaseDraw = true; lastClickTime = 0; dwellDelay = SC_TIME_FOREVER; ticksToDwell = SC_TIME_FOREVER; dwelling = false; ptMouseLast.x = 0; ptMouseLast.y = 0; inDragDrop = ddNone; dropWentOutside = false; posDrag = SelectionPosition(invalidPosition); posDrop = SelectionPosition(invalidPosition); hotSpotClickPos = INVALID_POSITION; selectionType = selChar; lastXChosen = 0; lineAnchorPos = 0; originalAnchorPos = 0; wordSelectAnchorStartPos = 0; wordSelectAnchorEndPos = 0; wordSelectInitialCaretPos = -1; primarySelection = true; caretXPolicy = CARET_SLOP | CARET_EVEN; caretXSlop = 50; caretYPolicy = CARET_EVEN; caretYSlop = 0; visiblePolicy = 0; visibleSlop = 0; searchAnchor = 0; xOffset = 0; xCaretMargin = 50; horizontalScrollBarVisible = true; scrollWidth = 2000; trackLineWidth = false; lineWidthMaxSeen = 0; verticalScrollBarVisible = true; endAtLastLine = true; caretSticky = SC_CARETSTICKY_OFF; marginOptions = SC_MARGINOPTION_NONE; multipleSelection = false; additionalSelectionTyping = false; multiPasteMode = SC_MULTIPASTE_ONCE; additionalCaretsBlink = true; additionalCaretsVisible = true; virtualSpaceOptions = SCVS_NONE; pixmapLine = 0; pixmapSelMargin = 0; pixmapSelPattern = 0; pixmapSelPatternOffset1 = 0; pixmapIndentGuide = 0; pixmapIndentGuideHighlight = 0; targetStart = 0; targetEnd = 0; searchFlags = 0; topLine = 0; posTopLine = 0; lengthForEncode = -1; needUpdateUI = 0; ContainerNeedsUpdate(SC_UPDATE_CONTENT); braces[0] = invalidPosition; braces[1] = invalidPosition; bracesMatchStyle = STYLE_BRACEBAD; highlightGuideColumn = 0; theEdge = 0; paintState = notPainting; willRedrawAll = false; modEventMask = SC_MODEVENTMASKALL; pdoc = new Document(); pdoc->AddRef(); pdoc->AddWatcher(this, 0); recordingMacro = false; foldFlags = 0; wrapState = eWrapNone; wrapWidth = LineLayout::wrapWidthInfinite; wrapStart = wrapLineLarge; wrapEnd = wrapLineLarge; wrapVisualFlags = 0; wrapVisualFlagsLocation = 0; wrapVisualStartIndent = 0; wrapIndentMode = SC_WRAPINDENT_FIXED; convertPastes = true; marginNumberPadding = 3; ctrlCharPadding = 3; // +3 For a blank on front and rounded edge each side lastSegItalicsOffset = 2; hsStart = -1; hsEnd = -1; llc.SetLevel(LineLayoutCache::llcCaret); posCache.SetSize(0x400); } Editor::~Editor() { pdoc->RemoveWatcher(this, 0); pdoc->Release(); pdoc = 0; DropGraphics(true); } void Editor::Finalise() { SetIdle(false); CancelModes(); } void Editor::DropGraphics(bool freeObjects) { if (freeObjects) { delete pixmapLine; pixmapLine = 0; delete pixmapSelMargin; pixmapSelMargin = 0; delete pixmapSelPattern; pixmapSelPattern = 0; delete pixmapSelPatternOffset1; pixmapSelPatternOffset1 = 0; delete pixmapIndentGuide; pixmapIndentGuide = 0; delete pixmapIndentGuideHighlight; pixmapIndentGuideHighlight = 0; } else { if (pixmapLine) pixmapLine->Release(); if (pixmapSelMargin) pixmapSelMargin->Release(); if (pixmapSelPattern) pixmapSelPattern->Release(); if (pixmapSelPatternOffset1) pixmapSelPatternOffset1->Release(); if (pixmapIndentGuide) pixmapIndentGuide->Release(); if (pixmapIndentGuideHighlight) pixmapIndentGuideHighlight->Release(); } } void Editor::AllocateGraphics() { if (!pixmapLine) pixmapLine = Surface::Allocate(technology); if (!pixmapSelMargin) pixmapSelMargin = Surface::Allocate(technology); if (!pixmapSelPattern) pixmapSelPattern = Surface::Allocate(technology); if (!pixmapSelPatternOffset1) pixmapSelPatternOffset1 = Surface::Allocate(technology); if (!pixmapIndentGuide) pixmapIndentGuide = Surface::Allocate(technology); if (!pixmapIndentGuideHighlight) pixmapIndentGuideHighlight = Surface::Allocate(technology); } void Editor::InvalidateStyleData() { stylesValid = false; vs.technology = technology; DropGraphics(false); AllocateGraphics(); llc.Invalidate(LineLayout::llInvalid); posCache.Clear(); } void Editor::InvalidateStyleRedraw() { NeedWrapping(); InvalidateStyleData(); Redraw(); } void Editor::RefreshStyleData() { if (!stylesValid) { stylesValid = true; AutoSurface surface(this); if (surface) { vs.Refresh(*surface); } SetScrollBars(); SetRectangularRange(); } } Point Editor::GetVisibleOriginInMain() { return Point(0,0); } Point Editor::DocumentPointFromView(Point ptView) { Point ptDocument = ptView; if (wMargin.GetID()) { Point ptOrigin = GetVisibleOriginInMain(); ptDocument.x += ptOrigin.x; ptDocument.y += ptOrigin.y; } else { ptDocument.x += xOffset; ptDocument.y += topLine * vs.lineHeight; } return ptDocument; } int Editor::TopLineOfMain() { if (wMargin.GetID()) return 0; else return topLine; } PRectangle Editor::GetClientRectangle() { return wMain.GetClientPosition(); } PRectangle Editor::GetTextRectangle() { PRectangle rc = GetClientRectangle(); rc.left += vs.textStart; rc.right -= vs.rightMarginWidth; return rc; } int Editor::LinesOnScreen() { PRectangle rcClient = GetClientRectangle(); int htClient = rcClient.bottom - rcClient.top; //Platform::DebugPrintf("lines on screen = %d\n", htClient / lineHeight + 1); return htClient / vs.lineHeight; } int Editor::LinesToScroll() { int retVal = LinesOnScreen() - 1; if (retVal < 1) return 1; else return retVal; } int Editor::MaxScrollPos() { //Platform::DebugPrintf("Lines %d screen = %d maxScroll = %d\n", //LinesTotal(), LinesOnScreen(), LinesTotal() - LinesOnScreen() + 1); int retVal = cs.LinesDisplayed(); if (endAtLastLine) { retVal -= LinesOnScreen(); } else { retVal--; } if (retVal < 0) { return 0; } else { return retVal; } } const char *ControlCharacterString(unsigned char ch) { const char *reps[] = { "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" }; if (ch < (sizeof(reps) / sizeof(reps[0]))) { return reps[ch]; } else { return "BAD"; } } /** * Convenience class to ensure LineLayout objects are always disposed. */ class AutoLineLayout { LineLayoutCache &llc; LineLayout *ll; AutoLineLayout &operator=(const AutoLineLayout &); public: AutoLineLayout(LineLayoutCache &llc_, LineLayout *ll_) : llc(llc_), ll(ll_) {} ~AutoLineLayout() { llc.Dispose(ll); ll = 0; } LineLayout *operator->() const { return ll; } operator LineLayout *() const { return ll; } void Set(LineLayout *ll_) { llc.Dispose(ll); ll = ll_; } }; SelectionPosition Editor::ClampPositionIntoDocument(SelectionPosition sp) const { if (sp.Position() < 0) { return SelectionPosition(0); } else if (sp.Position() > pdoc->Length()) { return SelectionPosition(pdoc->Length()); } else { // If not at end of line then set offset to 0 if (!pdoc->IsLineEndPosition(sp.Position())) sp.SetVirtualSpace(0); return sp; } } Point Editor::LocationFromPosition(SelectionPosition pos) { Point pt; RefreshStyleData(); if (pos.Position() == INVALID_POSITION) return pt; int line = pdoc->LineFromPosition(pos.Position()); int lineVisible = cs.DisplayFromDoc(line); //Platform::DebugPrintf("line=%d\n", line); AutoSurface surface(this); AutoLineLayout ll(llc, RetrieveLineLayout(line)); if (surface && ll) { // -1 because of adding in for visible lines in following loop. pt.y = (lineVisible - topLine - 1) * vs.lineHeight; pt.x = 0; unsigned int posLineStart = pdoc->LineStart(line); LayoutLine(line, surface, vs, ll, wrapWidth); int posInLine = pos.Position() - posLineStart; // In case of very long line put x at arbitrary large position if (posInLine > ll->maxLineLength) { pt.x = ll->positions[ll->maxLineLength] - ll->positions[ll->LineStart(ll->lines)]; } for (int subLine = 0; subLine < ll->lines; subLine++) { if ((posInLine >= ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine + 1))) { pt.x = ll->positions[posInLine] - ll->positions[ll->LineStart(subLine)]; if (ll->wrapIndent != 0) { int lineStart = ll->LineStart(subLine); if (lineStart != 0) // Wrapped pt.x += ll->wrapIndent; } } if (posInLine >= ll->LineStart(subLine)) { pt.y += vs.lineHeight; } } pt.x += vs.textStart - xOffset; } pt.x += pos.VirtualSpace() * vs.styles[ll->EndLineStyle()].spaceWidth; return pt; } Point Editor::LocationFromPosition(int pos) { return LocationFromPosition(SelectionPosition(pos)); } int Editor::XFromPosition(int pos) { Point pt = LocationFromPosition(pos); return pt.x - vs.textStart + xOffset; } int Editor::XFromPosition(SelectionPosition sp) { Point pt = LocationFromPosition(sp); return pt.x - vs.textStart + xOffset; } int Editor::LineFromLocation(Point pt) { return cs.DocFromDisplay(pt.y / vs.lineHeight + topLine); } void Editor::SetTopLine(int topLineNew) { if ((topLine != topLineNew) && (topLineNew >= 0)) { topLine = topLineNew; ContainerNeedsUpdate(SC_UPDATE_V_SCROLL); } posTopLine = pdoc->LineStart(cs.DocFromDisplay(topLine)); } SelectionPosition Editor::SPositionFromLocation(Point pt, bool canReturnInvalid, bool charPosition, bool virtualSpace) { RefreshStyleData(); if (canReturnInvalid) { PRectangle rcClient = GetTextRectangle(); if (!rcClient.Contains(pt)) return SelectionPosition(INVALID_POSITION); if (pt.x < vs.textStart) return SelectionPosition(INVALID_POSITION); if (pt.y < 0) return SelectionPosition(INVALID_POSITION); } pt = DocumentPointFromView(pt); pt.x = pt.x - vs.textStart; int visibleLine = (int)floor((double)(pt.y / vs.lineHeight)); if (!canReturnInvalid && (visibleLine < 0)) visibleLine = 0; int lineDoc = cs.DocFromDisplay(visibleLine); if (canReturnInvalid && (lineDoc < 0)) return SelectionPosition(INVALID_POSITION); if (lineDoc >= pdoc->LinesTotal()) return SelectionPosition(canReturnInvalid ? INVALID_POSITION : pdoc->Length()); unsigned int posLineStart = pdoc->LineStart(lineDoc); SelectionPosition retVal(canReturnInvalid ? INVALID_POSITION : static_cast<int>(posLineStart)); AutoSurface surface(this); AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); if (surface && ll) { LayoutLine(lineDoc, surface, vs, ll, wrapWidth); int lineStartSet = cs.DisplayFromDoc(lineDoc); int subLine = visibleLine - lineStartSet; if (subLine < ll->lines) { int lineStart = ll->LineStart(subLine); int lineEnd = ll->LineLastVisible(subLine); XYPOSITION subLineStart = ll->positions[lineStart]; if (ll->wrapIndent != 0) { if (lineStart != 0) // Wrapped pt.x -= ll->wrapIndent; } int i = ll->FindBefore(pt.x + subLineStart, lineStart, lineEnd); while (i < lineEnd) { if (charPosition) { if ((pt.x + subLineStart) < (ll->positions[i + 1])) { return SelectionPosition(pdoc->MovePositionOutsideChar(i + posLineStart, 1)); } } else { if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) { return SelectionPosition(pdoc->MovePositionOutsideChar(i + posLineStart, 1)); } } i++; } if (virtualSpace) { const XYPOSITION spaceWidth = vs.styles[ll->EndLineStyle()].spaceWidth; int spaceOffset = (pt.x + subLineStart - ll->positions[lineEnd] + spaceWidth / 2) / spaceWidth; return SelectionPosition(lineEnd + posLineStart, spaceOffset); } else if (canReturnInvalid) { if (pt.x < (ll->positions[lineEnd] - subLineStart)) { return SelectionPosition(pdoc->MovePositionOutsideChar(lineEnd + posLineStart, 1)); } } else { return SelectionPosition(lineEnd + posLineStart); } } if (!canReturnInvalid) return SelectionPosition(ll->numCharsInLine + posLineStart); } return retVal; } int Editor::PositionFromLocation(Point pt, bool canReturnInvalid, bool charPosition) { return SPositionFromLocation(pt, canReturnInvalid, charPosition, false).Position(); } /** * Find the document position corresponding to an x coordinate on a particular document line. * Ensure is between whole characters when document is in multi-byte or UTF-8 mode. */ SelectionPosition Editor::SPositionFromLineX(int lineDoc, int x) { RefreshStyleData(); if (lineDoc >= pdoc->LinesTotal()) return SelectionPosition(pdoc->Length()); //Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine); AutoSurface surface(this); AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); int retVal = 0; if (surface && ll) { unsigned int posLineStart = pdoc->LineStart(lineDoc); LayoutLine(lineDoc, surface, vs, ll, wrapWidth); int subLine = 0; int lineStart = ll->LineStart(subLine); int lineEnd = ll->LineLastVisible(subLine); XYPOSITION subLineStart = ll->positions[lineStart]; XYPOSITION newX = x; if (ll->wrapIndent != 0) { if (lineStart != 0) // Wrapped newX -= ll->wrapIndent; } int i = ll->FindBefore(newX + subLineStart, lineStart, lineEnd); while (i < lineEnd) { if ((newX + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) { retVal = pdoc->MovePositionOutsideChar(i + posLineStart, 1); return SelectionPosition(retVal); } i++; } const XYPOSITION spaceWidth = vs.styles[ll->EndLineStyle()].spaceWidth; int spaceOffset = (newX + subLineStart - ll->positions[lineEnd] + spaceWidth / 2) / spaceWidth; return SelectionPosition(lineEnd + posLineStart, spaceOffset); } return SelectionPosition(retVal); } int Editor::PositionFromLineX(int lineDoc, int x) { return SPositionFromLineX(lineDoc, x).Position(); } /** * If painting then abandon the painting because a wider redraw is needed. * @return true if calling code should stop drawing. */ bool Editor::AbandonPaint() { if ((paintState == painting) && !paintingAllText) { paintState = paintAbandoned; } return paintState == paintAbandoned; } void Editor::RedrawRect(PRectangle rc) { //Platform::DebugPrintf("Redraw %0d,%0d - %0d,%0d\n", rc.left, rc.top, rc.right, rc.bottom); // Clip the redraw rectangle into the client area PRectangle rcClient = GetClientRectangle(); if (rc.top < rcClient.top) rc.top = rcClient.top; if (rc.bottom > rcClient.bottom) rc.bottom = rcClient.bottom; if (rc.left < rcClient.left) rc.left = rcClient.left; if (rc.right > rcClient.right) rc.right = rcClient.right; if ((rc.bottom > rc.top) && (rc.right > rc.left)) { wMain.InvalidateRectangle(rc); } } void Editor::Redraw() { //Platform::DebugPrintf("Redraw all\n"); PRectangle rcClient = GetClientRectangle(); wMain.InvalidateRectangle(rcClient); if (wMargin.GetID()) wMargin.InvalidateAll(); //wMain.InvalidateAll(); } void Editor::RedrawSelMargin(int line, bool allAfter) { if (!AbandonPaint()) { if (vs.maskInLine) { Redraw(); } else { PRectangle rcSelMargin = GetClientRectangle(); rcSelMargin.right = rcSelMargin.left + vs.fixedColumnWidth; if (line != -1) { int position = pdoc->LineStart(line); PRectangle rcLine = RectangleFromRange(position, position); // Inflate line rectangle if there are image markers with height larger than line height if (vs.largestMarkerHeight > vs.lineHeight) { int delta = (vs.largestMarkerHeight - vs.lineHeight + 1) / 2; rcLine.top -= delta; rcLine.bottom += delta; if (rcLine.top < rcSelMargin.top) rcLine.top = rcSelMargin.top; if (rcLine.bottom > rcSelMargin.bottom) rcLine.bottom = rcSelMargin.bottom; } rcSelMargin.top = rcLine.top; if (!allAfter) rcSelMargin.bottom = rcLine.bottom; } if (wMargin.GetID()) { Point ptOrigin = GetVisibleOriginInMain(); rcSelMargin.Move(-ptOrigin.x, -ptOrigin.y); wMargin.InvalidateRectangle(rcSelMargin); } else { wMain.InvalidateRectangle(rcSelMargin); } } } } PRectangle Editor::RectangleFromRange(int start, int end) { int minPos = start; if (minPos > end) minPos = end; int maxPos = start; if (maxPos < end) maxPos = end; int minLine = cs.DisplayFromDoc(pdoc->LineFromPosition(minPos)); int lineDocMax = pdoc->LineFromPosition(maxPos); int maxLine = cs.DisplayFromDoc(lineDocMax) + cs.GetHeight(lineDocMax) - 1; PRectangle rcClient = GetTextRectangle(); PRectangle rc; const int leftTextOverlap = ((xOffset == 0) && (vs.leftMarginWidth > 0)) ? 1 : 0; rc.left = vs.textStart - leftTextOverlap; rc.top = (minLine - TopLineOfMain()) * vs.lineHeight; if (rc.top < rcClient.top) rc.top = rcClient.top; rc.right = rcClient.right; rc.bottom = (maxLine - TopLineOfMain() + 1) * vs.lineHeight; return rc; } void Editor::InvalidateRange(int start, int end) { RedrawRect(RectangleFromRange(start, end)); } int Editor::CurrentPosition() { return sel.MainCaret(); } bool Editor::SelectionEmpty() { return sel.Empty(); } SelectionPosition Editor::SelectionStart() { return sel.RangeMain().Start(); } SelectionPosition Editor::SelectionEnd() { return sel.RangeMain().End(); } void Editor::SetRectangularRange() { if (sel.IsRectangular()) { int xAnchor = XFromPosition(sel.Rectangular().anchor); int xCaret = XFromPosition(sel.Rectangular().caret); if (sel.selType == Selection::selThin) { xCaret = xAnchor; } int lineAnchorRect = pdoc->LineFromPosition(sel.Rectangular().anchor.Position()); int lineCaret = pdoc->LineFromPosition(sel.Rectangular().caret.Position()); int increment = (lineCaret > lineAnchorRect) ? 1 : -1; for (int line=lineAnchorRect; line != lineCaret+increment; line += increment) { SelectionRange range(SPositionFromLineX(line, xCaret), SPositionFromLineX(line, xAnchor)); if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) == 0) range.ClearVirtualSpace(); if (line == lineAnchorRect) sel.SetSelection(range); else sel.AddSelectionWithoutTrim(range); } } } void Editor::ThinRectangularRange() { if (sel.IsRectangular()) { sel.selType = Selection::selThin; if (sel.Rectangular().caret < sel.Rectangular().anchor) { sel.Rectangular() = SelectionRange(sel.Range(sel.Count()-1).caret, sel.Range(0).anchor); } else { sel.Rectangular() = SelectionRange(sel.Range(sel.Count()-1).anchor, sel.Range(0).caret); } SetRectangularRange(); } } void Editor::InvalidateSelection(SelectionRange newMain, bool invalidateWholeSelection) { if (sel.Count() > 1 || !(sel.RangeMain().anchor == newMain.anchor) || sel.IsRectangular()) { invalidateWholeSelection = true; } int firstAffected = Platform::Minimum(sel.RangeMain().Start().Position(), newMain.Start().Position()); // +1 for lastAffected ensures caret repainted int lastAffected = Platform::Maximum(newMain.caret.Position()+1, newMain.anchor.Position()); lastAffected = Platform::Maximum(lastAffected, sel.RangeMain().End().Position()); if (invalidateWholeSelection) { for (size_t r=0; r<sel.Count(); r++) { firstAffected = Platform::Minimum(firstAffected, sel.Range(r).caret.Position()); firstAffected = Platform::Minimum(firstAffected, sel.Range(r).anchor.Position()); lastAffected = Platform::Maximum(lastAffected, sel.Range(r).caret.Position()+1); lastAffected = Platform::Maximum(lastAffected, sel.Range(r).anchor.Position()); } } ContainerNeedsUpdate(SC_UPDATE_SELECTION); InvalidateRange(firstAffected, lastAffected); } void Editor::SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_) { currentPos_ = ClampPositionIntoDocument(currentPos_); anchor_ = ClampPositionIntoDocument(anchor_); int currentLine = pdoc->LineFromPosition(currentPos_.Position()); /* For Line selection - ensure the anchor and caret are always at the beginning and end of the region lines. */ if (sel.selType == Selection::selLines) { if (currentPos_ > anchor_) { anchor_ = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(anchor_.Position()))); currentPos_ = SelectionPosition(pdoc->LineEnd(pdoc->LineFromPosition(currentPos_.Position()))); } else { currentPos_ = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(currentPos_.Position()))); anchor_ = SelectionPosition(pdoc->LineEnd(pdoc->LineFromPosition(anchor_.Position()))); } } SelectionRange rangeNew(currentPos_, anchor_); if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) { InvalidateSelection(rangeNew); } sel.RangeMain() = rangeNew; SetRectangularRange(); ClaimSelection(); if (highlightDelimiter.NeedsDrawing(currentLine)) { RedrawSelMargin(); } QueueIdleWork(WorkNeeded::workUpdateUI); } void Editor::SetSelection(int currentPos_, int anchor_) { SetSelection(SelectionPosition(currentPos_), SelectionPosition(anchor_)); } // Just move the caret on the main selection void Editor::SetSelection(SelectionPosition currentPos_) { currentPos_ = ClampPositionIntoDocument(currentPos_); int currentLine = pdoc->LineFromPosition(currentPos_.Position()); if (sel.Count() > 1 || !(sel.RangeMain().caret == currentPos_)) { InvalidateSelection(SelectionRange(currentPos_)); } if (sel.IsRectangular()) { sel.Rectangular() = SelectionRange(SelectionPosition(currentPos_), sel.Rectangular().anchor); SetRectangularRange(); } else { sel.RangeMain() = SelectionRange(SelectionPosition(currentPos_), sel.RangeMain().anchor); } ClaimSelection(); if (highlightDelimiter.NeedsDrawing(currentLine)) { RedrawSelMargin(); } QueueIdleWork(WorkNeeded::workUpdateUI); } void Editor::SetSelection(int currentPos_) { SetSelection(SelectionPosition(currentPos_)); } void Editor::SetEmptySelection(SelectionPosition currentPos_) { int currentLine = pdoc->LineFromPosition(currentPos_.Position()); SelectionRange rangeNew(ClampPositionIntoDocument(currentPos_)); if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) { InvalidateSelection(rangeNew); } sel.Clear(); sel.RangeMain() = rangeNew; SetRectangularRange(); ClaimSelection(); if (highlightDelimiter.NeedsDrawing(currentLine)) { RedrawSelMargin(); } QueueIdleWork(WorkNeeded::workUpdateUI); } void Editor::SetEmptySelection(int currentPos_) { SetEmptySelection(SelectionPosition(currentPos_)); } bool Editor::RangeContainsProtected(int start, int end) const { if (vs.ProtectionActive()) { if (start > end) { int t = start; start = end; end = t; } int mask = pdoc->stylingBitsMask; for (int pos = start; pos < end; pos++) { if (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected()) return true; } } return false; } bool Editor::SelectionContainsProtected() { for (size_t r=0; r<sel.Count(); r++) { if (RangeContainsProtected(sel.Range(r).Start().Position(), sel.Range(r).End().Position())) { return true; } } return false; } /** * Asks document to find a good position and then moves out of any invisible positions. */ int Editor::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) const { return MovePositionOutsideChar(SelectionPosition(pos), moveDir, checkLineEnd).Position(); } SelectionPosition Editor::MovePositionOutsideChar(SelectionPosition pos, int moveDir, bool checkLineEnd) const { int posMoved = pdoc->MovePositionOutsideChar(pos.Position(), moveDir, checkLineEnd); if (posMoved != pos.Position()) pos.SetPosition(posMoved); if (vs.ProtectionActive()) { int mask = pdoc->stylingBitsMask; if (moveDir > 0) { if ((pos.Position() > 0) && vs.styles[pdoc->StyleAt(pos.Position() - 1) & mask].IsProtected()) { while ((pos.Position() < pdoc->Length()) && (vs.styles[pdoc->StyleAt(pos.Position()) & mask].IsProtected())) pos.Add(1); } } else if (moveDir < 0) { if (vs.styles[pdoc->StyleAt(pos.Position()) & mask].IsProtected()) { while ((pos.Position() > 0) && (vs.styles[pdoc->StyleAt(pos.Position() - 1) & mask].IsProtected())) pos.Add(-1); } } } return pos; } int Editor::MovePositionTo(SelectionPosition newPos, Selection::selTypes selt, bool ensureVisible) { bool simpleCaret = (sel.Count() == 1) && sel.Empty(); SelectionPosition spCaret = sel.Last(); int delta = newPos.Position() - sel.MainCaret(); newPos = ClampPositionIntoDocument(newPos); newPos = MovePositionOutsideChar(newPos, delta); if (!multipleSelection && sel.IsRectangular() && (selt == Selection::selStream)) { // Can't turn into multiple selection so clear additional selections InvalidateSelection(SelectionRange(newPos), true); SelectionRange rangeMain = sel.RangeMain(); sel.SetSelection(rangeMain); } if (!sel.IsRectangular() && (selt == Selection::selRectangle)) { // Switching to rectangular SelectionRange rangeMain = sel.RangeMain(); sel.Clear(); sel.Rectangular() = rangeMain; } if (selt != Selection::noSel) { sel.selType = selt; } if (selt != Selection::noSel || sel.MoveExtends()) { SetSelection(newPos); } else { SetEmptySelection(newPos); } ShowCaretAtCurrentPosition(); int currentLine = pdoc->LineFromPosition(newPos.Position()); if (ensureVisible) { // In case in need of wrapping to ensure DisplayFromDoc works. if (currentLine >= wrapStart) WrapLines(true, -1); XYScrollPosition newXY = XYScrollToMakeVisible( SelectionRange(posDrag.IsValid() ? posDrag : sel.RangeMain().caret), xysDefault); if (simpleCaret && (newXY.xOffset == xOffset)) { // simple vertical scroll then invalidate ScrollTo(newXY.topLine); InvalidateSelection(SelectionRange(spCaret), true); } else { SetXYScroll(newXY); } } if (highlightDelimiter.NeedsDrawing(currentLine)) { RedrawSelMargin(); } return 0; } int Editor::MovePositionTo(int newPos, Selection::selTypes selt, bool ensureVisible) { return MovePositionTo(SelectionPosition(newPos), selt, ensureVisible); } SelectionPosition Editor::MovePositionSoVisible(SelectionPosition pos, int moveDir) { pos = ClampPositionIntoDocument(pos); pos = MovePositionOutsideChar(pos, moveDir); int lineDoc = pdoc->LineFromPosition(pos.Position()); if (cs.GetVisible(lineDoc)) { return pos; } else { int lineDisplay = cs.DisplayFromDoc(lineDoc); if (moveDir > 0) { // lineDisplay is already line before fold as lines in fold use display line of line after fold lineDisplay = Platform::Clamp(lineDisplay, 0, cs.LinesDisplayed()); return SelectionPosition(pdoc->LineStart(cs.DocFromDisplay(lineDisplay))); } else { lineDisplay = Platform::Clamp(lineDisplay - 1, 0, cs.LinesDisplayed()); return SelectionPosition(pdoc->LineEnd(cs.DocFromDisplay(lineDisplay))); } } } SelectionPosition Editor::MovePositionSoVisible(int pos, int moveDir) { return MovePositionSoVisible(SelectionPosition(pos), moveDir); } Point Editor::PointMainCaret() { return LocationFromPosition(sel.Range(sel.Main()).caret); } /** * Choose the x position that the caret will try to stick to * as it moves up and down. */ void Editor::SetLastXChosen() { Point pt = PointMainCaret(); lastXChosen = pt.x + xOffset; } void Editor::ScrollTo(int line, bool moveThumb) { int topLineNew = Platform::Clamp(line, 0, MaxScrollPos()); if (topLineNew != topLine) { // Try to optimise small scrolls #ifndef UNDER_CE int linesToMove = topLine - topLineNew; bool performBlit = (abs(linesToMove) <= 10) && (paintState == notPainting); willRedrawAll = !performBlit; #endif SetTopLine(topLineNew); // Optimize by styling the view as this will invalidate any needed area // which could abort the initial paint if discovered later. StyleToPositionInView(PositionAfterArea(GetClientRectangle())); #ifndef UNDER_CE // Perform redraw rather than scroll if many lines would be redrawn anyway. if (performBlit) { ScrollText(linesToMove); } else { Redraw(); } willRedrawAll = false; #else Redraw(); #endif if (moveThumb) { SetVerticalScrollPos(); } } } void Editor::ScrollText(int /* linesToMove */) { //Platform::DebugPrintf("Editor::ScrollText %d\n", linesToMove); Redraw(); } void Editor::HorizontalScrollTo(int xPos) { //Platform::DebugPrintf("HorizontalScroll %d\n", xPos); if (xPos < 0) xPos = 0; if ((wrapState == eWrapNone) && (xOffset != xPos)) { xOffset = xPos; ContainerNeedsUpdate(SC_UPDATE_H_SCROLL); SetHorizontalScrollPos(); RedrawRect(GetClientRectangle()); } } void Editor::VerticalCentreCaret() { int lineDoc = pdoc->LineFromPosition(sel.IsRectangular() ? sel.Rectangular().caret.Position() : sel.MainCaret()); int lineDisplay = cs.DisplayFromDoc(lineDoc); int newTop = lineDisplay - (LinesOnScreen() / 2); if (topLine != newTop) { SetTopLine(newTop > 0 ? newTop : 0); RedrawRect(GetClientRectangle()); } } // Avoid 64 bit compiler warnings. // Scintilla does not support text buffers larger than 2**31 static int istrlen(const char *s) { return static_cast<int>(strlen(s)); } void Editor::MoveSelectedLines(int lineDelta) { // if selection doesn't start at the beginning of the line, set the new start int selectionStart = SelectionStart().Position(); int startLine = pdoc->LineFromPosition(selectionStart); int beginningOfStartLine = pdoc->LineStart(startLine); selectionStart = beginningOfStartLine; // if selection doesn't end at the beginning of a line greater than that of the start, // then set it at the beginning of the next one int selectionEnd = SelectionEnd().Position(); int endLine = pdoc->LineFromPosition(selectionEnd); int beginningOfEndLine = pdoc->LineStart(endLine); bool appendEol = false; if (selectionEnd > beginningOfEndLine || selectionStart == selectionEnd) { selectionEnd = pdoc->LineStart(endLine + 1); appendEol = (selectionEnd == pdoc->Length() && pdoc->LineFromPosition(selectionEnd) == endLine); } // if there's nowhere for the selection to move // (i.e. at the beginning going up or at the end going down), // stop it right there! if ((selectionStart == 0 && lineDelta < 0) || (selectionEnd == pdoc->Length() && lineDelta > 0) || selectionStart == selectionEnd) { return; } UndoGroup ug(pdoc); if (lineDelta > 0 && selectionEnd == pdoc->LineStart(pdoc->LinesTotal() - 1)) { SetSelection(pdoc->MovePositionOutsideChar(selectionEnd - 1, -1), selectionEnd); ClearSelection(); selectionEnd = CurrentPosition(); } SetSelection(selectionStart, selectionEnd); SelectionText selectedText; CopySelectionRange(&selectedText); int selectionLength = SelectionRange(selectionStart, selectionEnd).Length(); Point currentLocation = LocationFromPosition(CurrentPosition()); int currentLine = LineFromLocation(currentLocation); if (appendEol) SetSelection(pdoc->MovePositionOutsideChar(selectionStart - 1, -1), selectionEnd); ClearSelection(); const char *eol = StringFromEOLMode(pdoc->eolMode); if (currentLine + lineDelta >= pdoc->LinesTotal()) pdoc->InsertCString(pdoc->Length(), eol); GoToLine(currentLine + lineDelta); pdoc->InsertCString(CurrentPosition(), selectedText.s); if (appendEol) { pdoc->InsertCString(CurrentPosition() + selectionLength, eol); selectionLength += istrlen(eol); } SetSelection(CurrentPosition(), CurrentPosition() + selectionLength); } void Editor::MoveSelectedLinesUp() { MoveSelectedLines(-1); } void Editor::MoveSelectedLinesDown() { MoveSelectedLines(1); } void Editor::MoveCaretInsideView(bool ensureVisible) { PRectangle rcClient = GetTextRectangle(); Point pt = PointMainCaret(); if (pt.y < rcClient.top) { MovePositionTo(SPositionFromLocation( Point(lastXChosen - xOffset, rcClient.top), false, false, UserVirtualSpace()), Selection::noSel, ensureVisible); } else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) { int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen() - 1) * vs.lineHeight; MovePositionTo(SPositionFromLocation( Point(lastXChosen - xOffset, rcClient.top + yOfLastLineFullyDisplayed), false, false, UserVirtualSpace()), Selection::noSel, ensureVisible); } } int Editor::DisplayFromPosition(int pos) { int lineDoc = pdoc->LineFromPosition(pos); int lineDisplay = cs.DisplayFromDoc(lineDoc); AutoSurface surface(this); AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc)); if (surface && ll) { LayoutLine(lineDoc, surface, vs, ll, wrapWidth); unsigned int posLineStart = pdoc->LineStart(lineDoc); int posInLine = pos - posLineStart; lineDisplay--; // To make up for first increment ahead. for (int subLine = 0; subLine < ll->lines; subLine++) { if (posInLine >= ll->LineStart(subLine)) { lineDisplay++; } } } return lineDisplay; } /** * Ensure the caret is reasonably visible in context. * Caret policy in SciTE If slop is set, we can define a slop value. This value defines an unwanted zone (UZ) where the caret is... unwanted. This zone is defined as a number of pixels near the vertical margins, and as a number of lines near the horizontal margins. By keeping the caret away from the edges, it is seen within its context, so it is likely that the identifier that the caret is on can be completely seen, and that the current line is seen with some of the lines following it which are often dependent on that line. If strict is set, the policy is enforced... strictly. The caret is centred on the display if slop is not set, and cannot go in the UZ if slop is set. If jumps is set, the display is moved more energetically so the caret can move in the same direction longer before the policy is applied again. '3UZ' notation is used to indicate three time the size of the UZ as a distance to the margin. If even is not set, instead of having symmetrical UZs, the left and bottom UZs are extended up to right and top UZs respectively. This way, we favour the displaying of useful information: the begining of lines, where most code reside, and the lines after the caret, eg. the body of a function. | | | | | slop | strict | jumps | even | Caret can go to the margin | When reaching limit (caret going out of | | | | | visibility or going into the UZ) display is... -----+--------+-------+------+--------------------------------------------+-------------------------------------------------------------- 0 | 0 | 0 | 0 | Yes | moved to put caret on top/on right 0 | 0 | 0 | 1 | Yes | moved by one position 0 | 0 | 1 | 0 | Yes | moved to put caret on top/on right 0 | 0 | 1 | 1 | Yes | centred on the caret 0 | 1 | - | 0 | Caret is always on top/on right of display | - 0 | 1 | - | 1 | No, caret is always centred | - 1 | 0 | 0 | 0 | Yes | moved to put caret out of the asymmetrical UZ 1 | 0 | 0 | 1 | Yes | moved to put caret out of the UZ 1 | 0 | 1 | 0 | Yes | moved to put caret at 3UZ of the top or right margin 1 | 0 | 1 | 1 | Yes | moved to put caret at 3UZ of the margin 1 | 1 | - | 0 | Caret is always at UZ of top/right margin | - 1 | 1 | 0 | 1 | No, kept out of UZ | moved by one position 1 | 1 | 1 | 1 | No, kept out of UZ | moved to put caret at 3UZ of the margin */ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange range, const XYScrollOptions options) { PRectangle rcClient = GetTextRectangle(); Point pt = LocationFromPosition(range.caret); Point ptAnchor = LocationFromPosition(range.anchor); const Point ptOrigin = GetVisibleOriginInMain(); pt.x += ptOrigin.x; ptAnchor.x += ptOrigin.x; const Point ptBottomCaret(pt.x, pt.y + vs.lineHeight - 1); XYScrollPosition newXY(xOffset, topLine); // Vertical positioning if ((options & xysVertical) && (pt.y < rcClient.top || ptBottomCaret.y >= rcClient.bottom || (caretYPolicy & CARET_STRICT) != 0)) { const int lineCaret = DisplayFromPosition(range.caret.Position()); const int linesOnScreen = LinesOnScreen(); const int halfScreen = Platform::Maximum(linesOnScreen - 1, 2) / 2; const bool bSlop = (caretYPolicy & CARET_SLOP) != 0; const bool bStrict = (caretYPolicy & CARET_STRICT) != 0; const bool bJump = (caretYPolicy & CARET_JUMPS) != 0; const bool bEven = (caretYPolicy & CARET_EVEN) != 0; // It should be possible to scroll the window to show the caret, // but this fails to remove the caret on GTK+ if (bSlop) { // A margin is defined int yMoveT, yMoveB; if (bStrict) { int yMarginT, yMarginB; if (!(options & xysUseMargin)) { // In drag mode, avoid moves // otherwise, a double click will select several lines. yMarginT = yMarginB = 0; } else { // yMarginT must equal to caretYSlop, with a minimum of 1 and // a maximum of slightly less than half the heigth of the text area. yMarginT = Platform::Clamp(caretYSlop, 1, halfScreen); if (bEven) { yMarginB = yMarginT; } else { yMarginB = linesOnScreen - yMarginT - 1; } } yMoveT = yMarginT; if (bEven) { if (bJump) { yMoveT = Platform::Clamp(caretYSlop * 3, 1, halfScreen); } yMoveB = yMoveT; } else { yMoveB = linesOnScreen - yMoveT - 1; } if (lineCaret < topLine + yMarginT) { // Caret goes too high newXY.topLine = lineCaret - yMoveT; } else if (lineCaret > topLine + linesOnScreen - 1 - yMarginB) { // Caret goes too low newXY.topLine = lineCaret - linesOnScreen + 1 + yMoveB; } } else { // Not strict yMoveT = bJump ? caretYSlop * 3 : caretYSlop; yMoveT = Platform::Clamp(yMoveT, 1, halfScreen); if (bEven) { yMoveB = yMoveT; } else { yMoveB = linesOnScreen - yMoveT - 1; } if (lineCaret < topLine) { // Caret goes too high newXY.topLine = lineCaret - yMoveT; } else if (lineCaret > topLine + linesOnScreen - 1) { // Caret goes too low newXY.topLine = lineCaret - linesOnScreen + 1 + yMoveB; } } } else { // No slop if (!bStrict && !bJump) { // Minimal move if (lineCaret < topLine) { // Caret goes too high newXY.topLine = lineCaret; } else if (lineCaret > topLine + linesOnScreen - 1) { // Caret goes too low if (bEven) { newXY.topLine = lineCaret - linesOnScreen + 1; } else { newXY.topLine = lineCaret; } } } else { // Strict or going out of display if (bEven) { // Always center caret newXY.topLine = lineCaret - halfScreen; } else { // Always put caret on top of display newXY.topLine = lineCaret; } } } if (!(range.caret == range.anchor)) { const int lineAnchor = DisplayFromPosition(range.anchor.Position()); if (lineAnchor < lineCaret) { // Shift up to show anchor or as much of range as possible newXY.topLine = std::min(newXY.topLine, lineAnchor); newXY.topLine = std::max(newXY.topLine, lineCaret - LinesOnScreen()); } else { // Shift down to show anchor or as much of range as possible newXY.topLine = std::max(newXY.topLine, lineAnchor - LinesOnScreen()); newXY.topLine = std::min(newXY.topLine, lineCaret); } } newXY.topLine = Platform::Clamp(newXY.topLine, 0, MaxScrollPos()); } // Horizontal positioning if ((options & xysHorizontal) && (wrapState == eWrapNone)) { const int halfScreen = Platform::Maximum(rcClient.Width() - 4, 4) / 2; const bool bSlop = (caretXPolicy & CARET_SLOP) != 0; const bool bStrict = (caretXPolicy & CARET_STRICT) != 0; const bool bJump = (caretXPolicy & CARET_JUMPS) != 0; const bool bEven = (caretXPolicy & CARET_EVEN) != 0; if (bSlop) { // A margin is defined int xMoveL, xMoveR; if (bStrict) { int xMarginL, xMarginR; if (!(options & xysUseMargin)) { // In drag mode, avoid moves unless very near of the margin // otherwise, a simple click will select text. xMarginL = xMarginR = 2; } else { // xMargin must equal to caretXSlop, with a minimum of 2 and // a maximum of slightly less than half the width of the text area. xMarginR = Platform::Clamp(caretXSlop, 2, halfScreen); if (bEven) { xMarginL = xMarginR; } else { xMarginL = rcClient.Width() - xMarginR - 4; } } if (bJump && bEven) { // Jump is used only in even mode xMoveL = xMoveR = Platform::Clamp(caretXSlop * 3, 1, halfScreen); } else { xMoveL = xMoveR = 0; // Not used, avoid a warning } if (pt.x < rcClient.left + xMarginL) { // Caret is on the left of the display if (bJump && bEven) { newXY.xOffset -= xMoveL; } else { // Move just enough to allow to display the caret newXY.xOffset -= (rcClient.left + xMarginL) - pt.x; } } else if (pt.x >= rcClient.right - xMarginR) { // Caret is on the right of the display if (bJump && bEven) { newXY.xOffset += xMoveR; } else { // Move just enough to allow to display the caret newXY.xOffset += pt.x - (rcClient.right - xMarginR) + 1; } } } else { // Not strict xMoveR = bJump ? caretXSlop * 3 : caretXSlop; xMoveR = Platform::Clamp(xMoveR, 1, halfScreen); if (bEven) { xMoveL = xMoveR; } else { xMoveL = rcClient.Width() - xMoveR - 4; } if (pt.x < rcClient.left) { // Caret is on the left of the display newXY.xOffset -= xMoveL; } else if (pt.x >= rcClient.right) { // Caret is on the right of the display newXY.xOffset += xMoveR; } } } else { // No slop if (bStrict || (bJump && (pt.x < rcClient.left || pt.x >= rcClient.right))) { // Strict or going out of display if (bEven) { // Center caret newXY.xOffset += pt.x - rcClient.left - halfScreen; } else { // Put caret on right newXY.xOffset += pt.x - rcClient.right + 1; } } else { // Move just enough to allow to display the caret if (pt.x < rcClient.left) { // Caret is on the left of the display if (bEven) { newXY.xOffset -= rcClient.left - pt.x; } else { newXY.xOffset += pt.x - rcClient.right + 1; } } else if (pt.x >= rcClient.right) { // Caret is on the right of the display newXY.xOffset += pt.x - rcClient.right + 1; } } } // In case of a jump (find result) largely out of display, adjust the offset to display the caret if (pt.x + xOffset < rcClient.left + newXY.xOffset) { newXY.xOffset = pt.x + xOffset - rcClient.left; } else if (pt.x + xOffset >= rcClient.right + newXY.xOffset) { newXY.xOffset = pt.x + xOffset - rcClient.right + 1; if (vs.caretStyle == CARETSTYLE_BLOCK) { // Ensure we can see a good portion of the block caret newXY.xOffset += static_cast<int>(vs.aveCharWidth); } } if (!(range.caret == range.anchor)) { if (ptAnchor.x < pt.x) { // Shift to left to show anchor or as much of range as possible int maxOffset = ptAnchor.x + xOffset - rcClient.left - 1; int minOffset = pt.x + xOffset - rcClient.right + 1; newXY.xOffset = std::min(newXY.xOffset, maxOffset); newXY.xOffset = std::max(newXY.xOffset, minOffset); } else { // Shift to right to show anchor or as much of range as possible int minOffset = ptAnchor.x + xOffset - rcClient.right + 1; int maxOffset = pt.x + xOffset - rcClient.left - 1; newXY.xOffset = std::max(newXY.xOffset, minOffset); newXY.xOffset = std::min(newXY.xOffset, maxOffset); } } if (newXY.xOffset < 0) { newXY.xOffset = 0; } } return newXY; } void Editor::SetXYScroll(XYScrollPosition newXY) { if ((newXY.topLine != topLine) || (newXY.xOffset != xOffset)) { if (newXY.topLine != topLine) { SetTopLine(newXY.topLine); SetVerticalScrollPos(); } if (newXY.xOffset != xOffset) { xOffset = newXY.xOffset; ContainerNeedsUpdate(SC_UPDATE_H_SCROLL); if (newXY.xOffset > 0) { PRectangle rcText = GetTextRectangle(); if (horizontalScrollBarVisible && rcText.Width() + xOffset > scrollWidth) { scrollWidth = xOffset + rcText.Width(); SetScrollBars(); } } SetHorizontalScrollPos(); } Redraw(); UpdateSystemCaret(); } } void Editor::ScrollRange(SelectionRange range) { SetXYScroll(XYScrollToMakeVisible(range, xysDefault)); } void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) { SetXYScroll(XYScrollToMakeVisible(SelectionRange(posDrag.IsValid() ? posDrag : sel.RangeMain().caret), static_cast<XYScrollOptions>((useMargin?xysUseMargin:0)|(vert?xysVertical:0)|(horiz?xysHorizontal:0)))); } void Editor::ShowCaretAtCurrentPosition() { if (hasFocus) { caret.active = true; caret.on = true; SetTicking(true); } else { caret.active = false; caret.on = false; } InvalidateCaret(); } void Editor::DropCaret() { caret.active = false; InvalidateCaret(); } void Editor::InvalidateCaret() { if (posDrag.IsValid()) { InvalidateRange(posDrag.Position(), posDrag.Position() + 1); } else { for (size_t r=0; r<sel.Count(); r++) { InvalidateRange(sel.Range(r).caret.Position(), sel.Range(r).caret.Position() + 1); } } UpdateSystemCaret(); } void Editor::UpdateSystemCaret() { } void Editor::NeedWrapping(int docLineStart, int docLineEnd) { docLineStart = Platform::Clamp(docLineStart, 0, pdoc->LinesTotal()); if (wrapStart > docLineStart) { wrapStart = docLineStart; llc.Invalidate(LineLayout::llPositions); } if (wrapEnd < docLineEnd) { wrapEnd = docLineEnd; } wrapEnd = Platform::Clamp(wrapEnd, 0, pdoc->LinesTotal()); // Wrap lines during idle. if ((wrapState != eWrapNone) && (wrapEnd != wrapStart)) { SetIdle(true); } } bool Editor::WrapOneLine(Surface *surface, int lineToWrap) { AutoLineLayout ll(llc, RetrieveLineLayout(lineToWrap)); int linesWrapped = 1; if (ll) { LayoutLine(lineToWrap, surface, vs, ll, wrapWidth); linesWrapped = ll->lines; } return cs.SetHeight(lineToWrap, linesWrapped + (vs.annotationVisible ? pdoc->AnnotationLines(lineToWrap) : 0)); } // Check if wrapping needed and perform any needed wrapping. // fullwrap: if true, all lines which need wrapping will be done, // in this single call. // priorityWrapLineStart: If greater than or equal to zero, all lines starting from // here to 1 page + 100 lines past will be wrapped (even if there are // more lines under wrapping process in idle). // If it is neither fullwrap, nor priorityWrap, then 1 page + 100 lines will be // wrapped, if there are any wrapping going on in idle. (Generally this // condition is called only from idler). // Return true if wrapping occurred. bool Editor::WrapLines(bool fullWrap, int priorityWrapLineStart) { // If there are any pending wraps, do them during idle if possible. int linesInOneCall = LinesOnScreen() + 100; if (priorityWrapLineStart >= 0) { // Using DocFromDisplay() here may result in chicken and egg problem in certain corner cases, // which will hopefully be handled by added 100 lines. If some lines are still missed, idle wrapping will catch on. int docLinesInOneCall = cs.DocFromDisplay(topLine + LinesOnScreen() + 100) - cs.DocFromDisplay(topLine); linesInOneCall = Platform::Maximum(linesInOneCall, docLinesInOneCall); } if (wrapState != eWrapNone) { if (wrapStart < wrapEnd) { if (!SetIdle(true)) { // Idle processing not supported so full wrap required. fullWrap = true; } } if (!fullWrap && priorityWrapLineStart >= 0 && // .. and if the paint window is outside pending wraps (((priorityWrapLineStart + linesInOneCall) < wrapStart) || (priorityWrapLineStart > wrapEnd))) { // No priority wrap pending return false; } } int goodTopLine = topLine; bool wrapOccurred = false; if (wrapStart <= pdoc->LinesTotal()) { if (wrapState == eWrapNone) { if (wrapWidth != LineLayout::wrapWidthInfinite) { wrapWidth = LineLayout::wrapWidthInfinite; for (int lineDoc = 0; lineDoc < pdoc->LinesTotal(); lineDoc++) { cs.SetHeight(lineDoc, 1 + (vs.annotationVisible ? pdoc->AnnotationLines(lineDoc) : 0)); } wrapOccurred = true; } wrapStart = wrapLineLarge; wrapEnd = wrapLineLarge; } else { if (wrapEnd >= pdoc->LinesTotal()) wrapEnd = pdoc->LinesTotal(); //ElapsedTime et; int lineDocTop = cs.DocFromDisplay(topLine); int subLineTop = topLine - cs.DisplayFromDoc(lineDocTop); PRectangle rcTextArea = GetClientRectangle(); rcTextArea.left = vs.textStart; rcTextArea.right -= vs.textStart; wrapWidth = rcTextArea.Width(); RefreshStyleData(); AutoSurface surface(this); if (surface) { bool priorityWrap = false; int lastLineToWrap = wrapEnd; int lineToWrap = wrapStart; if (!fullWrap) { if (priorityWrapLineStart >= 0) { // This is a priority wrap. lineToWrap = priorityWrapLineStart; lastLineToWrap = priorityWrapLineStart + linesInOneCall; priorityWrap = true; } else { // This is idle wrap. lastLineToWrap = wrapStart + linesInOneCall; } if (lastLineToWrap >= wrapEnd) lastLineToWrap = wrapEnd; } // else do a fullWrap. // Ensure all lines being wrapped are styled. pdoc->EnsureStyledTo(pdoc->LineEnd(lastLineToWrap)); // Platform::DebugPrintf("Wraplines: full = %d, priorityStart = %d (wrapping: %d to %d)\n", fullWrap, priorityWrapLineStart, lineToWrap, lastLineToWrap); // Platform::DebugPrintf("Pending wraps: %d to %d\n", wrapStart, wrapEnd); while (lineToWrap < lastLineToWrap) { if (WrapOneLine(surface, lineToWrap)) { wrapOccurred = true; } lineToWrap++; } if (!priorityWrap) wrapStart = lineToWrap; // If wrapping is done, bring it to resting position if (wrapStart >= wrapEnd) { wrapStart = wrapLineLarge; wrapEnd = wrapLineLarge; } } goodTopLine = cs.DisplayFromDoc(lineDocTop); if (subLineTop < cs.GetHeight(lineDocTop)) goodTopLine += subLineTop; else goodTopLine += cs.GetHeight(lineDocTop); //double durWrap = et.Duration(true); //Platform::DebugPrintf("Wrap:%9.6g \n", durWrap); } } if (wrapOccurred) { SetScrollBars(); SetTopLine(Platform::Clamp(goodTopLine, 0, MaxScrollPos())); SetVerticalScrollPos(); } return wrapOccurred; } void Editor::LinesJoin() { if (!RangeContainsProtected(targetStart, targetEnd)) { UndoGroup ug(pdoc); bool prevNonWS = true; for (int pos = targetStart; pos < targetEnd; pos++) { if (pdoc->IsPositionInLineEnd(pos)) { targetEnd -= pdoc->LenChar(pos); pdoc->DelChar(pos); if (prevNonWS) { // Ensure at least one space separating previous lines pdoc->InsertChar(pos, ' '); targetEnd++; } } else { prevNonWS = pdoc->CharAt(pos) != ' '; } } } } const char *Editor::StringFromEOLMode(int eolMode) { if (eolMode == SC_EOL_CRLF) { return "\r\n"; } else if (eolMode == SC_EOL_CR) { return "\r"; } else { return "\n"; } } void Editor::LinesSplit(int pixelWidth) { if (!RangeContainsProtected(targetStart, targetEnd)) { if (pixelWidth == 0) { PRectangle rcText = GetTextRectangle(); pixelWidth = rcText.Width(); } int lineStart = pdoc->LineFromPosition(targetStart); int lineEnd = pdoc->LineFromPosition(targetEnd); const char *eol = StringFromEOLMode(pdoc->eolMode); UndoGroup ug(pdoc); for (int line = lineStart; line <= lineEnd; line++) { AutoSurface surface(this); AutoLineLayout ll(llc, RetrieveLineLayout(line)); if (surface && ll) { unsigned int posLineStart = pdoc->LineStart(line); LayoutLine(line, surface, vs, ll, pixelWidth); for (int subLine = 1; subLine < ll->lines; subLine++) { pdoc->InsertCString( static_cast<int>(posLineStart + (subLine - 1) * strlen(eol) + ll->LineStart(subLine)), eol); targetEnd += static_cast<int>(strlen(eol)); } } lineEnd = pdoc->LineFromPosition(targetEnd); } } } int Editor::SubstituteMarkerIfEmpty(int markerCheck, int markerDefault) { if (vs.markers[markerCheck].markType == SC_MARK_EMPTY) return markerDefault; return markerCheck; } bool ValidStyledText(ViewStyle &vs, size_t styleOffset, const StyledText &st) { if (st.multipleStyles) { for (size_t iStyle=0; iStyle<st.length; iStyle++) { if (!vs.ValidStyle(styleOffset + st.styles[iStyle])) return false; } } else { if (!vs.ValidStyle(styleOffset + st.style)) return false; } return true; } static int WidthStyledText(Surface *surface, ViewStyle &vs, int styleOffset, const char *text, const unsigned char *styles, size_t len) { int width = 0; size_t start = 0; while (start < len) { size_t style = styles[start]; size_t endSegment = start; while ((endSegment+1 < len) && (static_cast<size_t>(styles[endSegment+1]) == style)) endSegment++; width += surface->WidthText(vs.styles[style+styleOffset].font, text + start, static_cast<int>(endSegment - start + 1)); start = endSegment + 1; } return width; } static int WidestLineWidth(Surface *surface, ViewStyle &vs, int styleOffset, const StyledText &st) { int widthMax = 0; size_t start = 0; while (start < st.length) { size_t lenLine = st.LineLength(start); int widthSubLine; if (st.multipleStyles) { widthSubLine = WidthStyledText(surface, vs, styleOffset, st.text + start, st.styles + start, lenLine); } else { widthSubLine = surface->WidthText(vs.styles[styleOffset + st.style].font, st.text + start, static_cast<int>(lenLine)); } if (widthSubLine > widthMax) widthMax = widthSubLine; start += lenLine + 1; } return widthMax; } void DrawStyledText(Surface *surface, ViewStyle &vs, int styleOffset, PRectangle rcText, int ascent, const StyledText &st, size_t start, size_t length) { if (st.multipleStyles) { int x = rcText.left; size_t i = 0; while (i < length) { size_t end = i; int style = st.styles[i + start]; while (end < length-1 && st.styles[start+end+1] == style) end++; style += styleOffset; int width = surface->WidthText(vs.styles[style].font, st.text + start + i, static_cast<int>(end - i + 1)); PRectangle rcSegment = rcText; rcSegment.left = x; rcSegment.right = x + width + 1; surface->DrawTextNoClip(rcSegment, vs.styles[style].font, ascent, st.text + start + i, static_cast<int>(end - i + 1), vs.styles[style].fore, vs.styles[style].back); x += width; i = end + 1; } } else { size_t style = st.style + styleOffset; surface->DrawTextNoClip(rcText, vs.styles[style].font, rcText.top + vs.maxAscent, st.text + start, static_cast<int>(length), vs.styles[style].fore, vs.styles[style].back); } } void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { if (vs.fixedColumnWidth == 0) return; RefreshPixMaps(surfWindow); PRectangle rcMargin = GetClientRectangle(); Point ptOrigin = GetVisibleOriginInMain(); rcMargin.Move(0, -ptOrigin.y); rcMargin.left = 0; rcMargin.right = vs.fixedColumnWidth; if (!rc.Intersects(rcMargin)) return; Surface *surface; if (bufferedDraw) { surface = pixmapSelMargin; } else { surface = surfWindow; } // Clip vertically to paint area to avoid drawing line numbers if (rcMargin.bottom > rc.bottom) rcMargin.bottom = rc.bottom; if (rcMargin.top < rc.top) rcMargin.top = rc.top; PRectangle rcSelMargin = rcMargin; rcSelMargin.right = rcMargin.left; if (rcSelMargin.bottom < rc.bottom) rcSelMargin.bottom = rc.bottom; for (int margin = 0; margin <= SC_MAX_MARGIN; margin++) { if (vs.ms[margin].width > 0) { rcSelMargin.left = rcSelMargin.right; rcSelMargin.right = rcSelMargin.left + vs.ms[margin].width; if (vs.ms[margin].style != SC_MARGIN_NUMBER) { if (vs.ms[margin].mask & SC_MASK_FOLDERS) { // Required because of special way brush is created for selection margin // Ensure patterns line up when scrolling with separate margin view // by choosing correctly aligned variant. bool invertPhase = static_cast<int>(ptOrigin.y) & 1; surface->FillRectangle(rcSelMargin, invertPhase ? *pixmapSelPattern : *pixmapSelPatternOffset1); } else { ColourDesired colour; switch (vs.ms[margin].style) { case SC_MARGIN_BACK: colour = vs.styles[STYLE_DEFAULT].back; break; case SC_MARGIN_FORE: colour = vs.styles[STYLE_DEFAULT].fore; break; default: colour = vs.styles[STYLE_LINENUMBER].back; break; } surface->FillRectangle(rcSelMargin, colour); } } else { surface->FillRectangle(rcSelMargin, vs.styles[STYLE_LINENUMBER].back); } const int lineStartPaint = (rcMargin.top + ptOrigin.y) / vs.lineHeight; int visibleLine = TopLineOfMain() + lineStartPaint; int yposScreen = lineStartPaint * vs.lineHeight - ptOrigin.y; // Work out whether the top line is whitespace located after a // lessening of fold level which implies a 'fold tail' but which should not // be displayed until the last of a sequence of whitespace. bool needWhiteClosure = false; if (vs.ms[margin].mask & SC_MASK_FOLDERS) { int level = pdoc->GetLevel(cs.DocFromDisplay(visibleLine)); if (level & SC_FOLDLEVELWHITEFLAG) { int lineBack = cs.DocFromDisplay(visibleLine); int levelPrev = level; while ((lineBack > 0) && (levelPrev & SC_FOLDLEVELWHITEFLAG)) { lineBack--; levelPrev = pdoc->GetLevel(lineBack); } if (!(levelPrev & SC_FOLDLEVELHEADERFLAG)) { if ((level & SC_FOLDLEVELNUMBERMASK) < (levelPrev & SC_FOLDLEVELNUMBERMASK)) needWhiteClosure = true; } } if (highlightDelimiter.isEnabled) { int lastLine = cs.DocFromDisplay(topLine + LinesOnScreen()) + 1; pdoc->GetHighlightDelimiters(highlightDelimiter, pdoc->LineFromPosition(CurrentPosition()), lastLine); } } // Old code does not know about new markers needed to distinguish all cases int folderOpenMid = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEROPENMID, SC_MARKNUM_FOLDEROPEN); int folderEnd = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEREND, SC_MARKNUM_FOLDER); while ((visibleLine < cs.LinesDisplayed()) && yposScreen < rc.bottom) { PLATFORM_ASSERT(visibleLine < cs.LinesDisplayed()); int lineDoc = cs.DocFromDisplay(visibleLine); PLATFORM_ASSERT(cs.GetVisible(lineDoc)); bool firstSubLine = visibleLine == cs.DisplayFromDoc(lineDoc); bool lastSubLine = visibleLine == (cs.DisplayFromDoc(lineDoc + 1) - 1); int marks = pdoc->GetMark(lineDoc); if (!firstSubLine) marks = 0; bool headWithTail = false; if (vs.ms[margin].mask & SC_MASK_FOLDERS) { // Decide which fold indicator should be displayed int level = pdoc->GetLevel(lineDoc); int levelNext = pdoc->GetLevel(lineDoc + 1); int levelNum = level & SC_FOLDLEVELNUMBERMASK; int levelNextNum = levelNext & SC_FOLDLEVELNUMBERMASK; if (level & SC_FOLDLEVELHEADERFLAG) { if (firstSubLine) { if (levelNum < levelNextNum) { if (cs.GetExpanded(lineDoc)) { if (levelNum == SC_FOLDLEVELBASE) marks |= 1 << SC_MARKNUM_FOLDEROPEN; else marks |= 1 << folderOpenMid; } else { if (levelNum == SC_FOLDLEVELBASE) marks |= 1 << SC_MARKNUM_FOLDER; else marks |= 1 << folderEnd; } } else if (levelNum > SC_FOLDLEVELBASE) { marks |= 1 << SC_MARKNUM_FOLDERSUB; } } else { if (levelNum < levelNextNum) { if (cs.GetExpanded(lineDoc)) { marks |= 1 << SC_MARKNUM_FOLDERSUB; } else if (levelNum > SC_FOLDLEVELBASE) { marks |= 1 << SC_MARKNUM_FOLDERSUB; } } else if (levelNum > SC_FOLDLEVELBASE) { marks |= 1 << SC_MARKNUM_FOLDERSUB; } } needWhiteClosure = false; int firstFollowupLine = cs.DocFromDisplay(cs.DisplayFromDoc(lineDoc + 1)); int firstFollowupLineLevel = pdoc->GetLevel(firstFollowupLine); int secondFollowupLineLevelNum = pdoc->GetLevel(firstFollowupLine + 1) & SC_FOLDLEVELNUMBERMASK; if (!cs.GetExpanded(lineDoc)) { if ((firstFollowupLineLevel & SC_FOLDLEVELWHITEFLAG) && (levelNum > secondFollowupLineLevelNum)) needWhiteClosure = true; if (highlightDelimiter.IsFoldBlockHighlighted(firstFollowupLine)) headWithTail = true; } } else if (level & SC_FOLDLEVELWHITEFLAG) { if (needWhiteClosure) { if (levelNext & SC_FOLDLEVELWHITEFLAG) { marks |= 1 << SC_MARKNUM_FOLDERSUB; } else if (levelNextNum > SC_FOLDLEVELBASE) { marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL; needWhiteClosure = false; } else { marks |= 1 << SC_MARKNUM_FOLDERTAIL; needWhiteClosure = false; } } else if (levelNum > SC_FOLDLEVELBASE) { if (levelNextNum < levelNum) { if (levelNextNum > SC_FOLDLEVELBASE) { marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL; } else { marks |= 1 << SC_MARKNUM_FOLDERTAIL; } } else { marks |= 1 << SC_MARKNUM_FOLDERSUB; } } } else if (levelNum > SC_FOLDLEVELBASE) { if (levelNextNum < levelNum) { needWhiteClosure = false; if (levelNext & SC_FOLDLEVELWHITEFLAG) { marks |= 1 << SC_MARKNUM_FOLDERSUB; needWhiteClosure = true; } else if (lastSubLine) { if (levelNextNum > SC_FOLDLEVELBASE) { marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL; } else { marks |= 1 << SC_MARKNUM_FOLDERTAIL; } } else { marks |= 1 << SC_MARKNUM_FOLDERSUB; } } else { marks |= 1 << SC_MARKNUM_FOLDERSUB; } } } marks &= vs.ms[margin].mask; PRectangle rcMarker = rcSelMargin; rcMarker.top = yposScreen; rcMarker.bottom = yposScreen + vs.lineHeight; if (vs.ms[margin].style == SC_MARGIN_NUMBER) { if (firstSubLine) { char number[100] = ""; if (lineDoc >= 0) sprintf(number, "%d", lineDoc + 1); if (foldFlags & SC_FOLDFLAG_LEVELNUMBERS) { int lev = pdoc->GetLevel(lineDoc); sprintf(number, "%c%c %03X %03X", (lev & SC_FOLDLEVELHEADERFLAG) ? 'H' : '_', (lev & SC_FOLDLEVELWHITEFLAG) ? 'W' : '_', lev & SC_FOLDLEVELNUMBERMASK, lev >> 16 ); } PRectangle rcNumber = rcMarker; // Right justify XYPOSITION width = surface->WidthText(vs.styles[STYLE_LINENUMBER].font, number, istrlen(number)); XYPOSITION xpos = rcNumber.right - width - marginNumberPadding; rcNumber.left = xpos; surface->DrawTextNoClip(rcNumber, vs.styles[STYLE_LINENUMBER].font, rcNumber.top + vs.maxAscent, number, istrlen(number), vs.styles[STYLE_LINENUMBER].fore, vs.styles[STYLE_LINENUMBER].back); } else if (wrapVisualFlags & SC_WRAPVISUALFLAG_MARGIN) { PRectangle rcWrapMarker = rcMarker; rcWrapMarker.right -= 3; rcWrapMarker.left = rcWrapMarker.right - vs.styles[STYLE_LINENUMBER].aveCharWidth; DrawWrapMarker(surface, rcWrapMarker, false, vs.styles[STYLE_LINENUMBER].fore); } } else if (vs.ms[margin].style == SC_MARGIN_TEXT || vs.ms[margin].style == SC_MARGIN_RTEXT) { if (firstSubLine) { const StyledText stMargin = pdoc->MarginStyledText(lineDoc); if (stMargin.text && ValidStyledText(vs, vs.marginStyleOffset, stMargin)) { surface->FillRectangle(rcMarker, vs.styles[stMargin.StyleAt(0)+vs.marginStyleOffset].back); if (vs.ms[margin].style == SC_MARGIN_RTEXT) { int width = WidestLineWidth(surface, vs, vs.marginStyleOffset, stMargin); rcMarker.left = rcMarker.right - width - 3; } DrawStyledText(surface, vs, vs.marginStyleOffset, rcMarker, rcMarker.top + vs.maxAscent, stMargin, 0, stMargin.length); } } } if (marks) { for (int markBit = 0; (markBit < 32) && marks; markBit++) { if (marks & 1) { LineMarker::typeOfFold tFold = LineMarker::undefined; if ((vs.ms[margin].mask & SC_MASK_FOLDERS) && highlightDelimiter.IsFoldBlockHighlighted(lineDoc)) { if (highlightDelimiter.IsBodyOfFoldBlock(lineDoc)) { tFold = LineMarker::body; } else if (highlightDelimiter.IsHeadOfFoldBlock(lineDoc)) { if (firstSubLine) { tFold = headWithTail ? LineMarker::headWithTail : LineMarker::head; } else { if (cs.GetExpanded(lineDoc) || headWithTail) { tFold = LineMarker::body; } else { tFold = LineMarker::undefined; } } } else if (highlightDelimiter.IsTailOfFoldBlock(lineDoc)) { tFold = LineMarker::tail; } } vs.markers[markBit].Draw(surface, rcMarker, vs.styles[STYLE_LINENUMBER].font, tFold, vs.ms[margin].style); } marks >>= 1; } } visibleLine++; yposScreen += vs.lineHeight; } } } PRectangle rcBlankMargin = rcMargin; rcBlankMargin.left = rcSelMargin.right; surface->FillRectangle(rcBlankMargin, vs.styles[STYLE_DEFAULT].back); if (bufferedDraw) { surfWindow->Copy(rcMargin, Point(rcMargin.left, rcMargin.top), *pixmapSelMargin); } } void DrawTabArrow(Surface *surface, PRectangle rcTab, int ymid) { int ydiff = (rcTab.bottom - rcTab.top) / 2; int xhead = rcTab.right - 1 - ydiff; if (xhead <= rcTab.left) { ydiff -= rcTab.left - xhead - 1; xhead = rcTab.left - 1; } if ((rcTab.left + 2) < (rcTab.right - 1)) surface->MoveTo(rcTab.left + 2, ymid); else surface->MoveTo(rcTab.right - 1, ymid); surface->LineTo(rcTab.right - 1, ymid); surface->LineTo(xhead, ymid - ydiff); surface->MoveTo(rcTab.right - 1, ymid); surface->LineTo(xhead, ymid + ydiff); } LineLayout *Editor::RetrieveLineLayout(int lineNumber) { int posLineStart = pdoc->LineStart(lineNumber); int posLineEnd = pdoc->LineStart(lineNumber + 1); PLATFORM_ASSERT(posLineEnd >= posLineStart); int lineCaret = pdoc->LineFromPosition(sel.MainCaret()); return llc.Retrieve(lineNumber, lineCaret, posLineEnd - posLineStart, pdoc->GetStyleClock(), LinesOnScreen() + 1, pdoc->LinesTotal()); } bool BadUTF(const char *s, int len, int &trailBytes) { // For the rules: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 if (trailBytes) { trailBytes--; return false; } int utf8status = UTF8Classify(reinterpret_cast<const unsigned char *>(s), len); if (utf8status & UTF8MaskInvalid) { return true; } else { trailBytes = (utf8status & UTF8MaskWidth) - 1; return false; } } /** * Fill in the LineLayout data for the given line. * Copy the given @a line and its styles from the document into local arrays. * Also determine the x position at which each character starts. */ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout *ll, int width) { if (!ll) return; PLATFORM_ASSERT(line < pdoc->LinesTotal()); PLATFORM_ASSERT(ll->chars != NULL); int posLineStart = pdoc->LineStart(line); int posLineEnd = pdoc->LineStart(line + 1); // If the line is very long, limit the treatment to a length that should fit in the viewport if (posLineEnd > (posLineStart + ll->maxLineLength)) { posLineEnd = posLineStart + ll->maxLineLength; } if (ll->validity == LineLayout::llCheckTextAndStyle) { int lineLength = posLineEnd - posLineStart; if (!vstyle.viewEOL) { lineLength = pdoc->LineEnd(line) - posLineStart; } if (lineLength == ll->numCharsInLine) { // See if chars, styles, indicators, are all the same bool allSame = true; const int styleMask = pdoc->stylingBitsMask; // Check base line layout char styleByte = 0; int numCharsInLine = 0; while (numCharsInLine < lineLength) { int charInDoc = numCharsInLine + posLineStart; char chDoc = pdoc->CharAt(charInDoc); styleByte = pdoc->StyleAt(charInDoc); allSame = allSame && (ll->styles[numCharsInLine] == static_cast<unsigned char>(styleByte & styleMask)); allSame = allSame && (ll->indicators[numCharsInLine] == static_cast<char>(styleByte & ~styleMask)); if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseMixed) allSame = allSame && (ll->chars[numCharsInLine] == chDoc); else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower) allSame = allSame && (ll->chars[numCharsInLine] == static_cast<char>(tolower(chDoc))); else // Style::caseUpper allSame = allSame && (ll->chars[numCharsInLine] == static_cast<char>(toupper(chDoc))); numCharsInLine++; } allSame = allSame && (ll->styles[numCharsInLine] == styleByte); // For eolFilled if (allSame) { ll->validity = LineLayout::llPositions; } else { ll->validity = LineLayout::llInvalid; } } else { ll->validity = LineLayout::llInvalid; } } if (ll->validity == LineLayout::llInvalid) { ll->widthLine = LineLayout::wrapWidthInfinite; ll->lines = 1; if (vstyle.edgeState == EDGE_BACKGROUND) { ll->edgeColumn = pdoc->FindColumn(line, theEdge); if (ll->edgeColumn >= posLineStart) { ll->edgeColumn -= posLineStart; } } else { ll->edgeColumn = -1; } char styleByte; const int styleMask = pdoc->stylingBitsMask; ll->styleBitsSet = 0; // Fill base line layout const int lineLength = posLineEnd - posLineStart; pdoc->GetCharRange(ll->chars, posLineStart, lineLength); pdoc->GetStyleRange(ll->styles, posLineStart, lineLength); int numCharsBeforeEOL = pdoc->LineEnd(line) - posLineStart; const int numCharsInLine = (vstyle.viewEOL) ? lineLength : numCharsBeforeEOL; for (int styleInLine = 0; styleInLine < numCharsInLine; styleInLine++) { styleByte = ll->styles[styleInLine]; ll->styleBitsSet |= styleByte; ll->styles[styleInLine] = static_cast<char>(styleByte & styleMask); ll->indicators[styleInLine] = static_cast<char>(styleByte & ~styleMask); } styleByte = static_cast<char>(((lineLength > 0) ? ll->styles[lineLength-1] : 0) & styleMask); if (vstyle.someStylesForceCase) { for (int charInLine = 0; charInLine<lineLength; charInLine++) { char chDoc = ll->chars[charInLine]; if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseUpper) ll->chars[charInLine] = static_cast<char>(toupper(chDoc)); else if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseLower) ll->chars[charInLine] = static_cast<char>(tolower(chDoc)); } } ll->xHighlightGuide = 0; // Extra element at the end of the line to hold end x position and act as ll->chars[numCharsInLine] = 0; // Also triggers processing in the loops as this is a control character ll->styles[numCharsInLine] = styleByte; // For eolFilled ll->indicators[numCharsInLine] = 0; // Layout the line, determining the position of each character, // with an extra element at the end for the end of the line. int startseg = 0; // Start of the current segment, in char. number XYACCUMULATOR startsegx = 0; // Start of the current segment, in pixels ll->positions[0] = 0; XYPOSITION tabWidth = vstyle.spaceWidth * pdoc->tabInChars; bool lastSegItalics = false; Font &ctrlCharsFont = vstyle.styles[STYLE_CONTROLCHAR].font; XYPOSITION ctrlCharWidth[32] = {0}; bool isControlNext = IsControlCharacter(ll->chars[0]); int trailBytes = 0; bool isBadUTFNext = IsUnicodeMode() && BadUTF(ll->chars, numCharsInLine, trailBytes); for (int charInLine = 0; charInLine < numCharsInLine; charInLine++) { bool isControl = isControlNext; isControlNext = IsControlCharacter(ll->chars[charInLine + 1]); bool isBadUTF = isBadUTFNext; isBadUTFNext = IsUnicodeMode() && BadUTF(ll->chars + charInLine + 1, numCharsInLine - charInLine - 1, trailBytes); if ((ll->styles[charInLine] != ll->styles[charInLine + 1]) || isControl || isControlNext || isBadUTF || isBadUTFNext || ((charInLine+1) >= numCharsBeforeEOL)) { ll->positions[startseg] = 0; if (vstyle.styles[ll->styles[charInLine]].visible) { if (isControl) { if (ll->chars[charInLine] == '\t') { ll->positions[charInLine + 1] = ((static_cast<int>((startsegx + 2) / tabWidth) + 1) * tabWidth) - startsegx; } else if (controlCharSymbol < 32) { if (ctrlCharWidth[ll->chars[charInLine]] == 0) { const char *ctrlChar = ControlCharacterString(ll->chars[charInLine]); ctrlCharWidth[ll->chars[charInLine]] = surface->WidthText(ctrlCharsFont, ctrlChar, istrlen(ctrlChar)) + ctrlCharPadding; } ll->positions[charInLine + 1] = ctrlCharWidth[ll->chars[charInLine]]; } else { char cc[2] = { static_cast<char>(controlCharSymbol), '\0' }; surface->MeasureWidths(ctrlCharsFont, cc, 1, ll->positions + startseg + 1); } lastSegItalics = false; } else if ((isBadUTF) || (charInLine >= numCharsBeforeEOL)) { char hexits[4]; sprintf(hexits, "x%2X", ll->chars[charInLine] & 0xff); ll->positions[charInLine + 1] = surface->WidthText(ctrlCharsFont, hexits, istrlen(hexits)) + 3; } else { // Regular character int lenSeg = charInLine - startseg + 1; if ((lenSeg == 1) && (' ' == ll->chars[startseg])) { lastSegItalics = false; // Over half the segments are single characters and of these about half are space characters. ll->positions[charInLine + 1] = vstyle.styles[ll->styles[charInLine]].spaceWidth; } else { lastSegItalics = vstyle.styles[ll->styles[charInLine]].italic; posCache.MeasureWidths(surface, vstyle, ll->styles[charInLine], ll->chars + startseg, lenSeg, ll->positions + startseg + 1, pdoc); } } } else { // invisible for (int posToZero = startseg; posToZero <= (charInLine + 1); posToZero++) { ll->positions[posToZero] = 0; } } for (int posToIncrease = startseg; posToIncrease <= (charInLine + 1); posToIncrease++) { ll->positions[posToIncrease] += startsegx; } startsegx = ll->positions[charInLine + 1]; startseg = charInLine + 1; } } // Small hack to make lines that end with italics not cut off the edge of the last character if ((startseg > 0) && lastSegItalics) { ll->positions[startseg] += lastSegItalicsOffset; } ll->numCharsInLine = numCharsInLine; ll->numCharsBeforeEOL = numCharsBeforeEOL; ll->validity = LineLayout::llPositions; } // Hard to cope when too narrow, so just assume there is space if (width < 20) { width = 20; } if ((ll->validity == LineLayout::llPositions) || (ll->widthLine != width)) { ll->widthLine = width; if (width == LineLayout::wrapWidthInfinite) { ll->lines = 1; } else if (width > ll->positions[ll->numCharsInLine]) { // Simple common case where line does not need wrapping. ll->lines = 1; } else { if (wrapVisualFlags & SC_WRAPVISUALFLAG_END) { width -= static_cast<int>(vstyle.aveCharWidth); // take into account the space for end wrap mark } XYPOSITION wrapAddIndent = 0; // This will be added to initial indent of line if (wrapIndentMode == SC_WRAPINDENT_INDENT) { wrapAddIndent = pdoc->IndentSize() * vstyle.spaceWidth; } else if (wrapIndentMode == SC_WRAPINDENT_FIXED) { wrapAddIndent = wrapVisualStartIndent * vstyle.aveCharWidth; } ll->wrapIndent = wrapAddIndent; if (wrapIndentMode != SC_WRAPINDENT_FIXED) for (int i = 0; i < ll->numCharsInLine; i++) { if (!IsSpaceOrTab(ll->chars[i])) { ll->wrapIndent += ll->positions[i]; // Add line indent break; } } // Check for text width minimum if (ll->wrapIndent > width - static_cast<int>(vstyle.aveCharWidth) * 15) ll->wrapIndent = wrapAddIndent; // Check for wrapIndent minimum if ((wrapVisualFlags & SC_WRAPVISUALFLAG_START) && (ll->wrapIndent < vstyle.aveCharWidth)) ll->wrapIndent = vstyle.aveCharWidth; // Indent to show start visual ll->lines = 0; // Calculate line start positions based upon width. int lastGoodBreak = 0; int lastLineStart = 0; XYACCUMULATOR startOffset = 0; int p = 0; while (p < ll->numCharsInLine) { if ((ll->positions[p + 1] - startOffset) >= width) { if (lastGoodBreak == lastLineStart) { // Try moving to start of last character if (p > 0) { lastGoodBreak = pdoc->MovePositionOutsideChar(p + posLineStart, -1) - posLineStart; } if (lastGoodBreak == lastLineStart) { // Ensure at least one character on line. lastGoodBreak = pdoc->MovePositionOutsideChar(lastGoodBreak + posLineStart + 1, 1) - posLineStart; } } lastLineStart = lastGoodBreak; ll->lines++; ll->SetLineStart(ll->lines, lastGoodBreak); startOffset = ll->positions[lastGoodBreak]; // take into account the space for start wrap mark and indent startOffset -= ll->wrapIndent; p = lastGoodBreak + 1; continue; } if (p > 0) { if (wrapState == eWrapChar) { lastGoodBreak = pdoc->MovePositionOutsideChar(p + posLineStart, -1) - posLineStart; p = pdoc->MovePositionOutsideChar(p + 1 + posLineStart, 1) - posLineStart; continue; } else if (ll->styles[p] != ll->styles[p - 1]) { lastGoodBreak = p; } else if (IsSpaceOrTab(ll->chars[p - 1]) && !IsSpaceOrTab(ll->chars[p])) { lastGoodBreak = p; } } p++; } ll->lines++; } ll->validity = LineLayout::llLines; } } ColourDesired Editor::SelectionBackground(ViewStyle &vsDraw, bool main) { return main ? (primarySelection ? vsDraw.selbackground : vsDraw.selbackground2) : vsDraw.selAdditionalBackground; } ColourDesired Editor::TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourDesired background, int inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll) { if (inSelection == 1) { if (vsDraw.selbackset && (vsDraw.selAlpha == SC_ALPHA_NOALPHA)) { return SelectionBackground(vsDraw, true); } } else if (inSelection == 2) { if (vsDraw.selbackset && (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA)) { return SelectionBackground(vsDraw, false); } } else { if ((vsDraw.edgeState == EDGE_BACKGROUND) && (i >= ll->edgeColumn) && (i < ll->numCharsBeforeEOL)) return vsDraw.edgecolour; if (inHotspot && vsDraw.hotspotBackgroundSet) return vsDraw.hotspotBackground; } if (overrideBackground && (styleMain != STYLE_BRACELIGHT) && (styleMain != STYLE_BRACEBAD)) { return background; } else { return vsDraw.styles[styleMain].back; } } void Editor::DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight) { Point from(0, ((lineVisible & 1) && (lineHeight & 1)) ? 1 : 0); PRectangle rcCopyArea(start + 1, rcSegment.top, start + 2, rcSegment.bottom); surface->Copy(rcCopyArea, from, highlight ? *pixmapIndentGuideHighlight : *pixmapIndentGuide); } void Editor::DrawWrapMarker(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourDesired wrapColour) { surface->PenColour(wrapColour); enum { xa = 1 }; // gap before start int w = rcPlace.right - rcPlace.left - xa - 1; bool xStraight = isEndMarker; // x-mirrored symbol for start marker bool yStraight = true; //bool yStraight= isEndMarker; // comment in for start marker y-mirrowed int x0 = xStraight ? rcPlace.left : rcPlace.right - 1; int y0 = yStraight ? rcPlace.top : rcPlace.bottom - 1; int dy = (rcPlace.bottom - rcPlace.top) / 5; int y = (rcPlace.bottom - rcPlace.top) / 2 + dy; struct Relative { Surface *surface; int xBase; int xDir; int yBase; int yDir; void MoveTo(int xRelative, int yRelative) { surface->MoveTo(xBase + xDir * xRelative, yBase + yDir * yRelative); } void LineTo(int xRelative, int yRelative) { surface->LineTo(xBase + xDir * xRelative, yBase + yDir * yRelative); } }; Relative rel = {surface, x0, xStraight ? 1 : -1, y0, yStraight ? 1 : -1}; // arrow head rel.MoveTo(xa, y); rel.LineTo(xa + 2*w / 3, y - dy); rel.MoveTo(xa, y); rel.LineTo(xa + 2*w / 3, y + dy); // arrow body rel.MoveTo(xa, y); rel.LineTo(xa + w, y); rel.LineTo(xa + w, y - 2 * dy); rel.LineTo(xa - 1, // on windows lineto is exclusive endpoint, perhaps GTK not... y - 2 * dy); } static void SimpleAlphaRectangle(Surface *surface, PRectangle rc, ColourDesired fill, int alpha) { if (alpha != SC_ALPHA_NOALPHA) { surface->AlphaRectangle(rc, 0, fill, alpha, fill, alpha, 0); } } void DrawTextBlob(Surface *surface, ViewStyle &vsDraw, PRectangle rcSegment, const char *s, ColourDesired textBack, ColourDesired textFore, bool twoPhaseDraw) { if (!twoPhaseDraw) { surface->FillRectangle(rcSegment, textBack); } Font &ctrlCharsFont = vsDraw.styles[STYLE_CONTROLCHAR].font; int normalCharHeight = surface->Ascent(ctrlCharsFont) - surface->InternalLeading(ctrlCharsFont); PRectangle rcCChar = rcSegment; rcCChar.left = rcCChar.left + 1; rcCChar.top = rcSegment.top + vsDraw.maxAscent - normalCharHeight; rcCChar.bottom = rcSegment.top + vsDraw.maxAscent + 1; PRectangle rcCentral = rcCChar; rcCentral.top++; rcCentral.bottom--; surface->FillRectangle(rcCentral, textFore); PRectangle rcChar = rcCChar; rcChar.left++; rcChar.right--; surface->DrawTextClipped(rcChar, ctrlCharsFont, rcSegment.top + vsDraw.maxAscent, s, istrlen(s), textBack, textFore); } void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll, int line, int lineEnd, int xStart, int subLine, XYACCUMULATOR subLineStart, bool overrideBackground, ColourDesired background, bool drawWrapMarkEnd, ColourDesired wrapColour) { const int posLineStart = pdoc->LineStart(line); const int styleMask = pdoc->stylingBitsMask; PRectangle rcSegment = rcLine; const bool lastSubLine = subLine == (ll->lines - 1); XYPOSITION virtualSpace = 0; if (lastSubLine) { const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth; virtualSpace = sel.VirtualSpaceFor(pdoc->LineEnd(line)) * spaceWidth; } XYPOSITION xEol = ll->positions[lineEnd] - subLineStart; // Fill the virtual space and show selections within it if (virtualSpace) { rcSegment.left = xEol + xStart; rcSegment.right = xEol + xStart + virtualSpace; surface->FillRectangle(rcSegment, overrideBackground ? background : vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back); if (!hideSelection && ((vsDraw.selAlpha == SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA))) { SelectionSegment virtualSpaceRange(SelectionPosition(pdoc->LineEnd(line)), SelectionPosition(pdoc->LineEnd(line), sel.VirtualSpaceFor(pdoc->LineEnd(line)))); for (size_t r=0; r<sel.Count(); r++) { int alpha = (r == sel.Main()) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha; if (alpha == SC_ALPHA_NOALPHA) { SelectionSegment portion = sel.Range(r).Intersect(virtualSpaceRange); if (!portion.Empty()) { const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth; rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] - subLineStart + portion.start.VirtualSpace() * spaceWidth; rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] - subLineStart + portion.end.VirtualSpace() * spaceWidth; rcSegment.left = (rcSegment.left > rcLine.left) ? rcSegment.left : rcLine.left; rcSegment.right = (rcSegment.right < rcLine.right) ? rcSegment.right : rcLine.right; surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, r == sel.Main())); } } } } } int eolInSelection = 0; int alpha = SC_ALPHA_NOALPHA; if (!hideSelection) { int posAfterLineEnd = pdoc->LineStart(line + 1); eolInSelection = (subLine == (ll->lines - 1)) ? sel.InSelectionForEOL(posAfterLineEnd) : 0; alpha = (eolInSelection == 1) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha; } // Draw the [CR], [LF], or [CR][LF] blobs if visible line ends are on XYPOSITION blobsWidth = 0; if (lastSubLine) { for (int eolPos=ll->numCharsBeforeEOL; eolPos<ll->numCharsInLine; eolPos++) { rcSegment.left = xStart + ll->positions[eolPos] - subLineStart + virtualSpace; rcSegment.right = xStart + ll->positions[eolPos+1] - subLineStart + virtualSpace; blobsWidth += rcSegment.Width(); char hexits[4]; const char *ctrlChar; unsigned char chEOL = ll->chars[eolPos]; if (UTF8IsAscii(chEOL)) { ctrlChar = ControlCharacterString(chEOL); } else { sprintf(hexits, "x%2X", chEOL); ctrlChar = hexits; } int styleMain = ll->styles[eolPos]; ColourDesired textBack = TextBackground(vsDraw, overrideBackground, background, eolInSelection, false, styleMain, eolPos, ll); ColourDesired textFore = vsDraw.styles[styleMain].fore; if (eolInSelection && vsDraw.selforeset) { textFore = (eolInSelection == 1) ? vsDraw.selforeground : vsDraw.selAdditionalForeground; } if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1)) { if (alpha == SC_ALPHA_NOALPHA) { surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1)); } else { surface->FillRectangle(rcSegment, textBack); } } else { surface->FillRectangle(rcSegment, textBack); } DrawTextBlob(surface, vsDraw, rcSegment, ctrlChar, textBack, textFore, twoPhaseDraw); if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) { SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1), alpha); } } } // Draw the eol-is-selected rectangle rcSegment.left = xEol + xStart + virtualSpace + blobsWidth; rcSegment.right = rcSegment.left + vsDraw.aveCharWidth; if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) { surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1)); } else { if (overrideBackground) { surface->FillRectangle(rcSegment, background); } else if (line < pdoc->LinesTotal() - 1) { surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back); } else if (vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].eolFilled) { surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back); } else { surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back); } if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) { SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1), alpha); } } // Fill the remainder of the line rcSegment.left = rcSegment.right; if (rcSegment.left < rcLine.left) rcSegment.left = rcLine.left; rcSegment.right = rcLine.right; if (eolInSelection && vsDraw.selEOLFilled && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) { surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1)); } else { if (overrideBackground) { surface->FillRectangle(rcSegment, background); } else if (vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].eolFilled) { surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back); } else { surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back); } if (eolInSelection && vsDraw.selEOLFilled && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) { SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1), alpha); } } if (drawWrapMarkEnd) { PRectangle rcPlace = rcSegment; if (wrapVisualFlagsLocation & SC_WRAPVISUALFLAGLOC_END_BY_TEXT) { rcPlace.left = xEol + xStart + virtualSpace; rcPlace.right = rcPlace.left + vsDraw.aveCharWidth; } else { // rcLine is clipped to text area rcPlace.right = rcLine.right; rcPlace.left = rcPlace.right - vsDraw.aveCharWidth; } DrawWrapMarker(surface, rcPlace, true, wrapColour); } } void Editor::DrawIndicator(int indicNum, int startPos, int endPos, Surface *surface, ViewStyle &vsDraw, int xStart, PRectangle rcLine, LineLayout *ll, int subLine) { const XYPOSITION subLineStart = ll->positions[ll->LineStart(subLine)]; PRectangle rcIndic( ll->positions[startPos] + xStart - subLineStart, rcLine.top + vsDraw.maxAscent, ll->positions[endPos] + xStart - subLineStart, rcLine.top + vsDraw.maxAscent + 3); vsDraw.indicators[indicNum].Draw(surface, rcIndic, rcLine); } void Editor::DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart, PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under) { // Draw decorators const int posLineStart = pdoc->LineStart(line); const int lineStart = ll->LineStart(subLine); const int posLineEnd = posLineStart + lineEnd; if (!under) { // Draw indicators // foreach indicator... for (int indicnum = 0, mask = 1 << pdoc->stylingBits; mask < 0x100; indicnum++) { if (!(mask & ll->styleBitsSet)) { mask <<= 1; continue; } int startPos = -1; // foreach style pos in line... for (int indicPos = lineStart; indicPos <= lineEnd; indicPos++) { // look for starts... if (startPos < 0) { // NOT in indicator run, looking for START if (indicPos < lineEnd && (ll->indicators[indicPos] & mask)) startPos = indicPos; } // ... or ends if (startPos >= 0) { // IN indicator run, looking for END if (indicPos >= lineEnd || !(ll->indicators[indicPos] & mask)) { // AT end of indicator run, DRAW it! DrawIndicator(indicnum, startPos, indicPos, surface, vsDraw, xStart, rcLine, ll, subLine); // RESET control var startPos = -1; } } } mask <<= 1; } } for (Decoration *deco = pdoc->decorations.root; deco; deco = deco->next) { if (under == vsDraw.indicators[deco->indicator].under) { int startPos = posLineStart + lineStart; if (!deco->rs.ValueAt(startPos)) { startPos = deco->rs.EndRun(startPos); } while ((startPos < posLineEnd) && (deco->rs.ValueAt(startPos))) { int endPos = deco->rs.EndRun(startPos); if (endPos > posLineEnd) endPos = posLineEnd; DrawIndicator(deco->indicator, startPos - posLineStart, endPos - posLineStart, surface, vsDraw, xStart, rcLine, ll, subLine); startPos = deco->rs.EndRun(endPos); } } } // Use indicators to highlight matching braces if ((vs.braceHighlightIndicatorSet && (bracesMatchStyle == STYLE_BRACELIGHT)) || (vs.braceBadLightIndicatorSet && (bracesMatchStyle == STYLE_BRACEBAD))) { int braceIndicator = (bracesMatchStyle == STYLE_BRACELIGHT) ? vs.braceHighlightIndicator : vs.braceBadLightIndicator; if (under == vsDraw.indicators[braceIndicator].under) { Range rangeLine(posLineStart + lineStart, posLineEnd); if (rangeLine.ContainsCharacter(braces[0])) { int braceOffset = braces[0] - posLineStart; if (braceOffset < ll->numCharsInLine) { DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, xStart, rcLine, ll, subLine); } } if (rangeLine.ContainsCharacter(braces[1])) { int braceOffset = braces[1] - posLineStart; if (braceOffset < ll->numCharsInLine) { DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, xStart, rcLine, ll, subLine); } } } } } void Editor::DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart, PRectangle rcLine, LineLayout *ll, int subLine) { int indent = pdoc->GetLineIndentation(line) * vsDraw.spaceWidth; PRectangle rcSegment = rcLine; int annotationLine = subLine - ll->lines; const StyledText stAnnotation = pdoc->AnnotationStyledText(line); if (stAnnotation.text && ValidStyledText(vsDraw, vsDraw.annotationStyleOffset, stAnnotation)) { surface->FillRectangle(rcSegment, vsDraw.styles[0].back); if (vs.annotationVisible == ANNOTATION_BOXED) { // Only care about calculating width if need to draw box int widthAnnotation = WidestLineWidth(surface, vsDraw, vsDraw.annotationStyleOffset, stAnnotation); widthAnnotation += vsDraw.spaceWidth * 2; // Margins rcSegment.left = xStart + indent; rcSegment.right = rcSegment.left + widthAnnotation; } else { rcSegment.left = xStart; } const int annotationLines = pdoc->AnnotationLines(line); size_t start = 0; size_t lengthAnnotation = stAnnotation.LineLength(start); int lineInAnnotation = 0; while ((lineInAnnotation < annotationLine) && (start < stAnnotation.length)) { start += lengthAnnotation + 1; lengthAnnotation = stAnnotation.LineLength(start); lineInAnnotation++; } PRectangle rcText = rcSegment; if (vs.annotationVisible == ANNOTATION_BOXED) { surface->FillRectangle(rcText, vsDraw.styles[stAnnotation.StyleAt(start) + vsDraw.annotationStyleOffset].back); rcText.left += vsDraw.spaceWidth; } DrawStyledText(surface, vsDraw, vsDraw.annotationStyleOffset, rcText, rcText.top + vsDraw.maxAscent, stAnnotation, start, lengthAnnotation); if (vs.annotationVisible == ANNOTATION_BOXED) { surface->PenColour(vsDraw.styles[vsDraw.annotationStyleOffset].fore); surface->MoveTo(rcSegment.left, rcSegment.top); surface->LineTo(rcSegment.left, rcSegment.bottom); surface->MoveTo(rcSegment.right, rcSegment.top); surface->LineTo(rcSegment.right, rcSegment.bottom); if (subLine == ll->lines) { surface->MoveTo(rcSegment.left, rcSegment.top); surface->LineTo(rcSegment.right, rcSegment.top); } if (subLine == ll->lines+annotationLines-1) { surface->MoveTo(rcSegment.left, rcSegment.bottom - 1); surface->LineTo(rcSegment.right, rcSegment.bottom - 1); } } } } void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart, PRectangle rcLine, LineLayout *ll, int subLine) { PRectangle rcSegment = rcLine; // Using one font for all control characters so it can be controlled independently to ensure // the box goes around the characters tightly. Seems to be no way to work out what height // is taken by an individual character - internal leading gives varying results. Font &ctrlCharsFont = vsDraw.styles[STYLE_CONTROLCHAR].font; // See if something overrides the line background color: Either if caret is on the line // and background color is set for that, or if a marker is defined that forces its background // color onto the line, or if a marker is defined but has no selection margin in which to // display itself (as long as it's not an SC_MARK_EMPTY marker). These are checked in order // with the earlier taking precedence. When multiple markers cause background override, // the color for the highest numbered one is used. bool overrideBackground = false; ColourDesired background; if ((caret.active || vsDraw.alwaysShowCaretLineBackground) && vsDraw.showCaretLineBackground && (vsDraw.caretLineAlpha == SC_ALPHA_NOALPHA) && ll->containsCaret) { overrideBackground = true; background = vsDraw.caretLineBackground; } if (!overrideBackground) { int marks = pdoc->GetMark(line); for (int markBit = 0; (markBit < 32) && marks; markBit++) { if ((marks & 1) && (vsDraw.markers[markBit].markType == SC_MARK_BACKGROUND) && (vsDraw.markers[markBit].alpha == SC_ALPHA_NOALPHA)) { background = vsDraw.markers[markBit].back; overrideBackground = true; } marks >>= 1; } } if (!overrideBackground) { if (vsDraw.maskInLine) { int marksMasked = pdoc->GetMark(line) & vsDraw.maskInLine; if (marksMasked) { for (int markBit = 0; (markBit < 32) && marksMasked; markBit++) { if ((marksMasked & 1) && (vsDraw.markers[markBit].markType != SC_MARK_EMPTY) && (vsDraw.markers[markBit].alpha == SC_ALPHA_NOALPHA)) { overrideBackground = true; background = vsDraw.markers[markBit].back; } marksMasked >>= 1; } } } } bool drawWhitespaceBackground = (vsDraw.viewWhitespace != wsInvisible) && (!overrideBackground) && (vsDraw.whitespaceBackgroundSet); bool inIndentation = subLine == 0; // Do not handle indentation except on first subline. const XYPOSITION indentWidth = pdoc->IndentSize() * vsDraw.spaceWidth; const XYPOSITION epsilon = 0.0001f; // A small nudge to avoid floating point precision issues int posLineStart = pdoc->LineStart(line); int startseg = ll->LineStart(subLine); XYACCUMULATOR subLineStart = ll->positions[startseg]; if (subLine >= ll->lines) { DrawAnnotation(surface, vsDraw, line, xStart, rcLine, ll, subLine); return; // No further drawing } int lineStart = 0; int lineEnd = 0; if (subLine < ll->lines) { lineStart = ll->LineStart(subLine); lineEnd = ll->LineStart(subLine + 1); if (subLine == ll->lines - 1) { lineEnd = ll->numCharsBeforeEOL; } } ColourDesired wrapColour = vsDraw.styles[STYLE_DEFAULT].fore; if (vsDraw.whitespaceForegroundSet) wrapColour = vsDraw.whitespaceForeground; bool drawWrapMarkEnd = false; if (wrapVisualFlags & SC_WRAPVISUALFLAG_END) { if (subLine + 1 < ll->lines) { drawWrapMarkEnd = ll->LineStart(subLine + 1) != 0; } } if (ll->wrapIndent != 0) { bool continuedWrapLine = false; if (subLine < ll->lines) { continuedWrapLine = ll->LineStart(subLine) != 0; } if (continuedWrapLine) { // draw continuation rect PRectangle rcPlace = rcSegment; rcPlace.left = ll->positions[startseg] + xStart - subLineStart; rcPlace.right = rcPlace.left + ll->wrapIndent; // default bgnd here.. surface->FillRectangle(rcSegment, overrideBackground ? background : vsDraw.styles[STYLE_DEFAULT].back); // main line style would be below but this would be inconsistent with end markers // also would possibly not be the style at wrap point //int styleMain = ll->styles[lineStart]; //surface->FillRectangle(rcPlace, vsDraw.styles[styleMain].back); if (wrapVisualFlags & SC_WRAPVISUALFLAG_START) { if (wrapVisualFlagsLocation & SC_WRAPVISUALFLAGLOC_START_BY_TEXT) rcPlace.left = rcPlace.right - vsDraw.aveCharWidth; else rcPlace.right = rcPlace.left + vsDraw.aveCharWidth; DrawWrapMarker(surface, rcPlace, false, wrapColour); } xStart += static_cast<int>(ll->wrapIndent); } } bool selBackDrawn = vsDraw.selbackset && ((vsDraw.selAlpha == SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA)); // Does not take margin into account but not significant int xStartVisible = static_cast<int>(subLineStart) - xStart; ll->psel = &sel; BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, xStartVisible, selBackDrawn, pdoc); int next = bfBack.First(); // Background drawing loop while (twoPhaseDraw && (next < lineEnd)) { startseg = next; next = bfBack.Next(); int i = next - 1; int iDoc = i + posLineStart; rcSegment.left = ll->positions[startseg] + xStart - subLineStart; rcSegment.right = ll->positions[i + 1] + xStart - subLineStart; // Only try to draw if really visible - enhances performance by not calling environment to // draw strings that are completely past the right side of the window. if ((rcSegment.left <= rcLine.right) && (rcSegment.right >= rcLine.left)) { // Clip to line rectangle, since may have a huge position which will not work with some platforms if (rcSegment.left < rcLine.left) rcSegment.left = rcLine.left; if (rcSegment.right > rcLine.right) rcSegment.right = rcLine.right; int styleMain = ll->styles[i]; const int inSelection = hideSelection ? 0 : sel.CharacterInSelection(iDoc); bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd); ColourDesired textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll); if (ll->chars[i] == '\t') { // Tab display if (drawWhitespaceBackground && (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) textBack = vsDraw.whitespaceBackground; surface->FillRectangle(rcSegment, textBack); } else if (IsControlCharacter(ll->chars[i])) { // Control character display inIndentation = false; surface->FillRectangle(rcSegment, textBack); } else { // Normal text display surface->FillRectangle(rcSegment, textBack); if (vsDraw.viewWhitespace != wsInvisible || (inIndentation && vsDraw.viewIndentationGuides == ivReal)) { for (int cpos = 0; cpos <= i - startseg; cpos++) { if (ll->chars[cpos + startseg] == ' ') { if (drawWhitespaceBackground && (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) { PRectangle rcSpace(ll->positions[cpos + startseg] + xStart - subLineStart, rcSegment.top, ll->positions[cpos + startseg + 1] + xStart - subLineStart, rcSegment.bottom); surface->FillRectangle(rcSpace, vsDraw.whitespaceBackground); } } else { inIndentation = false; } } } } } else if (rcSegment.left > rcLine.right) { break; } } if (twoPhaseDraw) { DrawEOL(surface, vsDraw, rcLine, ll, line, lineEnd, xStart, subLine, subLineStart, overrideBackground, background, drawWrapMarkEnd, wrapColour); } DrawIndicators(surface, vsDraw, line, xStart, rcLine, ll, subLine, lineEnd, true); if (vsDraw.edgeState == EDGE_LINE) { int edgeX = theEdge * vsDraw.spaceWidth; rcSegment.left = edgeX + xStart; if ((ll->wrapIndent != 0) && (lineStart != 0)) rcSegment.left -= ll->wrapIndent; rcSegment.right = rcSegment.left + 1; surface->FillRectangle(rcSegment, vsDraw.edgecolour); } // Draw underline mark as part of background if not transparent int marks = pdoc->GetMark(line); int markBit; for (markBit = 0; (markBit < 32) && marks; markBit++) { if ((marks & 1) && (vsDraw.markers[markBit].markType == SC_MARK_UNDERLINE) && (vsDraw.markers[markBit].alpha == SC_ALPHA_NOALPHA)) { PRectangle rcUnderline = rcLine; rcUnderline.top = rcUnderline.bottom - 2; surface->FillRectangle(rcUnderline, vsDraw.markers[markBit].back); } marks >>= 1; } inIndentation = subLine == 0; // Do not handle indentation except on first subline. // Foreground drawing loop BreakFinder bfFore(ll, lineStart, lineEnd, posLineStart, xStartVisible, ((!twoPhaseDraw && selBackDrawn) || vsDraw.selforeset), pdoc); next = bfFore.First(); while (next < lineEnd) { startseg = next; next = bfFore.Next(); int i = next - 1; int iDoc = i + posLineStart; rcSegment.left = ll->positions[startseg] + xStart - subLineStart; rcSegment.right = ll->positions[i + 1] + xStart - subLineStart; // Only try to draw if really visible - enhances performance by not calling environment to // draw strings that are completely past the right side of the window. if ((rcSegment.left <= rcLine.right) && (rcSegment.right >= rcLine.left)) { int styleMain = ll->styles[i]; ColourDesired textFore = vsDraw.styles[styleMain].fore; Font &textFont = vsDraw.styles[styleMain].font; //hotspot foreground if (ll->hsStart != -1 && iDoc >= ll->hsStart && iDoc < hsEnd) { if (vsDraw.hotspotForegroundSet) textFore = vsDraw.hotspotForeground; } const int inSelection = hideSelection ? 0 : sel.CharacterInSelection(iDoc); if (inSelection && (vsDraw.selforeset)) { textFore = (inSelection == 1) ? vsDraw.selforeground : vsDraw.selAdditionalForeground; } bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd); ColourDesired textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll); if (ll->chars[i] == '\t') { // Tab display if (!twoPhaseDraw) { if (drawWhitespaceBackground && (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) textBack = vsDraw.whitespaceBackground; surface->FillRectangle(rcSegment, textBack); } if (inIndentation && vsDraw.viewIndentationGuides == ivReal) { for (int indentCount = (ll->positions[i] + epsilon) / indentWidth; indentCount <= (ll->positions[i + 1] - epsilon) / indentWidth; indentCount++) { if (indentCount > 0) { int xIndent = indentCount * indentWidth; DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment, (ll->xHighlightGuide == xIndent)); } } } if (vsDraw.viewWhitespace != wsInvisible) { if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) { if (vsDraw.whitespaceForegroundSet) textFore = vsDraw.whitespaceForeground; surface->PenColour(textFore); PRectangle rcTab(rcSegment.left + 1, rcSegment.top + 4, rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent); DrawTabArrow(surface, rcTab, rcSegment.top + vsDraw.lineHeight / 2); } } } else if (IsControlCharacter(ll->chars[i])) { // Control character display inIndentation = false; if (controlCharSymbol < 32) { // Draw the character const char *ctrlChar = ControlCharacterString(ll->chars[i]); DrawTextBlob(surface, vsDraw, rcSegment, ctrlChar, textBack, textFore, twoPhaseDraw); } else { char cc[2] = { static_cast<char>(controlCharSymbol), '\0' }; surface->DrawTextNoClip(rcSegment, ctrlCharsFont, rcSegment.top + vsDraw.maxAscent, cc, 1, textBack, textFore); } } else if ((i == startseg) && (static_cast<unsigned char>(ll->chars[i]) >= 0x80) && IsUnicodeMode()) { // A single byte >= 0x80 in UTF-8 is a bad byte and is displayed as its hex value char hexits[4]; sprintf(hexits, "x%2X", ll->chars[i] & 0xff); DrawTextBlob(surface, vsDraw, rcSegment, hexits, textBack, textFore, twoPhaseDraw); } else { // Normal text display if (vsDraw.styles[styleMain].visible) { if (twoPhaseDraw) { surface->DrawTextTransparent(rcSegment, textFont, rcSegment.top + vsDraw.maxAscent, ll->chars + startseg, i - startseg + 1, textFore); } else { surface->DrawTextNoClip(rcSegment, textFont, rcSegment.top + vsDraw.maxAscent, ll->chars + startseg, i - startseg + 1, textFore, textBack); } } if (vsDraw.viewWhitespace != wsInvisible || (inIndentation && vsDraw.viewIndentationGuides != ivNone)) { for (int cpos = 0; cpos <= i - startseg; cpos++) { if (ll->chars[cpos + startseg] == ' ') { if (vsDraw.viewWhitespace != wsInvisible) { if (vsDraw.whitespaceForegroundSet) textFore = vsDraw.whitespaceForeground; if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) { XYPOSITION xmid = (ll->positions[cpos + startseg] + ll->positions[cpos + startseg + 1]) / 2; if (!twoPhaseDraw && drawWhitespaceBackground && (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways)) { textBack = vsDraw.whitespaceBackground; PRectangle rcSpace(ll->positions[cpos + startseg] + xStart - subLineStart, rcSegment.top, ll->positions[cpos + startseg + 1] + xStart - subLineStart, rcSegment.bottom); surface->FillRectangle(rcSpace, textBack); } PRectangle rcDot(xmid + xStart - subLineStart, rcSegment.top + vsDraw.lineHeight / 2, 0, 0); rcDot.right = rcDot.left + vs.whitespaceSize; rcDot.bottom = rcDot.top + vs.whitespaceSize; surface->FillRectangle(rcDot, textFore); } } if (inIndentation && vsDraw.viewIndentationGuides == ivReal) { for (int indentCount = (ll->positions[cpos + startseg] + epsilon) / indentWidth; indentCount <= (ll->positions[cpos + startseg + 1] - epsilon) / indentWidth; indentCount++) { if (indentCount > 0) { int xIndent = indentCount * indentWidth; DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment, (ll->xHighlightGuide == xIndent)); } } } } else { inIndentation = false; } } } } if (ll->hsStart != -1 && vsDraw.hotspotUnderline && iDoc >= ll->hsStart && iDoc < ll->hsEnd) { PRectangle rcUL = rcSegment; rcUL.top = rcUL.top + vsDraw.maxAscent + 1; rcUL.bottom = rcUL.top + 1; if (vsDraw.hotspotForegroundSet) surface->FillRectangle(rcUL, vsDraw.hotspotForeground); else surface->FillRectangle(rcUL, textFore); } else if (vsDraw.styles[styleMain].underline) { PRectangle rcUL = rcSegment; rcUL.top = rcUL.top + vsDraw.maxAscent + 1; rcUL.bottom = rcUL.top + 1; surface->FillRectangle(rcUL, textFore); } } else if (rcSegment.left > rcLine.right) { break; } } if ((vsDraw.viewIndentationGuides == ivLookForward || vsDraw.viewIndentationGuides == ivLookBoth) && (subLine == 0)) { int indentSpace = pdoc->GetLineIndentation(line); int xStartText = ll->positions[pdoc->GetLineIndentPosition(line) - posLineStart]; // Find the most recent line with some text int lineLastWithText = line; while (lineLastWithText > Platform::Maximum(line-20, 0) && pdoc->IsWhiteLine(lineLastWithText)) { lineLastWithText--; } if (lineLastWithText < line) { xStartText = 100000; // Don't limit to visible indentation on empty line // This line is empty, so use indentation of last line with text int indentLastWithText = pdoc->GetLineIndentation(lineLastWithText); int isFoldHeader = pdoc->GetLevel(lineLastWithText) & SC_FOLDLEVELHEADERFLAG; if (isFoldHeader) { // Level is one more level than parent indentLastWithText += pdoc->IndentSize(); } if (vsDraw.viewIndentationGuides == ivLookForward) { // In viLookForward mode, previous line only used if it is a fold header if (isFoldHeader) { indentSpace = Platform::Maximum(indentSpace, indentLastWithText); } } else { // viLookBoth indentSpace = Platform::Maximum(indentSpace, indentLastWithText); } } int lineNextWithText = line; while (lineNextWithText < Platform::Minimum(line+20, pdoc->LinesTotal()) && pdoc->IsWhiteLine(lineNextWithText)) { lineNextWithText++; } if (lineNextWithText > line) { xStartText = 100000; // Don't limit to visible indentation on empty line // This line is empty, so use indentation of first next line with text indentSpace = Platform::Maximum(indentSpace, pdoc->GetLineIndentation(lineNextWithText)); } for (int indentPos = pdoc->IndentSize(); indentPos < indentSpace; indentPos += pdoc->IndentSize()) { int xIndent = indentPos * vsDraw.spaceWidth; if (xIndent < xStartText) { DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment, (ll->xHighlightGuide == xIndent)); } } } DrawIndicators(surface, vsDraw, line, xStart, rcLine, ll, subLine, lineEnd, false); // End of the drawing of the current line if (!twoPhaseDraw) { DrawEOL(surface, vsDraw, rcLine, ll, line, lineEnd, xStart, subLine, subLineStart, overrideBackground, background, drawWrapMarkEnd, wrapColour); } if (!hideSelection && ((vsDraw.selAlpha != SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha != SC_ALPHA_NOALPHA))) { // For each selection draw int virtualSpaces = 0; if (subLine == (ll->lines - 1)) { virtualSpaces = sel.VirtualSpaceFor(pdoc->LineEnd(line)); } SelectionPosition posStart(posLineStart + lineStart); SelectionPosition posEnd(posLineStart + lineEnd, virtualSpaces); SelectionSegment virtualSpaceRange(posStart, posEnd); for (size_t r=0; r<sel.Count(); r++) { int alpha = (r == sel.Main()) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha; if (alpha != SC_ALPHA_NOALPHA) { SelectionSegment portion = sel.Range(r).Intersect(virtualSpaceRange); if (!portion.Empty()) { const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth; rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] - subLineStart + portion.start.VirtualSpace() * spaceWidth; rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] - subLineStart + portion.end.VirtualSpace() * spaceWidth; if ((ll->wrapIndent != 0) && (lineStart != 0)) { if ((portion.start.Position() - posLineStart) == lineStart && sel.Range(r).ContainsCharacter(portion.start.Position() - 1)) rcSegment.left -= static_cast<int>(ll->wrapIndent); // indentation added to xStart was truncated to int, so we do the same here } rcSegment.left = (rcSegment.left > rcLine.left) ? rcSegment.left : rcLine.left; rcSegment.right = (rcSegment.right < rcLine.right) ? rcSegment.right : rcLine.right; if (rcSegment.right > rcLine.left) SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, r == sel.Main()), alpha); } } } } // Draw any translucent whole line states rcSegment = rcLine; if ((caret.active || vsDraw.alwaysShowCaretLineBackground) && vsDraw.showCaretLineBackground && ll->containsCaret) { SimpleAlphaRectangle(surface, rcSegment, vsDraw.caretLineBackground, vsDraw.caretLineAlpha); } marks = pdoc->GetMark(line); for (markBit = 0; (markBit < 32) && marks; markBit++) { if ((marks & 1) && (vsDraw.markers[markBit].markType == SC_MARK_BACKGROUND)) { SimpleAlphaRectangle(surface, rcSegment, vsDraw.markers[markBit].back, vsDraw.markers[markBit].alpha); } else if ((marks & 1) && (vsDraw.markers[markBit].markType == SC_MARK_UNDERLINE)) { PRectangle rcUnderline = rcSegment; rcUnderline.top = rcUnderline.bottom - 2; SimpleAlphaRectangle(surface, rcUnderline, vsDraw.markers[markBit].back, vsDraw.markers[markBit].alpha); } marks >>= 1; } if (vsDraw.maskInLine) { int marksMasked = pdoc->GetMark(line) & vsDraw.maskInLine; if (marksMasked) { for (markBit = 0; (markBit < 32) && marksMasked; markBit++) { if ((marksMasked & 1) && (vsDraw.markers[markBit].markType != SC_MARK_EMPTY)) { SimpleAlphaRectangle(surface, rcSegment, vsDraw.markers[markBit].back, vsDraw.markers[markBit].alpha); } marksMasked >>= 1; } } } } void Editor::DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine, int xStart, int offset, int posCaret, PRectangle rcCaret, ColourDesired caretColour) { int lineStart = ll->LineStart(subLine); int posBefore = posCaret; int posAfter = MovePositionOutsideChar(posCaret + 1, 1); int numCharsToDraw = posAfter - posCaret; // Work out where the starting and ending offsets are. We need to // see if the previous character shares horizontal space, such as a // glyph / combining character. If so we'll need to draw that too. int offsetFirstChar = offset; int offsetLastChar = offset + (posAfter - posCaret); while ((posBefore > 0) && ((offsetLastChar - numCharsToDraw) >= lineStart)) { if ((ll->positions[offsetLastChar] - ll->positions[offsetLastChar - numCharsToDraw]) > 0) { // The char does not share horizontal space break; } // Char shares horizontal space, update the numChars to draw // Update posBefore to point to the prev char posBefore = MovePositionOutsideChar(posBefore - 1, -1); numCharsToDraw = posAfter - posBefore; offsetFirstChar = offset - (posCaret - posBefore); } // See if the next character shares horizontal space, if so we'll // need to draw that too. if (offsetFirstChar < 0) offsetFirstChar = 0; numCharsToDraw = offsetLastChar - offsetFirstChar; while ((offsetLastChar < ll->LineStart(subLine + 1)) && (offsetLastChar <= ll->numCharsInLine)) { // Update posAfter to point to the 2nd next char, this is where // the next character ends, and 2nd next begins. We'll need // to compare these two posBefore = posAfter; posAfter = MovePositionOutsideChar(posAfter + 1, 1); offsetLastChar = offset + (posAfter - posCaret); if ((ll->positions[offsetLastChar] - ll->positions[offsetLastChar - (posAfter - posBefore)]) > 0) { // The char does not share horizontal space break; } // Char shares horizontal space, update the numChars to draw numCharsToDraw = offsetLastChar - offsetFirstChar; } // We now know what to draw, update the caret drawing rectangle rcCaret.left = ll->positions[offsetFirstChar] - ll->positions[lineStart] + xStart; rcCaret.right = ll->positions[offsetFirstChar+numCharsToDraw] - ll->positions[lineStart] + xStart; // Adjust caret position to take into account any word wrapping symbols. if ((ll->wrapIndent != 0) && (lineStart != 0)) { XYPOSITION wordWrapCharWidth = ll->wrapIndent; rcCaret.left += wordWrapCharWidth; rcCaret.right += wordWrapCharWidth; } // This character is where the caret block is, we override the colours // (inversed) for drawing the caret here. int styleMain = ll->styles[offsetFirstChar]; surface->DrawTextClipped(rcCaret, vsDraw.styles[styleMain].font, rcCaret.top + vsDraw.maxAscent, ll->chars + offsetFirstChar, numCharsToDraw, vsDraw.styles[styleMain].back, caretColour); } void Editor::RefreshPixMaps(Surface *surfaceWindow) { if (!pixmapSelPattern->Initialised()) { const int patternSize = 8; pixmapSelPattern->InitPixMap(patternSize, patternSize, surfaceWindow, wMain.GetID()); pixmapSelPatternOffset1->InitPixMap(patternSize, patternSize, surfaceWindow, wMain.GetID()); // This complex procedure is to reproduce the checkerboard dithered pattern used by windows // for scroll bars and Visual Studio for its selection margin. The colour of this pattern is half // way between the chrome colour and the chrome highlight colour making a nice transition // between the window chrome and the content area. And it works in low colour depths. PRectangle rcPattern(0, 0, patternSize, patternSize); // Initialize default colours based on the chrome colour scheme. Typically the highlight is white. ColourDesired colourFMFill = vs.selbar; ColourDesired colourFMStripes = vs.selbarlight; if (!(vs.selbarlight == ColourDesired(0xff, 0xff, 0xff))) { // User has chosen an unusual chrome colour scheme so just use the highlight edge colour. // (Typically, the highlight colour is white.) colourFMFill = vs.selbarlight; } if (vs.foldmarginColourSet) { // override default fold margin colour colourFMFill = vs.foldmarginColour; } if (vs.foldmarginHighlightColourSet) { // override default fold margin highlight colour colourFMStripes = vs.foldmarginHighlightColour; } pixmapSelPattern->FillRectangle(rcPattern, colourFMFill); pixmapSelPatternOffset1->FillRectangle(rcPattern, colourFMStripes); for (int y = 0; y < patternSize; y++) { for (int x = y % 2; x < patternSize; x+=2) { PRectangle rcPixel(x, y, x+1, y+1); pixmapSelPattern->FillRectangle(rcPixel, colourFMStripes); pixmapSelPatternOffset1->FillRectangle(rcPixel, colourFMFill); } } } if (!pixmapIndentGuide->Initialised()) { // 1 extra pixel in height so can handle odd/even positions and so produce a continuous line pixmapIndentGuide->InitPixMap(1, vs.lineHeight + 1, surfaceWindow, wMain.GetID()); pixmapIndentGuideHighlight->InitPixMap(1, vs.lineHeight + 1, surfaceWindow, wMain.GetID()); PRectangle rcIG(0, 0, 1, vs.lineHeight); pixmapIndentGuide->FillRectangle(rcIG, vs.styles[STYLE_INDENTGUIDE].back); pixmapIndentGuide->PenColour(vs.styles[STYLE_INDENTGUIDE].fore); pixmapIndentGuideHighlight->FillRectangle(rcIG, vs.styles[STYLE_BRACELIGHT].back); pixmapIndentGuideHighlight->PenColour(vs.styles[STYLE_BRACELIGHT].fore); for (int stripe = 1; stripe < vs.lineHeight + 1; stripe += 2) { PRectangle rcPixel(0, stripe, 1, stripe+1); pixmapIndentGuide->FillRectangle(rcPixel, vs.styles[STYLE_INDENTGUIDE].fore); pixmapIndentGuideHighlight->FillRectangle(rcPixel, vs.styles[STYLE_BRACELIGHT].fore); } } if (bufferedDraw) { if (!pixmapLine->Initialised()) { PRectangle rcClient = GetClientRectangle(); pixmapLine->InitPixMap(rcClient.Width(), vs.lineHeight, surfaceWindow, wMain.GetID()); pixmapSelMargin->InitPixMap(vs.fixedColumnWidth, rcClient.Height(), surfaceWindow, wMain.GetID()); } } } void Editor::DrawCarets(Surface *surface, ViewStyle &vsDraw, int lineDoc, int xStart, PRectangle rcLine, LineLayout *ll, int subLine) { // When drag is active it is the only caret drawn bool drawDrag = posDrag.IsValid(); if (hideSelection && !drawDrag) return; const int posLineStart = pdoc->LineStart(lineDoc); // For each selection draw for (size_t r=0; (r<sel.Count()) || drawDrag; r++) { const bool mainCaret = r == sel.Main(); const SelectionPosition posCaret = (drawDrag ? posDrag : sel.Range(r).caret); const int offset = posCaret.Position() - posLineStart; const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth; const XYPOSITION virtualOffset = posCaret.VirtualSpace() * spaceWidth; if (ll->InLine(offset, subLine) && offset <= ll->numCharsBeforeEOL) { XYPOSITION xposCaret = ll->positions[offset] + virtualOffset - ll->positions[ll->LineStart(subLine)]; if (ll->wrapIndent != 0) { int lineStart = ll->LineStart(subLine); if (lineStart != 0) // Wrapped xposCaret += ll->wrapIndent; } bool caretBlinkState = (caret.active && caret.on) || (!additionalCaretsBlink && !mainCaret); bool caretVisibleState = additionalCaretsVisible || mainCaret; if ((xposCaret >= 0) && (vsDraw.caretWidth > 0) && (vsDraw.caretStyle != CARETSTYLE_INVISIBLE) && ((posDrag.IsValid()) || (caretBlinkState && caretVisibleState))) { bool caretAtEOF = false; bool caretAtEOL = false; bool drawBlockCaret = false; XYPOSITION widthOverstrikeCaret; int caretWidthOffset = 0; PRectangle rcCaret = rcLine; if (posCaret.Position() == pdoc->Length()) { // At end of document caretAtEOF = true; widthOverstrikeCaret = vsDraw.aveCharWidth; } else if ((posCaret.Position() - posLineStart) >= ll->numCharsInLine) { // At end of line caretAtEOL = true; widthOverstrikeCaret = vsDraw.aveCharWidth; } else { widthOverstrikeCaret = ll->positions[offset + 1] - ll->positions[offset]; } if (widthOverstrikeCaret < 3) // Make sure its visible widthOverstrikeCaret = 3; if (xposCaret > 0) caretWidthOffset = 1; // Move back so overlaps both character cells. xposCaret += xStart; if (posDrag.IsValid()) { /* Dragging text, use a line caret */ rcCaret.left = xposCaret - caretWidthOffset; rcCaret.right = rcCaret.left + vsDraw.caretWidth; } else if (inOverstrike) { /* Overstrike (insert mode), use a modified bar caret */ rcCaret.top = rcCaret.bottom - 2; rcCaret.left = xposCaret + 1; rcCaret.right = rcCaret.left + widthOverstrikeCaret - 1; } else if (vsDraw.caretStyle == CARETSTYLE_BLOCK) { /* Block caret */ rcCaret.left = xposCaret; if (!caretAtEOL && !caretAtEOF && (ll->chars[offset] != '\t') && !(IsControlCharacter(ll->chars[offset]))) { drawBlockCaret = true; rcCaret.right = xposCaret + widthOverstrikeCaret; } else { rcCaret.right = xposCaret + vsDraw.aveCharWidth; } } else { /* Line caret */ rcCaret.left = xposCaret - caretWidthOffset; rcCaret.right = rcCaret.left + vsDraw.caretWidth; } ColourDesired caretColour = mainCaret ? vsDraw.caretcolour : vsDraw.additionalCaretColour; if (drawBlockCaret) { DrawBlockCaret(surface, vsDraw, ll, subLine, xStart, offset, posCaret.Position(), rcCaret, caretColour); } else { surface->FillRectangle(rcCaret, caretColour); } } } if (drawDrag) break; } } void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { //Platform::DebugPrintf("Paint:%1d (%3d,%3d) ... (%3d,%3d)\n", // paintingAllText, rcArea.left, rcArea.top, rcArea.right, rcArea.bottom); AllocateGraphics(); RefreshStyleData(); if (paintState == paintAbandoned) return; // Scroll bars may have changed so need redraw RefreshPixMaps(surfaceWindow); StyleToPositionInView(PositionAfterArea(rcArea)); PRectangle rcClient = GetClientRectangle(); Point ptOrigin = GetVisibleOriginInMain(); //Platform::DebugPrintf("Client: (%3d,%3d) ... (%3d,%3d) %d\n", // rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); int screenLinePaintFirst = rcArea.top / vs.lineHeight; int xStart = vs.textStart - xOffset + ptOrigin.x; int ypos = 0; if (!bufferedDraw) ypos += screenLinePaintFirst * vs.lineHeight; int yposScreen = screenLinePaintFirst * vs.lineHeight; bool paintAbandonedByStyling = paintState == paintAbandoned; if (NotifyUpdateUI()) { RefreshStyleData(); RefreshPixMaps(surfaceWindow); } // Call priority lines wrap on a window of lines which are likely // to rendered with the following paint (that is wrap the visible // lines first). int startLineToWrap = cs.DocFromDisplay(topLine) - 5; if (startLineToWrap < 0) startLineToWrap = 0; if (WrapLines(false, startLineToWrap)) { // The wrapping process has changed the height of some lines so // abandon this paint for a complete repaint. if (AbandonPaint()) { return; } RefreshPixMaps(surfaceWindow); // In case pixmaps invalidated by scrollbar change } PLATFORM_ASSERT(pixmapSelPattern->Initialised()); if (!bufferedDraw) surfaceWindow->SetClip(rcArea); if (paintState != paintAbandoned) { if (vs.marginInside) { PaintSelMargin(surfaceWindow, rcArea); PRectangle rcRightMargin = rcClient; rcRightMargin.left = rcRightMargin.right - vs.rightMarginWidth; if (rcArea.Intersects(rcRightMargin)) { surfaceWindow->FillRectangle(rcRightMargin, vs.styles[STYLE_DEFAULT].back); } } else { // Else separate view so separate paint event but leftMargin included to allow overlap PRectangle rcLeftMargin = rcArea; rcLeftMargin.left = 0; rcLeftMargin.right = rcLeftMargin.left + vs.leftMarginWidth; if (rcArea.Intersects(rcLeftMargin)) { surfaceWindow->FillRectangle(rcLeftMargin, vs.styles[STYLE_DEFAULT].back); } } } if (paintState == paintAbandoned) { // Either styling or NotifyUpdateUI noticed that painting is needed // outside the current painting rectangle //Platform::DebugPrintf("Abandoning paint\n"); if (wrapState != eWrapNone) { if (paintAbandonedByStyling) { // Styling has spilled over a line end, such as occurs by starting a multiline // comment. The width of subsequent text may have changed, so rewrap. NeedWrapping(cs.DocFromDisplay(topLine)); } } return; } //Platform::DebugPrintf("start display %d, offset = %d\n", pdoc->Length(), xOffset); // Allow text at start of line to overlap 1 pixel into the margin as this displays // serifs and italic stems for aliased text. const int leftTextOverlap = ((xOffset == 0) && (vs.leftMarginWidth > 0)) ? 1 : 0; // Do the painting if (rcArea.right > vs.textStart - leftTextOverlap) { Surface *surface = surfaceWindow; if (bufferedDraw) { surface = pixmapLine; PLATFORM_ASSERT(pixmapLine->Initialised()); } surface->SetUnicodeMode(IsUnicodeMode()); surface->SetDBCSMode(CodePage()); int visibleLine = TopLineOfMain() + screenLinePaintFirst; SelectionPosition posCaret = sel.RangeMain().caret; if (posDrag.IsValid()) posCaret = posDrag; int lineCaret = pdoc->LineFromPosition(posCaret.Position()); PRectangle rcTextArea = rcClient; if (vs.marginInside) { rcTextArea.left += vs.textStart; rcTextArea.right -= vs.rightMarginWidth; } else { rcTextArea = rcArea; } // Remove selection margin from drawing area so text will not be drawn // on it in unbuffered mode. if (!bufferedDraw && vs.marginInside) { PRectangle rcClipText = rcTextArea; rcClipText.left -= leftTextOverlap; surfaceWindow->SetClip(rcClipText); } // Loop on visible lines //double durLayout = 0.0; //double durPaint = 0.0; //double durCopy = 0.0; //ElapsedTime etWhole; int lineDocPrevious = -1; // Used to avoid laying out one document line multiple times AutoLineLayout ll(llc, 0); while (visibleLine < cs.LinesDisplayed() && yposScreen < rcArea.bottom) { int lineDoc = cs.DocFromDisplay(visibleLine); // Only visible lines should be handled by the code within the loop PLATFORM_ASSERT(cs.GetVisible(lineDoc)); int lineStartSet = cs.DisplayFromDoc(lineDoc); int subLine = visibleLine - lineStartSet; // Copy this line and its styles from the document into local arrays // and determine the x position at which each character starts. //ElapsedTime et; if (lineDoc != lineDocPrevious) { ll.Set(0); ll.Set(RetrieveLineLayout(lineDoc)); LayoutLine(lineDoc, surface, vs, ll, wrapWidth); lineDocPrevious = lineDoc; } //durLayout += et.Duration(true); if (ll) { ll->containsCaret = lineDoc == lineCaret; if (hideSelection) { ll->containsCaret = false; } GetHotSpotRange(ll->hsStart, ll->hsEnd); PRectangle rcLine = rcTextArea; rcLine.top = ypos; rcLine.bottom = ypos + vs.lineHeight; bool bracesIgnoreStyle = false; if ((vs.braceHighlightIndicatorSet && (bracesMatchStyle == STYLE_BRACELIGHT)) || (vs.braceBadLightIndicatorSet && (bracesMatchStyle == STYLE_BRACEBAD))) { bracesIgnoreStyle = true; } Range rangeLine(pdoc->LineStart(lineDoc), pdoc->LineStart(lineDoc + 1)); // Highlight the current braces if any ll->SetBracesHighlight(rangeLine, braces, static_cast<char>(bracesMatchStyle), highlightGuideColumn * vs.spaceWidth, bracesIgnoreStyle); if (leftTextOverlap && bufferedDraw) { PRectangle rcSpacer = rcLine; rcSpacer.right = rcSpacer.left; rcSpacer.left -= 1; surface->FillRectangle(rcSpacer, vs.styles[STYLE_DEFAULT].back); } // Draw the line DrawLine(surface, vs, lineDoc, visibleLine, xStart, rcLine, ll, subLine); //durPaint += et.Duration(true); // Restore the previous styles for the brace highlights in case layout is in cache. ll->RestoreBracesHighlight(rangeLine, braces, bracesIgnoreStyle); bool expanded = cs.GetExpanded(lineDoc); const int level = pdoc->GetLevel(lineDoc); const int levelNext = pdoc->GetLevel(lineDoc + 1); if ((level & SC_FOLDLEVELHEADERFLAG) && ((level & SC_FOLDLEVELNUMBERMASK) < (levelNext & SC_FOLDLEVELNUMBERMASK))) { // Paint the line above the fold if ((expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_EXPANDED)) || (!expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_CONTRACTED))) { PRectangle rcFoldLine = rcLine; rcFoldLine.bottom = rcFoldLine.top + 1; surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore); } // Paint the line below the fold if ((expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_EXPANDED)) || (!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) { PRectangle rcFoldLine = rcLine; rcFoldLine.top = rcFoldLine.bottom - 1; surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore); } } DrawCarets(surface, vs, lineDoc, xStart, rcLine, ll, subLine); if (bufferedDraw) { Point from(vs.textStart-leftTextOverlap, 0); PRectangle rcCopyArea(vs.textStart-leftTextOverlap, yposScreen, rcClient.right - vs.rightMarginWidth, yposScreen + vs.lineHeight); surfaceWindow->Copy(rcCopyArea, from, *pixmapLine); } lineWidthMaxSeen = Platform::Maximum( lineWidthMaxSeen, ll->positions[ll->numCharsInLine]); //durCopy += et.Duration(true); } if (!bufferedDraw) { ypos += vs.lineHeight; } yposScreen += vs.lineHeight; visibleLine++; //gdk_flush(); } ll.Set(0); //if (durPaint < 0.00000001) // durPaint = 0.00000001; // Right column limit indicator PRectangle rcBeyondEOF = (vs.marginInside) ? rcClient : rcArea; rcBeyondEOF.left = vs.textStart; rcBeyondEOF.right = rcBeyondEOF.right - ((vs.marginInside) ? vs.rightMarginWidth : 0); rcBeyondEOF.top = (cs.LinesDisplayed() - TopLineOfMain()) * vs.lineHeight; if (rcBeyondEOF.top < rcBeyondEOF.bottom) { surfaceWindow->FillRectangle(rcBeyondEOF, vs.styles[STYLE_DEFAULT].back); if (vs.edgeState == EDGE_LINE) { int edgeX = theEdge * vs.spaceWidth; rcBeyondEOF.left = edgeX + xStart; rcBeyondEOF.right = rcBeyondEOF.left + 1; surfaceWindow->FillRectangle(rcBeyondEOF, vs.edgecolour); } } //Platform::DebugPrintf( //"Layout:%9.6g Paint:%9.6g Ratio:%9.6g Copy:%9.6g Total:%9.6g\n", //durLayout, durPaint, durLayout / durPaint, durCopy, etWhole.Duration()); NotifyPainted(); } } // Space (3 space characters) between line numbers and text when printing. #define lineNumberPrintSpace " " ColourDesired InvertedLight(ColourDesired orig) { unsigned int r = orig.GetRed(); unsigned int g = orig.GetGreen(); unsigned int b = orig.GetBlue(); unsigned int l = (r + g + b) / 3; // There is a better calculation for this that matches human eye unsigned int il = 0xff - l; if (l == 0) return ColourDesired(0xff, 0xff, 0xff); r = r * il / l; g = g * il / l; b = b * il / l; return ColourDesired(Platform::Minimum(r, 0xff), Platform::Minimum(g, 0xff), Platform::Minimum(b, 0xff)); } // This is mostly copied from the Paint method but with some things omitted // such as the margin markers, line numbers, selection and caret // Should be merged back into a combined Draw method. long Editor::FormatRange(bool draw, Sci_RangeToFormat *pfr) { if (!pfr) return 0; AutoSurface surface(pfr->hdc, this, SC_TECHNOLOGY_DEFAULT); if (!surface) return 0; AutoSurface surfaceMeasure(pfr->hdcTarget, this, SC_TECHNOLOGY_DEFAULT); if (!surfaceMeasure) { return 0; } // Can't use measurements cached for screen posCache.Clear(); ViewStyle vsPrint(vs); vsPrint.technology = SC_TECHNOLOGY_DEFAULT; // Modify the view style for printing as do not normally want any of the transient features to be printed // Printing supports only the line number margin. int lineNumberIndex = -1; for (int margin = 0; margin <= SC_MAX_MARGIN; margin++) { if ((vsPrint.ms[margin].style == SC_MARGIN_NUMBER) && (vsPrint.ms[margin].width > 0)) { lineNumberIndex = margin; } else { vsPrint.ms[margin].width = 0; } } vsPrint.fixedColumnWidth = 0; vsPrint.zoomLevel = printMagnification; // Don't show indentation guides // If this ever gets changed, cached pixmap would need to be recreated if technology != SC_TECHNOLOGY_DEFAULT vsPrint.viewIndentationGuides = ivNone; // Don't show the selection when printing vsPrint.selbackset = false; vsPrint.selforeset = false; vsPrint.selAlpha = SC_ALPHA_NOALPHA; vsPrint.selAdditionalAlpha = SC_ALPHA_NOALPHA; vsPrint.whitespaceBackgroundSet = false; vsPrint.whitespaceForegroundSet = false; vsPrint.showCaretLineBackground = false; vsPrint.alwaysShowCaretLineBackground = false; // Don't highlight matching braces using indicators vsPrint.braceHighlightIndicatorSet = false; vsPrint.braceBadLightIndicatorSet = false; // Set colours for printing according to users settings for (size_t sty = 0; sty < vsPrint.stylesSize; sty++) { if (printColourMode == SC_PRINT_INVERTLIGHT) { vsPrint.styles[sty].fore = InvertedLight(vsPrint.styles[sty].fore); vsPrint.styles[sty].back = InvertedLight(vsPrint.styles[sty].back); } else if (printColourMode == SC_PRINT_BLACKONWHITE) { vsPrint.styles[sty].fore = ColourDesired(0, 0, 0); vsPrint.styles[sty].back = ColourDesired(0xff, 0xff, 0xff); } else if (printColourMode == SC_PRINT_COLOURONWHITE) { vsPrint.styles[sty].back = ColourDesired(0xff, 0xff, 0xff); } else if (printColourMode == SC_PRINT_COLOURONWHITEDEFAULTBG) { if (sty <= STYLE_DEFAULT) { vsPrint.styles[sty].back = ColourDesired(0xff, 0xff, 0xff); } } } // White background for the line numbers vsPrint.styles[STYLE_LINENUMBER].back = ColourDesired(0xff, 0xff, 0xff); // Printing uses different margins, so reset screen margins vsPrint.leftMarginWidth = 0; vsPrint.rightMarginWidth = 0; vsPrint.Refresh(*surfaceMeasure); // Determining width must hapen after fonts have been realised in Refresh int lineNumberWidth = 0; if (lineNumberIndex >= 0) { lineNumberWidth = surfaceMeasure->WidthText(vsPrint.styles[STYLE_LINENUMBER].font, "99999" lineNumberPrintSpace, 5 + istrlen(lineNumberPrintSpace)); vsPrint.ms[lineNumberIndex].width = lineNumberWidth; vsPrint.Refresh(*surfaceMeasure); // Recalculate fixedColumnWidth } int linePrintStart = pdoc->LineFromPosition(pfr->chrg.cpMin); int linePrintLast = linePrintStart + (pfr->rc.bottom - pfr->rc.top) / vsPrint.lineHeight - 1; if (linePrintLast < linePrintStart) linePrintLast = linePrintStart; int linePrintMax = pdoc->LineFromPosition(pfr->chrg.cpMax); if (linePrintLast > linePrintMax) linePrintLast = linePrintMax; //Platform::DebugPrintf("Formatting lines=[%0d,%0d,%0d] top=%0d bottom=%0d line=%0d %0d\n", // linePrintStart, linePrintLast, linePrintMax, pfr->rc.top, pfr->rc.bottom, vsPrint.lineHeight, // surfaceMeasure->Height(vsPrint.styles[STYLE_LINENUMBER].font)); int endPosPrint = pdoc->Length(); if (linePrintLast < pdoc->LinesTotal()) endPosPrint = pdoc->LineStart(linePrintLast + 1); // Ensure we are styled to where we are formatting. pdoc->EnsureStyledTo(endPosPrint); int xStart = vsPrint.fixedColumnWidth + pfr->rc.left; int ypos = pfr->rc.top; int lineDoc = linePrintStart; int nPrintPos = pfr->chrg.cpMin; int visibleLine = 0; int widthPrint = pfr->rc.right - pfr->rc.left - vsPrint.fixedColumnWidth; if (printWrapState == eWrapNone) widthPrint = LineLayout::wrapWidthInfinite; while (lineDoc <= linePrintLast && ypos < pfr->rc.bottom) { // When printing, the hdc and hdcTarget may be the same, so // changing the state of surfaceMeasure may change the underlying // state of surface. Therefore, any cached state is discarded before // using each surface. surfaceMeasure->FlushCachedState(); // Copy this line and its styles from the document into local arrays // and determine the x position at which each character starts. LineLayout ll(pdoc->LineStart(lineDoc+1)-pdoc->LineStart(lineDoc)+1); LayoutLine(lineDoc, surfaceMeasure, vsPrint, &ll, widthPrint); ll.containsCaret = false; PRectangle rcLine; rcLine.left = pfr->rc.left; rcLine.top = ypos; rcLine.right = pfr->rc.right - 1; rcLine.bottom = ypos + vsPrint.lineHeight; // When document line is wrapped over multiple display lines, find where // to start printing from to ensure a particular position is on the first // line of the page. if (visibleLine == 0) { int startWithinLine = nPrintPos - pdoc->LineStart(lineDoc); for (int iwl = 0; iwl < ll.lines - 1; iwl++) { if (ll.LineStart(iwl) <= startWithinLine && ll.LineStart(iwl + 1) >= startWithinLine) { visibleLine = -iwl; } } if (ll.lines > 1 && startWithinLine >= ll.LineStart(ll.lines - 1)) { visibleLine = -(ll.lines - 1); } } if (draw && lineNumberWidth && (ypos + vsPrint.lineHeight <= pfr->rc.bottom) && (visibleLine >= 0)) { char number[100]; sprintf(number, "%d" lineNumberPrintSpace, lineDoc + 1); PRectangle rcNumber = rcLine; rcNumber.right = rcNumber.left + lineNumberWidth; // Right justify rcNumber.left = rcNumber.right - surfaceMeasure->WidthText( vsPrint.styles[STYLE_LINENUMBER].font, number, istrlen(number)); surface->FlushCachedState(); surface->DrawTextNoClip(rcNumber, vsPrint.styles[STYLE_LINENUMBER].font, ypos + vsPrint.maxAscent, number, istrlen(number), vsPrint.styles[STYLE_LINENUMBER].fore, vsPrint.styles[STYLE_LINENUMBER].back); } // Draw the line surface->FlushCachedState(); for (int iwl = 0; iwl < ll.lines; iwl++) { if (ypos + vsPrint.lineHeight <= pfr->rc.bottom) { if (visibleLine >= 0) { if (draw) { rcLine.top = ypos; rcLine.bottom = ypos + vsPrint.lineHeight; DrawLine(surface, vsPrint, lineDoc, visibleLine, xStart, rcLine, &ll, iwl); } ypos += vsPrint.lineHeight; } visibleLine++; if (iwl == ll.lines - 1) nPrintPos = pdoc->LineStart(lineDoc + 1); else nPrintPos += ll.LineStart(iwl + 1) - ll.LineStart(iwl); } } ++lineDoc; } // Clear cache so measurements are not used for screen posCache.Clear(); return nPrintPos; } int Editor::TextWidth(int style, const char *text) { RefreshStyleData(); AutoSurface surface(this); if (surface) { return surface->WidthText(vs.styles[style].font, text, istrlen(text)); } else { return 1; } } // Empty method is overridden on GTK+ to show / hide scrollbars void Editor::ReconfigureScrollBars() {} void Editor::SetScrollBars() { RefreshStyleData(); int nMax = MaxScrollPos(); int nPage = LinesOnScreen(); bool modified = ModifyScrollBars(nMax + nPage - 1, nPage); if (modified) { DwellEnd(true); } // TODO: ensure always showing as many lines as possible // May not be, if, for example, window made larger if (topLine > MaxScrollPos()) { SetTopLine(Platform::Clamp(topLine, 0, MaxScrollPos())); SetVerticalScrollPos(); Redraw(); } if (modified) { if (!AbandonPaint()) Redraw(); } //Platform::DebugPrintf("end max = %d page = %d\n", nMax, nPage); } void Editor::ChangeSize() { DropGraphics(false); SetScrollBars(); if (wrapState != eWrapNone) { PRectangle rcTextArea = GetClientRectangle(); rcTextArea.left = vs.textStart; rcTextArea.right -= vs.rightMarginWidth; if (wrapWidth != rcTextArea.Width()) { NeedWrapping(); Redraw(); } } } int Editor::InsertSpace(int position, unsigned int spaces) { if (spaces > 0) { std::string spaceText(spaces, ' '); pdoc->InsertString(position, spaceText.c_str(), spaces); position += spaces; } return position; } void Editor::AddChar(char ch) { char s[2]; s[0] = ch; s[1] = '\0'; AddCharUTF(s, 1); } void Editor::FilterSelections() { if (!additionalSelectionTyping && (sel.Count() > 1)) { SelectionRange rangeOnly = sel.RangeMain(); InvalidateSelection(rangeOnly, true); sel.SetSelection(rangeOnly); } } static bool cmpSelPtrs(const SelectionRange *a, const SelectionRange *b) { return *a < *b; } // AddCharUTF inserts an array of bytes which may or may not be in UTF-8. void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) { FilterSelections(); { UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty() || inOverstrike); std::vector<SelectionRange *> selPtrs; for (size_t r = 0; r < sel.Count(); r++) { selPtrs.push_back(&sel.Range(r)); } std::sort(selPtrs.begin(), selPtrs.end(), cmpSelPtrs); for (std::vector<SelectionRange *>::reverse_iterator rit = selPtrs.rbegin(); rit != selPtrs.rend(); ++rit) { SelectionRange *currentSel = *rit; if (!RangeContainsProtected(currentSel->Start().Position(), currentSel->End().Position())) { int positionInsert = currentSel->Start().Position(); if (!currentSel->Empty()) { if (currentSel->Length()) { pdoc->DeleteChars(positionInsert, currentSel->Length()); currentSel->ClearVirtualSpace(); } else { // Range is all virtual so collapse to start of virtual space currentSel->MinimizeVirtualSpace(); } } else if (inOverstrike) { if (positionInsert < pdoc->Length()) { if (!pdoc->IsPositionInLineEnd(positionInsert)) { pdoc->DelChar(positionInsert); currentSel->ClearVirtualSpace(); } } } positionInsert = InsertSpace(positionInsert, currentSel->caret.VirtualSpace()); if (pdoc->InsertString(positionInsert, s, len)) { currentSel->caret.SetPosition(positionInsert + len); currentSel->anchor.SetPosition(positionInsert + len); } currentSel->ClearVirtualSpace(); // If in wrap mode rewrap current line so EnsureCaretVisible has accurate information if (wrapState != eWrapNone) { AutoSurface surface(this); if (surface) { if (WrapOneLine(surface, pdoc->LineFromPosition(positionInsert))) { SetScrollBars(); SetVerticalScrollPos(); Redraw(); } } } } } } if (wrapState != eWrapNone) { SetScrollBars(); } ThinRectangularRange(); // If in wrap mode rewrap current line so EnsureCaretVisible has accurate information EnsureCaretVisible(); // Avoid blinking during rapid typing: ShowCaretAtCurrentPosition(); if ((caretSticky == SC_CARETSTICKY_OFF) || ((caretSticky == SC_CARETSTICKY_WHITESPACE) && !IsAllSpacesOrTabs(s, len))) { SetLastXChosen(); } if (treatAsDBCS) { NotifyChar((static_cast<unsigned char>(s[0]) << 8) | static_cast<unsigned char>(s[1])); } else { int byte = static_cast<unsigned char>(s[0]); if ((byte < 0xC0) || (1 == len)) { // Handles UTF-8 characters between 0x01 and 0x7F and single byte // characters when not in UTF-8 mode. // Also treats \0 and naked trail bytes 0x80 to 0xBF as valid // characters representing themselves. } else { // Unroll 1 to 3 byte UTF-8 sequences. See reference data at: // http://www.cl.cam.ac.uk/~mgk25/unicode.html // http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt if (byte < 0xE0) { int byte2 = static_cast<unsigned char>(s[1]); if ((byte2 & 0xC0) == 0x80) { // Two-byte-character lead-byte followed by a trail-byte. byte = (((byte & 0x1F) << 6) | (byte2 & 0x3F)); } // A two-byte-character lead-byte not followed by trail-byte // represents itself. } else if (byte < 0xF0) { int byte2 = static_cast<unsigned char>(s[1]); int byte3 = static_cast<unsigned char>(s[2]); if (((byte2 & 0xC0) == 0x80) && ((byte3 & 0xC0) == 0x80)) { // Three-byte-character lead byte followed by two trail bytes. byte = (((byte & 0x0F) << 12) | ((byte2 & 0x3F) << 6) | (byte3 & 0x3F)); } // A three-byte-character lead-byte not followed by two trail-bytes // represents itself. } } NotifyChar(byte); } if (recordingMacro) { NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast<sptr_t>(s)); } } void Editor::InsertPaste(SelectionPosition selStart, const char *text, int len) { if (multiPasteMode == SC_MULTIPASTE_ONCE) { selStart = SelectionPosition(InsertSpace(selStart.Position(), selStart.VirtualSpace())); if (pdoc->InsertString(selStart.Position(), text, len)) { SetEmptySelection(selStart.Position() + len); } } else { // SC_MULTIPASTE_EACH for (size_t r=0; r<sel.Count(); r++) { if (!RangeContainsProtected(sel.Range(r).Start().Position(), sel.Range(r).End().Position())) { int positionInsert = sel.Range(r).Start().Position(); if (!sel.Range(r).Empty()) { if (sel.Range(r).Length()) { pdoc->DeleteChars(positionInsert, sel.Range(r).Length()); sel.Range(r).ClearVirtualSpace(); } else { // Range is all virtual so collapse to start of virtual space sel.Range(r).MinimizeVirtualSpace(); } } positionInsert = InsertSpace(positionInsert, sel.Range(r).caret.VirtualSpace()); if (pdoc->InsertString(positionInsert, text, len)) { sel.Range(r).caret.SetPosition(positionInsert + len); sel.Range(r).anchor.SetPosition(positionInsert + len); } sel.Range(r).ClearVirtualSpace(); } } } } void Editor::ClearSelection(bool retainMultipleSelections) { if (!sel.IsRectangular() && !retainMultipleSelections) FilterSelections(); UndoGroup ug(pdoc); for (size_t r=0; r<sel.Count(); r++) { if (!sel.Range(r).Empty()) { if (!RangeContainsProtected(sel.Range(r).Start().Position(), sel.Range(r).End().Position())) { pdoc->DeleteChars(sel.Range(r).Start().Position(), sel.Range(r).Length()); sel.Range(r) = sel.Range(r).Start(); } } } ThinRectangularRange(); sel.RemoveDuplicates(); ClaimSelection(); } void Editor::ClearAll() { { UndoGroup ug(pdoc); if (0 != pdoc->Length()) { pdoc->DeleteChars(0, pdoc->Length()); } if (!pdoc->IsReadOnly()) { cs.Clear(); pdoc->AnnotationClearAll(); pdoc->MarginClearAll(); } } sel.Clear(); SetTopLine(0); SetVerticalScrollPos(); InvalidateStyleRedraw(); } void Editor::ClearDocumentStyle() { Decoration *deco = pdoc->decorations.root; while (deco) { // Save next in case deco deleted Decoration *decoNext = deco->next; if (deco->indicator < INDIC_CONTAINER) { pdoc->decorations.SetCurrentIndicator(deco->indicator); pdoc->DecorationFillRange(0, 0, pdoc->Length()); } deco = decoNext; } pdoc->StartStyling(0, '\377'); pdoc->SetStyleFor(pdoc->Length(), 0); cs.ShowAll(); pdoc->ClearLevels(); } void Editor::CopyAllowLine() { SelectionText selectedText; CopySelectionRange(&selectedText, true); CopyToClipboard(selectedText); } void Editor::Cut() { pdoc->CheckReadOnly(); if (!pdoc->IsReadOnly() && !SelectionContainsProtected()) { Copy(); ClearSelection(); } } void Editor::PasteRectangular(SelectionPosition pos, const char *ptr, int len) { if (pdoc->IsReadOnly() || SelectionContainsProtected()) { return; } sel.Clear(); sel.RangeMain() = SelectionRange(pos); int line = pdoc->LineFromPosition(sel.MainCaret()); UndoGroup ug(pdoc); sel.RangeMain().caret = SelectionPosition( InsertSpace(sel.RangeMain().caret.Position(), sel.RangeMain().caret.VirtualSpace())); int xInsert = XFromPosition(sel.RangeMain().caret); bool prevCr = false; while ((len > 0) && IsEOLChar(ptr[len-1])) len--; for (int i = 0; i < len; i++) { if (IsEOLChar(ptr[i])) { if ((ptr[i] == '\r') || (!prevCr)) line++; if (line >= pdoc->LinesTotal()) { if (pdoc->eolMode != SC_EOL_LF) pdoc->InsertChar(pdoc->Length(), '\r'); if (pdoc->eolMode != SC_EOL_CR) pdoc->InsertChar(pdoc->Length(), '\n'); } // Pad the end of lines with spaces if required sel.RangeMain().caret.SetPosition(PositionFromLineX(line, xInsert)); if ((XFromPosition(sel.MainCaret()) < xInsert) && (i + 1 < len)) { while (XFromPosition(sel.MainCaret()) < xInsert) { pdoc->InsertChar(sel.MainCaret(), ' '); sel.RangeMain().caret.Add(1); } } prevCr = ptr[i] == '\r'; } else { pdoc->InsertString(sel.MainCaret(), ptr + i, 1); sel.RangeMain().caret.Add(1); prevCr = false; } } SetEmptySelection(pos); } bool Editor::CanPaste() { return !pdoc->IsReadOnly() && !SelectionContainsProtected(); } void Editor::Clear() { // If multiple selections, don't delete EOLS if (sel.Empty()) { bool singleVirtual = false; if ((sel.Count() == 1) && !RangeContainsProtected(sel.MainCaret(), sel.MainCaret() + 1) && sel.RangeMain().Start().VirtualSpace()) { singleVirtual = true; } UndoGroup ug(pdoc, (sel.Count() > 1) || singleVirtual); for (size_t r=0; r<sel.Count(); r++) { if (!RangeContainsProtected(sel.Range(r).caret.Position(), sel.Range(r).caret.Position() + 1)) { if (sel.Range(r).Start().VirtualSpace()) { if (sel.Range(r).anchor < sel.Range(r).caret) sel.Range(r) = SelectionPosition(InsertSpace(sel.Range(r).anchor.Position(), sel.Range(r).anchor.VirtualSpace())); else sel.Range(r) = SelectionPosition(InsertSpace(sel.Range(r).caret.Position(), sel.Range(r).caret.VirtualSpace())); } if ((sel.Count() == 1) || !pdoc->IsPositionInLineEnd(sel.Range(r).caret.Position())) { pdoc->DelChar(sel.Range(r).caret.Position()); sel.Range(r).ClearVirtualSpace(); } // else multiple selection so don't eat line ends } else { sel.Range(r).ClearVirtualSpace(); } } } else { ClearSelection(); } sel.RemoveDuplicates(); } void Editor::SelectAll() { sel.Clear(); SetSelection(0, pdoc->Length()); Redraw(); } void Editor::Undo() { if (pdoc->CanUndo()) { InvalidateCaret(); int newPos = pdoc->Undo(); if (newPos >= 0) SetEmptySelection(newPos); EnsureCaretVisible(); } } void Editor::Redo() { if (pdoc->CanRedo()) { int newPos = pdoc->Redo(); if (newPos >= 0) SetEmptySelection(newPos); EnsureCaretVisible(); } } void Editor::DelChar() { if (!RangeContainsProtected(sel.MainCaret(), sel.MainCaret() + 1)) { pdoc->DelChar(sel.MainCaret()); } // Avoid blinking during rapid typing: ShowCaretAtCurrentPosition(); } void Editor::DelCharBack(bool allowLineStartDeletion) { if (!sel.IsRectangular()) FilterSelections(); if (sel.IsRectangular()) allowLineStartDeletion = false; UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty()); if (sel.Empty()) { for (size_t r=0; r<sel.Count(); r++) { if (!RangeContainsProtected(sel.Range(r).caret.Position() - 1, sel.Range(r).caret.Position())) { if (sel.Range(r).caret.VirtualSpace()) { sel.Range(r).caret.SetVirtualSpace(sel.Range(r).caret.VirtualSpace() - 1); sel.Range(r).anchor.SetVirtualSpace(sel.Range(r).caret.VirtualSpace()); } else { int lineCurrentPos = pdoc->LineFromPosition(sel.Range(r).caret.Position()); if (allowLineStartDeletion || (pdoc->LineStart(lineCurrentPos) != sel.Range(r).caret.Position())) { if (pdoc->GetColumn(sel.Range(r).caret.Position()) <= pdoc->GetLineIndentation(lineCurrentPos) && pdoc->GetColumn(sel.Range(r).caret.Position()) > 0 && pdoc->backspaceUnindents) { UndoGroup ugInner(pdoc, !ug.Needed()); int indentation = pdoc->GetLineIndentation(lineCurrentPos); int indentationStep = pdoc->IndentSize(); if (indentation % indentationStep == 0) { pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep); } else { pdoc->SetLineIndentation(lineCurrentPos, indentation - (indentation % indentationStep)); } // SetEmptySelection sel.Range(r) = SelectionRange(pdoc->GetLineIndentPosition(lineCurrentPos), pdoc->GetLineIndentPosition(lineCurrentPos)); } else { pdoc->DelCharBack(sel.Range(r).caret.Position()); } } } } else { sel.Range(r).ClearVirtualSpace(); } } ThinRectangularRange(); } else { ClearSelection(); } sel.RemoveDuplicates(); ContainerNeedsUpdate(SC_UPDATE_SELECTION); // Avoid blinking during rapid typing: ShowCaretAtCurrentPosition(); } void Editor::NotifyFocus(bool) {} void Editor::SetCtrlID(int identifier) { ctrlID = identifier; } void Editor::NotifyStyleToNeeded(int endStyleNeeded) { SCNotification scn = {0}; scn.nmhdr.code = SCN_STYLENEEDED; scn.position = endStyleNeeded; NotifyParent(scn); } void Editor::NotifyStyleNeeded(Document *, void *, int endStyleNeeded) { NotifyStyleToNeeded(endStyleNeeded); } void Editor::NotifyLexerChanged(Document *, void *) { } void Editor::NotifyErrorOccurred(Document *, void *, int status) { errorStatus = status; } void Editor::NotifyChar(int ch) { SCNotification scn = {0}; scn.nmhdr.code = SCN_CHARADDED; scn.ch = ch; NotifyParent(scn); } void Editor::NotifySavePoint(bool isSavePoint) { SCNotification scn = {0}; if (isSavePoint) { scn.nmhdr.code = SCN_SAVEPOINTREACHED; } else { scn.nmhdr.code = SCN_SAVEPOINTLEFT; } NotifyParent(scn); } void Editor::NotifyModifyAttempt() { SCNotification scn = {0}; scn.nmhdr.code = SCN_MODIFYATTEMPTRO; NotifyParent(scn); } void Editor::NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt) { SCNotification scn = {0}; scn.nmhdr.code = SCN_DOUBLECLICK; scn.line = LineFromLocation(pt); scn.position = PositionFromLocation(pt, true); scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | (alt ? SCI_ALT : 0); NotifyParent(scn); } void Editor::NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt) { SCNotification scn = {0}; scn.nmhdr.code = SCN_HOTSPOTDOUBLECLICK; scn.position = position; scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | (alt ? SCI_ALT : 0); NotifyParent(scn); } void Editor::NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt) { SCNotification scn = {0}; scn.nmhdr.code = SCN_HOTSPOTCLICK; scn.position = position; scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | (alt ? SCI_ALT : 0); NotifyParent(scn); } void Editor::NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool alt) { SCNotification scn = {0}; scn.nmhdr.code = SCN_HOTSPOTRELEASECLICK; scn.position = position; scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | (alt ? SCI_ALT : 0); NotifyParent(scn); } bool Editor::NotifyUpdateUI() { if (needUpdateUI) { SCNotification scn = {0}; scn.nmhdr.code = SCN_UPDATEUI; scn.updated = needUpdateUI; NotifyParent(scn); needUpdateUI = 0; return true; } return false; } void Editor::NotifyPainted() { SCNotification scn = {0}; scn.nmhdr.code = SCN_PAINTED; NotifyParent(scn); } void Editor::NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt) { int mask = pdoc->decorations.AllOnFor(position); if ((click && mask) || pdoc->decorations.clickNotified) { SCNotification scn = {0}; pdoc->decorations.clickNotified = click; scn.nmhdr.code = click ? SCN_INDICATORCLICK : SCN_INDICATORRELEASE; scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | (alt ? SCI_ALT : 0); scn.position = position; NotifyParent(scn); } } bool Editor::NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt) { int marginClicked = -1; int x = vs.textStart - vs.fixedColumnWidth; for (int margin = 0; margin <= SC_MAX_MARGIN; margin++) { if ((pt.x >= x) && (pt.x < x + vs.ms[margin].width)) marginClicked = margin; x += vs.ms[margin].width; } if ((marginClicked >= 0) && vs.ms[marginClicked].sensitive) { SCNotification scn = {0}; scn.nmhdr.code = SCN_MARGINCLICK; scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | (alt ? SCI_ALT : 0); scn.position = pdoc->LineStart(LineFromLocation(pt)); scn.margin = marginClicked; NotifyParent(scn); return true; } else { return false; } } void Editor::NotifyNeedShown(int pos, int len) { SCNotification scn = {0}; scn.nmhdr.code = SCN_NEEDSHOWN; scn.position = pos; scn.length = len; NotifyParent(scn); } void Editor::NotifyDwelling(Point pt, bool state) { SCNotification scn = {0}; scn.nmhdr.code = state ? SCN_DWELLSTART : SCN_DWELLEND; scn.position = PositionFromLocation(pt, true); scn.x = pt.x; scn.y = pt.y; NotifyParent(scn); } void Editor::NotifyZoom() { SCNotification scn = {0}; scn.nmhdr.code = SCN_ZOOM; NotifyParent(scn); } // Notifications from document void Editor::NotifyModifyAttempt(Document *, void *) { //Platform::DebugPrintf("** Modify Attempt\n"); NotifyModifyAttempt(); } void Editor::NotifySavePoint(Document *, void *, bool atSavePoint) { //Platform::DebugPrintf("** Save Point %s\n", atSavePoint ? "On" : "Off"); NotifySavePoint(atSavePoint); } void Editor::CheckModificationForWrap(DocModification mh) { if (mh.modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT)) { llc.Invalidate(LineLayout::llCheckTextAndStyle); int lineDoc = pdoc->LineFromPosition(mh.position); int lines = Platform::Maximum(0, mh.linesAdded); if (wrapState != eWrapNone) { NeedWrapping(lineDoc, lineDoc + lines + 1); } RefreshStyleData(); // Fix up annotation heights SetAnnotationHeights(lineDoc, lineDoc + lines + 2); } } // Move a position so it is still after the same character as before the insertion. static inline int MovePositionForInsertion(int position, int startInsertion, int length) { if (position > startInsertion) { return position + length; } return position; } // Move a position so it is still after the same character as before the deletion if that // character is still present else after the previous surviving character. static inline int MovePositionForDeletion(int position, int startDeletion, int length) { if (position > startDeletion) { int endDeletion = startDeletion + length; if (position > endDeletion) { return position - length; } else { return startDeletion; } } else { return position; } } void Editor::NotifyModified(Document *, DocModification mh, void *) { ContainerNeedsUpdate(SC_UPDATE_CONTENT); if (paintState == painting) { CheckForChangeOutsidePaint(Range(mh.position, mh.position + mh.length)); } if (mh.modificationType & SC_MOD_CHANGELINESTATE) { if (paintState == painting) { CheckForChangeOutsidePaint( Range(pdoc->LineStart(mh.line), pdoc->LineStart(mh.line + 1))); } else { // Could check that change is before last visible line. Redraw(); } } if (mh.modificationType & SC_MOD_LEXERSTATE) { if (paintState == painting) { CheckForChangeOutsidePaint( Range(mh.position, mh.position + mh.length)); } else { Redraw(); } } if (mh.modificationType & (SC_MOD_CHANGESTYLE | SC_MOD_CHANGEINDICATOR)) { if (mh.modificationType & SC_MOD_CHANGESTYLE) { pdoc->IncrementStyleClock(); } if (paintState == notPainting) { if (mh.position < pdoc->LineStart(topLine)) { // Styling performed before this view Redraw(); } else { InvalidateRange(mh.position, mh.position + mh.length); } } if (mh.modificationType & SC_MOD_CHANGESTYLE) { llc.Invalidate(LineLayout::llCheckTextAndStyle); } } else { // Move selection and brace highlights if (mh.modificationType & SC_MOD_INSERTTEXT) { sel.MovePositions(true, mh.position, mh.length); braces[0] = MovePositionForInsertion(braces[0], mh.position, mh.length); braces[1] = MovePositionForInsertion(braces[1], mh.position, mh.length); } else if (mh.modificationType & SC_MOD_DELETETEXT) { sel.MovePositions(false, mh.position, mh.length); braces[0] = MovePositionForDeletion(braces[0], mh.position, mh.length); braces[1] = MovePositionForDeletion(braces[1], mh.position, mh.length); } if ((mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) && cs.HiddenLines()) { // Some lines are hidden so may need shown. // TODO: check if the modified area is hidden. if (mh.modificationType & SC_MOD_BEFOREINSERT) { int lineOfPos = pdoc->LineFromPosition(mh.position); bool insertingNewLine = false; for (int i=0; i < mh.length; i++) { if ((mh.text[i] == '\n') || (mh.text[i] == '\r')) insertingNewLine = true; } if (insertingNewLine && (mh.position != pdoc->LineStart(lineOfPos))) NotifyNeedShown(mh.position, pdoc->LineStart(lineOfPos+1) - mh.position); else NotifyNeedShown(mh.position, 0); } else if (mh.modificationType & SC_MOD_BEFOREDELETE) { NotifyNeedShown(mh.position, mh.length); } } if (mh.linesAdded != 0) { // Update contraction state for inserted and removed lines // lineOfPos should be calculated in context of state before modification, shouldn't it int lineOfPos = pdoc->LineFromPosition(mh.position); if (mh.linesAdded > 0) { cs.InsertLines(lineOfPos, mh.linesAdded); } else { cs.DeleteLines(lineOfPos, -mh.linesAdded); } } if (mh.modificationType & SC_MOD_CHANGEANNOTATION) { int lineDoc = pdoc->LineFromPosition(mh.position); if (vs.annotationVisible) { cs.SetHeight(lineDoc, cs.GetHeight(lineDoc) + mh.annotationLinesAdded); Redraw(); } } CheckModificationForWrap(mh); if (mh.linesAdded != 0) { // Avoid scrolling of display if change before current display if (mh.position < posTopLine && !CanDeferToLastStep(mh)) { int newTop = Platform::Clamp(topLine + mh.linesAdded, 0, MaxScrollPos()); if (newTop != topLine) { SetTopLine(newTop); SetVerticalScrollPos(); } } if (paintState == notPainting && !CanDeferToLastStep(mh)) { QueueIdleWork(WorkNeeded::workStyle, pdoc->Length()); Redraw(); } } else { if (paintState == notPainting && mh.length && !CanEliminate(mh)) { QueueIdleWork(WorkNeeded::workStyle, mh.position + mh.length); InvalidateRange(mh.position, mh.position + mh.length); } } } if (mh.linesAdded != 0 && !CanDeferToLastStep(mh)) { SetScrollBars(); } if ((mh.modificationType & SC_MOD_CHANGEMARKER) || (mh.modificationType & SC_MOD_CHANGEMARGIN)) { if ((!willRedrawAll) && ((paintState == notPainting) || !PaintContainsMargin())) { if (mh.modificationType & SC_MOD_CHANGEFOLD) { // Fold changes can affect the drawing of following lines so redraw whole margin RedrawSelMargin(highlightDelimiter.isEnabled ? -1 : mh.line-1, true); } else { RedrawSelMargin(mh.line); } } } // NOW pay the piper WRT "deferred" visual updates if (IsLastStep(mh)) { SetScrollBars(); Redraw(); } // If client wants to see this modification if (mh.modificationType & modEventMask) { if ((mh.modificationType & (SC_MOD_CHANGESTYLE | SC_MOD_CHANGEINDICATOR)) == 0) { // Real modification made to text of document. NotifyChange(); // Send EN_CHANGE } SCNotification scn = {0}; scn.nmhdr.code = SCN_MODIFIED; scn.position = mh.position; scn.modificationType = mh.modificationType; scn.text = mh.text; scn.length = mh.length; scn.linesAdded = mh.linesAdded; scn.line = mh.line; scn.foldLevelNow = mh.foldLevelNow; scn.foldLevelPrev = mh.foldLevelPrev; scn.token = mh.token; scn.annotationLinesAdded = mh.annotationLinesAdded; NotifyParent(scn); } } void Editor::NotifyDeleted(Document *, void *) { /* Do nothing */ } void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { // Enumerates all macroable messages switch (iMessage) { case SCI_CUT: case SCI_COPY: case SCI_PASTE: case SCI_CLEAR: case SCI_REPLACESEL: case SCI_ADDTEXT: case SCI_INSERTTEXT: case SCI_APPENDTEXT: case SCI_CLEARALL: case SCI_SELECTALL: case SCI_GOTOLINE: case SCI_GOTOPOS: case SCI_SEARCHANCHOR: case SCI_SEARCHNEXT: case SCI_SEARCHPREV: case SCI_LINEDOWN: case SCI_LINEDOWNEXTEND: case SCI_PARADOWN: case SCI_PARADOWNEXTEND: case SCI_LINEUP: case SCI_LINEUPEXTEND: case SCI_PARAUP: case SCI_PARAUPEXTEND: case SCI_CHARLEFT: case SCI_CHARLEFTEXTEND: case SCI_CHARRIGHT: case SCI_CHARRIGHTEXTEND: case SCI_WORDLEFT: case SCI_WORDLEFTEXTEND: case SCI_WORDRIGHT: case SCI_WORDRIGHTEXTEND: case SCI_WORDPARTLEFT: case SCI_WORDPARTLEFTEXTEND: case SCI_WORDPARTRIGHT: case SCI_WORDPARTRIGHTEXTEND: case SCI_WORDLEFTEND: case SCI_WORDLEFTENDEXTEND: case SCI_WORDRIGHTEND: case SCI_WORDRIGHTENDEXTEND: case SCI_HOME: case SCI_HOMEEXTEND: case SCI_LINEEND: case SCI_LINEENDEXTEND: case SCI_HOMEWRAP: case SCI_HOMEWRAPEXTEND: case SCI_LINEENDWRAP: case SCI_LINEENDWRAPEXTEND: case SCI_DOCUMENTSTART: case SCI_DOCUMENTSTARTEXTEND: case SCI_DOCUMENTEND: case SCI_DOCUMENTENDEXTEND: case SCI_STUTTEREDPAGEUP: case SCI_STUTTEREDPAGEUPEXTEND: case SCI_STUTTEREDPAGEDOWN: case SCI_STUTTEREDPAGEDOWNEXTEND: case SCI_PAGEUP: case SCI_PAGEUPEXTEND: case SCI_PAGEDOWN: case SCI_PAGEDOWNEXTEND: case SCI_EDITTOGGLEOVERTYPE: case SCI_CANCEL: case SCI_DELETEBACK: case SCI_TAB: case SCI_BACKTAB: case SCI_FORMFEED: case SCI_VCHOME: case SCI_VCHOMEEXTEND: case SCI_VCHOMEWRAP: case SCI_VCHOMEWRAPEXTEND: case SCI_VCHOMEDISPLAY: case SCI_VCHOMEDISPLAYEXTEND: case SCI_DELWORDLEFT: case SCI_DELWORDRIGHT: case SCI_DELWORDRIGHTEND: case SCI_DELLINELEFT: case SCI_DELLINERIGHT: case SCI_LINECOPY: case SCI_LINECUT: case SCI_LINEDELETE: case SCI_LINETRANSPOSE: case SCI_LINEDUPLICATE: case SCI_LOWERCASE: case SCI_UPPERCASE: case SCI_LINESCROLLDOWN: case SCI_LINESCROLLUP: case SCI_DELETEBACKNOTLINE: case SCI_HOMEDISPLAY: case SCI_HOMEDISPLAYEXTEND: case SCI_LINEENDDISPLAY: case SCI_LINEENDDISPLAYEXTEND: case SCI_SETSELECTIONMODE: case SCI_LINEDOWNRECTEXTEND: case SCI_LINEUPRECTEXTEND: case SCI_CHARLEFTRECTEXTEND: case SCI_CHARRIGHTRECTEXTEND: case SCI_HOMERECTEXTEND: case SCI_VCHOMERECTEXTEND: case SCI_LINEENDRECTEXTEND: case SCI_PAGEUPRECTEXTEND: case SCI_PAGEDOWNRECTEXTEND: case SCI_SELECTIONDUPLICATE: case SCI_COPYALLOWLINE: case SCI_VERTICALCENTRECARET: case SCI_MOVESELECTEDLINESUP: case SCI_MOVESELECTEDLINESDOWN: case SCI_SCROLLTOSTART: case SCI_SCROLLTOEND: break; // Filter out all others like display changes. Also, newlines are redundant // with char insert messages. case SCI_NEWLINE: default: // printf("Filtered out %ld of macro recording\n", iMessage); return ; } // Send notification SCNotification scn = {0}; scn.nmhdr.code = SCN_MACRORECORD; scn.message = iMessage; scn.wParam = wParam; scn.lParam = lParam; NotifyParent(scn); } // Something has changed that the container should know about void Editor::ContainerNeedsUpdate(int flags) { needUpdateUI |= flags; } /** * Force scroll and keep position relative to top of window. * * If stuttered = true and not already at first/last row, move to first/last row of window. * If stuttered = true and already at first/last row, scroll as normal. */ void Editor::PageMove(int direction, Selection::selTypes selt, bool stuttered) { int topLineNew; SelectionPosition newPos; int currentLine = pdoc->LineFromPosition(sel.MainCaret()); int topStutterLine = topLine + caretYSlop; int bottomStutterLine = pdoc->LineFromPosition(PositionFromLocation( Point(lastXChosen - xOffset, direction * vs.lineHeight * LinesToScroll()))) - caretYSlop - 1; if (stuttered && (direction < 0 && currentLine > topStutterLine)) { topLineNew = topLine; newPos = SPositionFromLocation(Point(lastXChosen - xOffset, vs.lineHeight * caretYSlop), false, false, UserVirtualSpace()); } else if (stuttered && (direction > 0 && currentLine < bottomStutterLine)) { topLineNew = topLine; newPos = SPositionFromLocation(Point(lastXChosen - xOffset, vs.lineHeight * (LinesToScroll() - caretYSlop)), false, false, UserVirtualSpace()); } else { Point pt = LocationFromPosition(sel.MainCaret()); topLineNew = Platform::Clamp( topLine + direction * LinesToScroll(), 0, MaxScrollPos()); newPos = SPositionFromLocation( Point(lastXChosen - xOffset, pt.y + direction * (vs.lineHeight * LinesToScroll())), false, false, UserVirtualSpace()); } if (topLineNew != topLine) { SetTopLine(topLineNew); MovePositionTo(newPos, selt); Redraw(); SetVerticalScrollPos(); } else { MovePositionTo(newPos, selt); } } void Editor::ChangeCaseOfSelection(int caseMapping) { UndoGroup ug(pdoc); for (size_t r=0; r<sel.Count(); r++) { SelectionRange current = sel.Range(r); SelectionRange currentNoVS = current; currentNoVS.ClearVirtualSpace(); char *text = CopyRange(currentNoVS.Start().Position(), currentNoVS.End().Position()); size_t rangeBytes = currentNoVS.Length(); if (rangeBytes > 0) { std::string sText(text, rangeBytes); std::string sMapped = CaseMapString(sText, caseMapping); if (sMapped != sText) { size_t firstDifference = 0; while (sMapped[firstDifference] == sText[firstDifference]) firstDifference++; size_t lastDifference = sMapped.size() - 1; while (sMapped[lastDifference] == sText[lastDifference]) lastDifference--; size_t endSame = sMapped.size() - 1 - lastDifference; pdoc->DeleteChars( static_cast<int>(currentNoVS.Start().Position() + firstDifference), static_cast<int>(rangeBytes - firstDifference - endSame)); pdoc->InsertString( static_cast<int>(currentNoVS.Start().Position() + firstDifference), sMapped.c_str() + firstDifference, static_cast<int>(lastDifference - firstDifference + 1)); // Automatic movement changes selection so reset to exactly the same as it was. sel.Range(r) = current; } } delete []text; } } void Editor::LineTranspose() { int line = pdoc->LineFromPosition(sel.MainCaret()); if (line > 0) { UndoGroup ug(pdoc); int startPrev = pdoc->LineStart(line - 1); int endPrev = pdoc->LineEnd(line - 1); int start = pdoc->LineStart(line); int end = pdoc->LineEnd(line); char *line1 = CopyRange(startPrev, endPrev); int len1 = endPrev - startPrev; char *line2 = CopyRange(start, end); int len2 = end - start; pdoc->DeleteChars(start, len2); pdoc->DeleteChars(startPrev, len1); pdoc->InsertString(startPrev, line2, len2); pdoc->InsertString(start - len1 + len2, line1, len1); MovePositionTo(SelectionPosition(start - len1 + len2)); delete []line1; delete []line2; } } void Editor::Duplicate(bool forLine) { if (sel.Empty()) { forLine = true; } UndoGroup ug(pdoc); const char *eol = ""; int eolLen = 0; if (forLine) { eol = StringFromEOLMode(pdoc->eolMode); eolLen = istrlen(eol); } for (size_t r=0; r<sel.Count(); r++) { SelectionPosition start = sel.Range(r).Start(); SelectionPosition end = sel.Range(r).End(); if (forLine) { int line = pdoc->LineFromPosition(sel.Range(r).caret.Position()); start = SelectionPosition(pdoc->LineStart(line)); end = SelectionPosition(pdoc->LineEnd(line)); } char *text = CopyRange(start.Position(), end.Position()); if (forLine) pdoc->InsertString(end.Position(), eol, eolLen); pdoc->InsertString(end.Position() + eolLen, text, SelectionRange(end, start).Length()); delete []text; } if (sel.Count() && sel.IsRectangular()) { SelectionPosition last = sel.Last(); if (forLine) { int line = pdoc->LineFromPosition(last.Position()); last = SelectionPosition(last.Position() + pdoc->LineStart(line+1) - pdoc->LineStart(line)); } if (sel.Rectangular().anchor > sel.Rectangular().caret) sel.Rectangular().anchor = last; else sel.Rectangular().caret = last; SetRectangularRange(); } } void Editor::CancelModes() { sel.SetMoveExtends(false); } void Editor::NewLine() { // Remove non-main ranges InvalidateSelection(sel.RangeMain(), true); sel.SetSelection(sel.RangeMain()); // Clear main range and insert line end bool needGroupUndo = !sel.Empty(); if (needGroupUndo) pdoc->BeginUndoAction(); if (!sel.Empty()) ClearSelection(); const char *eol = "\n"; if (pdoc->eolMode == SC_EOL_CRLF) { eol = "\r\n"; } else if (pdoc->eolMode == SC_EOL_CR) { eol = "\r"; } // else SC_EOL_LF -> "\n" already set bool inserted = pdoc->InsertCString(sel.MainCaret(), eol); // Want to end undo group before NotifyChar as applications often modify text here if (needGroupUndo) pdoc->EndUndoAction(); if (inserted) { SetEmptySelection(sel.MainCaret() + istrlen(eol)); while (*eol) { NotifyChar(*eol); if (recordingMacro) { char txt[2]; txt[0] = *eol; txt[1] = '\0'; NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast<sptr_t>(txt)); } eol++; } } SetLastXChosen(); SetScrollBars(); EnsureCaretVisible(); // Avoid blinking during rapid typing: ShowCaretAtCurrentPosition(); } void Editor::CursorUpOrDown(int direction, Selection::selTypes selt) { SelectionPosition caretToUse = sel.Range(sel.Main()).caret; if (sel.IsRectangular()) { if (selt == Selection::noSel) { caretToUse = (direction > 0) ? sel.Limits().end : sel.Limits().start; } else { caretToUse = sel.Rectangular().caret; } } Point pt = LocationFromPosition(caretToUse); int skipLines = 0; if (vs.annotationVisible) { int lineDoc = pdoc->LineFromPosition(caretToUse.Position()); Point ptStartLine = LocationFromPosition(pdoc->LineStart(lineDoc)); int subLine = (pt.y - ptStartLine.y) / vs.lineHeight; if (direction < 0 && subLine == 0) { int lineDisplay = cs.DisplayFromDoc(lineDoc); if (lineDisplay > 0) { skipLines = pdoc->AnnotationLines(cs.DocFromDisplay(lineDisplay - 1)); } } else if (direction > 0 && subLine >= (cs.GetHeight(lineDoc) - 1 - pdoc->AnnotationLines(lineDoc))) { skipLines = pdoc->AnnotationLines(lineDoc); } } int newY = pt.y + (1 + skipLines) * direction * vs.lineHeight; SelectionPosition posNew = SPositionFromLocation( Point(lastXChosen - xOffset, newY), false, false, UserVirtualSpace()); if (direction < 0) { // Line wrapping may lead to a location on the same line, so // seek back if that is the case. Point ptNew = LocationFromPosition(posNew.Position()); while ((posNew.Position() > 0) && (pt.y == ptNew.y)) { posNew.Add(-1); posNew.SetVirtualSpace(0); ptNew = LocationFromPosition(posNew.Position()); } } else if (direction > 0 && posNew.Position() != pdoc->Length()) { // There is an equivalent case when moving down which skips // over a line. Point ptNew = LocationFromPosition(posNew.Position()); while ((posNew.Position() > caretToUse.Position()) && (ptNew.y > newY)) { posNew.Add(-1); posNew.SetVirtualSpace(0); ptNew = LocationFromPosition(posNew.Position()); } } MovePositionTo(MovePositionSoVisible(posNew, direction), selt); } void Editor::ParaUpOrDown(int direction, Selection::selTypes selt) { int lineDoc, savedPos = sel.MainCaret(); do { MovePositionTo(SelectionPosition(direction > 0 ? pdoc->ParaDown(sel.MainCaret()) : pdoc->ParaUp(sel.MainCaret())), selt); lineDoc = pdoc->LineFromPosition(sel.MainCaret()); if (direction > 0) { if (sel.MainCaret() >= pdoc->Length() && !cs.GetVisible(lineDoc)) { if (selt == Selection::noSel) { MovePositionTo(SelectionPosition(pdoc->LineEndPosition(savedPos))); } break; } } } while (!cs.GetVisible(lineDoc)); } int Editor::StartEndDisplayLine(int pos, bool start) { RefreshStyleData(); int line = pdoc->LineFromPosition(pos); AutoSurface surface(this); AutoLineLayout ll(llc, RetrieveLineLayout(line)); int posRet = INVALID_POSITION; if (surface && ll) { unsigned int posLineStart = pdoc->LineStart(line); LayoutLine(line, surface, vs, ll, wrapWidth); int posInLine = pos - posLineStart; if (posInLine <= ll->maxLineLength) { for (int subLine = 0; subLine < ll->lines; subLine++) { if ((posInLine >= ll->LineStart(subLine)) && (posInLine <= ll->LineStart(subLine + 1))) { if (start) { posRet = ll->LineStart(subLine) + posLineStart; } else { if (subLine == ll->lines - 1) posRet = ll->LineStart(subLine + 1) + posLineStart; else posRet = ll->LineStart(subLine + 1) + posLineStart - 1; } } } } } if (posRet == INVALID_POSITION) { return pos; } else { return posRet; } } int Editor::KeyCommand(unsigned int iMessage) { switch (iMessage) { case SCI_LINEDOWN: CursorUpOrDown(1); break; case SCI_LINEDOWNEXTEND: CursorUpOrDown(1, Selection::selStream); break; case SCI_LINEDOWNRECTEXTEND: CursorUpOrDown(1, Selection::selRectangle); break; case SCI_PARADOWN: ParaUpOrDown(1); break; case SCI_PARADOWNEXTEND: ParaUpOrDown(1, Selection::selStream); break; case SCI_LINESCROLLDOWN: ScrollTo(topLine + 1); MoveCaretInsideView(false); break; case SCI_LINEUP: CursorUpOrDown(-1); break; case SCI_LINEUPEXTEND: CursorUpOrDown(-1, Selection::selStream); break; case SCI_LINEUPRECTEXTEND: CursorUpOrDown(-1, Selection::selRectangle); break; case SCI_PARAUP: ParaUpOrDown(-1); break; case SCI_PARAUPEXTEND: ParaUpOrDown(-1, Selection::selStream); break; case SCI_LINESCROLLUP: ScrollTo(topLine - 1); MoveCaretInsideView(false); break; case SCI_CHARLEFT: if (SelectionEmpty() || sel.MoveExtends()) { if ((sel.Count() == 1) && pdoc->IsLineEndPosition(sel.MainCaret()) && sel.RangeMain().caret.VirtualSpace()) { SelectionPosition spCaret = sel.RangeMain().caret; spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1); MovePositionTo(spCaret); } else if (sel.MoveExtends() && sel.selType == Selection::selStream) { MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() - 1), -1)); } else { MovePositionTo(MovePositionSoVisible( SelectionPosition((sel.LimitsForRectangularElseMain().start).Position() - 1), -1)); } } else { MovePositionTo(sel.LimitsForRectangularElseMain().start); } SetLastXChosen(); break; case SCI_CHARLEFTEXTEND: if (pdoc->IsLineEndPosition(sel.MainCaret()) && sel.RangeMain().caret.VirtualSpace()) { SelectionPosition spCaret = sel.RangeMain().caret; spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1); MovePositionTo(spCaret, Selection::selStream); } else { MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() - 1), -1), Selection::selStream); } SetLastXChosen(); break; case SCI_CHARLEFTRECTEXTEND: if (pdoc->IsLineEndPosition(sel.MainCaret()) && sel.RangeMain().caret.VirtualSpace()) { SelectionPosition spCaret = sel.RangeMain().caret; spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1); MovePositionTo(spCaret, Selection::selRectangle); } else { MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() - 1), -1), Selection::selRectangle); } SetLastXChosen(); break; case SCI_CHARRIGHT: if (SelectionEmpty() || sel.MoveExtends()) { if ((virtualSpaceOptions & SCVS_USERACCESSIBLE) && pdoc->IsLineEndPosition(sel.MainCaret())) { SelectionPosition spCaret = sel.RangeMain().caret; spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1); MovePositionTo(spCaret); } else if (sel.MoveExtends() && sel.selType == Selection::selStream) { MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() + 1), 1)); } else { MovePositionTo(MovePositionSoVisible( SelectionPosition((sel.LimitsForRectangularElseMain().end).Position() + 1), 1)); } } else { MovePositionTo(sel.LimitsForRectangularElseMain().end); } SetLastXChosen(); break; case SCI_CHARRIGHTEXTEND: if ((virtualSpaceOptions & SCVS_USERACCESSIBLE) && pdoc->IsLineEndPosition(sel.MainCaret())) { SelectionPosition spCaret = sel.RangeMain().caret; spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1); MovePositionTo(spCaret, Selection::selStream); } else { MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() + 1), 1), Selection::selStream); } SetLastXChosen(); break; case SCI_CHARRIGHTRECTEXTEND: if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) && pdoc->IsLineEndPosition(sel.MainCaret())) { SelectionPosition spCaret = sel.RangeMain().caret; spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1); MovePositionTo(spCaret, Selection::selRectangle); } else { MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() + 1), 1), Selection::selRectangle); } SetLastXChosen(); break; case SCI_WORDLEFT: MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(sel.MainCaret(), -1), -1)); SetLastXChosen(); break; case SCI_WORDLEFTEXTEND: MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(sel.MainCaret(), -1), -1), Selection::selStream); SetLastXChosen(); break; case SCI_WORDRIGHT: MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(sel.MainCaret(), 1), 1)); SetLastXChosen(); break; case SCI_WORDRIGHTEXTEND: MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(sel.MainCaret(), 1), 1), Selection::selStream); SetLastXChosen(); break; case SCI_WORDLEFTEND: MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(sel.MainCaret(), -1), -1)); SetLastXChosen(); break; case SCI_WORDLEFTENDEXTEND: MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(sel.MainCaret(), -1), -1), Selection::selStream); SetLastXChosen(); break; case SCI_WORDRIGHTEND: MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(sel.MainCaret(), 1), 1)); SetLastXChosen(); break; case SCI_WORDRIGHTENDEXTEND: MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(sel.MainCaret(), 1), 1), Selection::selStream); SetLastXChosen(); break; case SCI_HOME: MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret()))); SetLastXChosen(); break; case SCI_HOMEEXTEND: MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())), Selection::selStream); SetLastXChosen(); break; case SCI_HOMERECTEXTEND: MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())), Selection::selRectangle); SetLastXChosen(); break; case SCI_LINEEND: MovePositionTo(pdoc->LineEndPosition(sel.MainCaret())); SetLastXChosen(); break; case SCI_LINEENDEXTEND: MovePositionTo(pdoc->LineEndPosition(sel.MainCaret()), Selection::selStream); SetLastXChosen(); break; case SCI_LINEENDRECTEXTEND: MovePositionTo(pdoc->LineEndPosition(sel.MainCaret()), Selection::selRectangle); SetLastXChosen(); break; case SCI_HOMEWRAP: { SelectionPosition homePos = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1); if (sel.RangeMain().caret <= homePos) homePos = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret()))); MovePositionTo(homePos); SetLastXChosen(); } break; case SCI_HOMEWRAPEXTEND: { SelectionPosition homePos = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1); if (sel.RangeMain().caret <= homePos) homePos = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret()))); MovePositionTo(homePos, Selection::selStream); SetLastXChosen(); } break; case SCI_LINEENDWRAP: { SelectionPosition endPos = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), false), 1); SelectionPosition realEndPos = SelectionPosition(pdoc->LineEndPosition(sel.MainCaret())); if (endPos > realEndPos // if moved past visible EOLs || sel.RangeMain().caret >= endPos) // if at end of display line already endPos = realEndPos; MovePositionTo(endPos); SetLastXChosen(); } break; case SCI_LINEENDWRAPEXTEND: { SelectionPosition endPos = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), false), 1); SelectionPosition realEndPos = SelectionPosition(pdoc->LineEndPosition(sel.MainCaret())); if (endPos > realEndPos // if moved past visible EOLs || sel.RangeMain().caret >= endPos) // if at end of display line already endPos = realEndPos; MovePositionTo(endPos, Selection::selStream); SetLastXChosen(); } break; case SCI_DOCUMENTSTART: MovePositionTo(0); SetLastXChosen(); break; case SCI_DOCUMENTSTARTEXTEND: MovePositionTo(0, Selection::selStream); SetLastXChosen(); break; case SCI_DOCUMENTEND: MovePositionTo(pdoc->Length()); SetLastXChosen(); break; case SCI_DOCUMENTENDEXTEND: MovePositionTo(pdoc->Length(), Selection::selStream); SetLastXChosen(); break; case SCI_STUTTEREDPAGEUP: PageMove(-1, Selection::noSel, true); break; case SCI_STUTTEREDPAGEUPEXTEND: PageMove(-1, Selection::selStream, true); break; case SCI_STUTTEREDPAGEDOWN: PageMove(1, Selection::noSel, true); break; case SCI_STUTTEREDPAGEDOWNEXTEND: PageMove(1, Selection::selStream, true); break; case SCI_PAGEUP: PageMove(-1); break; case SCI_PAGEUPEXTEND: PageMove(-1, Selection::selStream); break; case SCI_PAGEUPRECTEXTEND: PageMove(-1, Selection::selRectangle); break; case SCI_PAGEDOWN: PageMove(1); break; case SCI_PAGEDOWNEXTEND: PageMove(1, Selection::selStream); break; case SCI_PAGEDOWNRECTEXTEND: PageMove(1, Selection::selRectangle); break; case SCI_EDITTOGGLEOVERTYPE: inOverstrike = !inOverstrike; DropCaret(); ShowCaretAtCurrentPosition(); ContainerNeedsUpdate(SC_UPDATE_CONTENT); NotifyUpdateUI(); break; case SCI_CANCEL: // Cancel any modes - handled in subclass // Also unselect text CancelModes(); break; case SCI_DELETEBACK: DelCharBack(true); if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) { SetLastXChosen(); } EnsureCaretVisible(); break; case SCI_DELETEBACKNOTLINE: DelCharBack(false); if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) { SetLastXChosen(); } EnsureCaretVisible(); break; case SCI_TAB: Indent(true); if (caretSticky == SC_CARETSTICKY_OFF) { SetLastXChosen(); } EnsureCaretVisible(); ShowCaretAtCurrentPosition(); // Avoid blinking break; case SCI_BACKTAB: Indent(false); if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) { SetLastXChosen(); } EnsureCaretVisible(); ShowCaretAtCurrentPosition(); // Avoid blinking break; case SCI_NEWLINE: NewLine(); break; case SCI_FORMFEED: AddChar('\f'); break; case SCI_VCHOME: MovePositionTo(pdoc->VCHomePosition(sel.MainCaret())); SetLastXChosen(); break; case SCI_VCHOMEEXTEND: MovePositionTo(pdoc->VCHomePosition(sel.MainCaret()), Selection::selStream); SetLastXChosen(); break; case SCI_VCHOMERECTEXTEND: MovePositionTo(pdoc->VCHomePosition(sel.MainCaret()), Selection::selRectangle); SetLastXChosen(); break; case SCI_VCHOMEWRAP: { SelectionPosition homePos = SelectionPosition(pdoc->VCHomePosition(sel.MainCaret())); SelectionPosition viewLineStart = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1); if ((viewLineStart < sel.RangeMain().caret) && (viewLineStart > homePos)) homePos = viewLineStart; MovePositionTo(homePos); SetLastXChosen(); } break; case SCI_VCHOMEWRAPEXTEND: { SelectionPosition homePos = SelectionPosition(pdoc->VCHomePosition(sel.MainCaret())); SelectionPosition viewLineStart = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1); if ((viewLineStart < sel.RangeMain().caret) && (viewLineStart > homePos)) homePos = viewLineStart; MovePositionTo(homePos, Selection::selStream); SetLastXChosen(); } break; case SCI_ZOOMIN: if (vs.zoomLevel < 20) { vs.zoomLevel++; InvalidateStyleRedraw(); NotifyZoom(); } break; case SCI_ZOOMOUT: if (vs.zoomLevel > -10) { vs.zoomLevel--; InvalidateStyleRedraw(); NotifyZoom(); } break; case SCI_DELWORDLEFT: { int startWord = pdoc->NextWordStart(sel.MainCaret(), -1); pdoc->DeleteChars(startWord, sel.MainCaret() - startWord); sel.RangeMain().ClearVirtualSpace(); SetLastXChosen(); } break; case SCI_DELWORDRIGHT: { UndoGroup ug(pdoc); sel.RangeMain().caret = SelectionPosition( InsertSpace(sel.RangeMain().caret.Position(), sel.RangeMain().caret.VirtualSpace())); sel.RangeMain().anchor = sel.RangeMain().caret; int endWord = pdoc->NextWordStart(sel.MainCaret(), 1); pdoc->DeleteChars(sel.MainCaret(), endWord - sel.MainCaret()); } break; case SCI_DELWORDRIGHTEND: { UndoGroup ug(pdoc); sel.RangeMain().caret = SelectionPosition( InsertSpace(sel.RangeMain().caret.Position(), sel.RangeMain().caret.VirtualSpace())); int endWord = pdoc->NextWordEnd(sel.MainCaret(), 1); pdoc->DeleteChars(sel.MainCaret(), endWord - sel.MainCaret()); } break; case SCI_DELLINELEFT: { int line = pdoc->LineFromPosition(sel.MainCaret()); int start = pdoc->LineStart(line); pdoc->DeleteChars(start, sel.MainCaret() - start); sel.RangeMain().ClearVirtualSpace(); SetLastXChosen(); } break; case SCI_DELLINERIGHT: { int line = pdoc->LineFromPosition(sel.MainCaret()); int end = pdoc->LineEnd(line); pdoc->DeleteChars(sel.MainCaret(), end - sel.MainCaret()); } break; case SCI_LINECOPY: { int lineStart = pdoc->LineFromPosition(SelectionStart().Position()); int lineEnd = pdoc->LineFromPosition(SelectionEnd().Position()); CopyRangeToClipboard(pdoc->LineStart(lineStart), pdoc->LineStart(lineEnd + 1)); } break; case SCI_LINECUT: { int lineStart = pdoc->LineFromPosition(SelectionStart().Position()); int lineEnd = pdoc->LineFromPosition(SelectionEnd().Position()); int start = pdoc->LineStart(lineStart); int end = pdoc->LineStart(lineEnd + 1); SetSelection(start, end); Cut(); SetLastXChosen(); } break; case SCI_LINEDELETE: { int line = pdoc->LineFromPosition(sel.MainCaret()); int start = pdoc->LineStart(line); int end = pdoc->LineStart(line + 1); pdoc->DeleteChars(start, end - start); } break; case SCI_LINETRANSPOSE: LineTranspose(); break; case SCI_LINEDUPLICATE: Duplicate(true); break; case SCI_SELECTIONDUPLICATE: Duplicate(false); break; case SCI_LOWERCASE: ChangeCaseOfSelection(cmLower); break; case SCI_UPPERCASE: ChangeCaseOfSelection(cmUpper); break; case SCI_WORDPARTLEFT: MovePositionTo(MovePositionSoVisible(pdoc->WordPartLeft(sel.MainCaret()), -1)); SetLastXChosen(); break; case SCI_WORDPARTLEFTEXTEND: MovePositionTo(MovePositionSoVisible(pdoc->WordPartLeft(sel.MainCaret()), -1), Selection::selStream); SetLastXChosen(); break; case SCI_WORDPARTRIGHT: MovePositionTo(MovePositionSoVisible(pdoc->WordPartRight(sel.MainCaret()), 1)); SetLastXChosen(); break; case SCI_WORDPARTRIGHTEXTEND: MovePositionTo(MovePositionSoVisible(pdoc->WordPartRight(sel.MainCaret()), 1), Selection::selStream); SetLastXChosen(); break; case SCI_HOMEDISPLAY: MovePositionTo(MovePositionSoVisible( StartEndDisplayLine(sel.MainCaret(), true), -1)); SetLastXChosen(); break; case SCI_VCHOMEDISPLAY: { SelectionPosition homePos = SelectionPosition(pdoc->VCHomePosition(sel.MainCaret())); SelectionPosition viewLineStart = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1); if (viewLineStart > homePos) homePos = viewLineStart; MovePositionTo(homePos); SetLastXChosen(); } break; case SCI_HOMEDISPLAYEXTEND: MovePositionTo(MovePositionSoVisible( StartEndDisplayLine(sel.MainCaret(), true), -1), Selection::selStream); SetLastXChosen(); break; case SCI_VCHOMEDISPLAYEXTEND: { SelectionPosition homePos = SelectionPosition(pdoc->VCHomePosition(sel.MainCaret())); SelectionPosition viewLineStart = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1); if (viewLineStart > homePos) homePos = viewLineStart; MovePositionTo(homePos, Selection::selStream); SetLastXChosen(); } break; case SCI_LINEENDDISPLAY: MovePositionTo(MovePositionSoVisible( StartEndDisplayLine(sel.MainCaret(), false), 1)); SetLastXChosen(); break; case SCI_LINEENDDISPLAYEXTEND: MovePositionTo(MovePositionSoVisible( StartEndDisplayLine(sel.MainCaret(), false), 1), Selection::selStream); SetLastXChosen(); break; case SCI_SCROLLTOSTART: ScrollTo(0); break; case SCI_SCROLLTOEND: ScrollTo(MaxScrollPos()); break; } return 0; } int Editor::KeyDefault(int, int) { return 0; } int Editor::KeyDownWithModifiers(int key, int modifiers, bool *consumed) { DwellEnd(false); int msg = kmap.Find(key, modifiers); if (msg) { if (consumed) *consumed = true; return WndProc(msg, 0, 0); } else { if (consumed) *consumed = false; return KeyDefault(key, modifiers); } } int Editor::KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed) { int modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | (alt ? SCI_ALT : 0); return KeyDownWithModifiers(key, modifiers, consumed); } void Editor::Indent(bool forwards) { for (size_t r=0; r<sel.Count(); r++) { int lineOfAnchor = pdoc->LineFromPosition(sel.Range(r).anchor.Position()); int caretPosition = sel.Range(r).caret.Position(); int lineCurrentPos = pdoc->LineFromPosition(caretPosition); if (lineOfAnchor == lineCurrentPos) { if (forwards) { UndoGroup ug(pdoc); pdoc->DeleteChars(sel.Range(r).Start().Position(), sel.Range(r).Length()); caretPosition = sel.Range(r).caret.Position(); if (pdoc->GetColumn(caretPosition) <= pdoc->GetColumn(pdoc->GetLineIndentPosition(lineCurrentPos)) && pdoc->tabIndents) { int indentation = pdoc->GetLineIndentation(lineCurrentPos); int indentationStep = pdoc->IndentSize(); pdoc->SetLineIndentation(lineCurrentPos, indentation + indentationStep - indentation % indentationStep); sel.Range(r) = SelectionRange(pdoc->GetLineIndentPosition(lineCurrentPos)); } else { if (pdoc->useTabs) { pdoc->InsertChar(caretPosition, '\t'); sel.Range(r) = SelectionRange(caretPosition+1); } else { int numSpaces = (pdoc->tabInChars) - (pdoc->GetColumn(caretPosition) % (pdoc->tabInChars)); if (numSpaces < 1) numSpaces = pdoc->tabInChars; for (int i = 0; i < numSpaces; i++) { pdoc->InsertChar(caretPosition + i, ' '); } sel.Range(r) = SelectionRange(caretPosition+numSpaces); } } } else { if (pdoc->GetColumn(caretPosition) <= pdoc->GetLineIndentation(lineCurrentPos) && pdoc->tabIndents) { UndoGroup ug(pdoc); int indentation = pdoc->GetLineIndentation(lineCurrentPos); int indentationStep = pdoc->IndentSize(); pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep); sel.Range(r) = SelectionRange(pdoc->GetLineIndentPosition(lineCurrentPos)); } else { int newColumn = ((pdoc->GetColumn(caretPosition) - 1) / pdoc->tabInChars) * pdoc->tabInChars; if (newColumn < 0) newColumn = 0; int newPos = caretPosition; while (pdoc->GetColumn(newPos) > newColumn) newPos--; sel.Range(r) = SelectionRange(newPos); } } } else { // Multiline int anchorPosOnLine = sel.Range(r).anchor.Position() - pdoc->LineStart(lineOfAnchor); int currentPosPosOnLine = caretPosition - pdoc->LineStart(lineCurrentPos); // Multiple lines selected so indent / dedent int lineTopSel = Platform::Minimum(lineOfAnchor, lineCurrentPos); int lineBottomSel = Platform::Maximum(lineOfAnchor, lineCurrentPos); if (pdoc->LineStart(lineBottomSel) == sel.Range(r).anchor.Position() || pdoc->LineStart(lineBottomSel) == caretPosition) lineBottomSel--; // If not selecting any characters on a line, do not indent { UndoGroup ug(pdoc); pdoc->Indent(forwards, lineBottomSel, lineTopSel); } if (lineOfAnchor < lineCurrentPos) { if (currentPosPosOnLine == 0) sel.Range(r) = SelectionRange(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor)); else sel.Range(r) = SelectionRange(pdoc->LineStart(lineCurrentPos + 1), pdoc->LineStart(lineOfAnchor)); } else { if (anchorPosOnLine == 0) sel.Range(r) = SelectionRange(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor)); else sel.Range(r) = SelectionRange(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor + 1)); } } } } class CaseFolderASCII : public CaseFolderTable { public: CaseFolderASCII() { StandardASCII(); } ~CaseFolderASCII() { } }; CaseFolder *Editor::CaseFolderForEncoding() { // Simple default that only maps ASCII upper case to lower case. return new CaseFolderASCII(); } /** * Search of a text in the document, in the given range. * @return The position of the found text, -1 if not found. */ long Editor::FindText( uptr_t wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD, ///< @c SCFIND_WORDSTART, @c SCFIND_REGEXP or @c SCFIND_POSIX. sptr_t lParam) { ///< @c TextToFind structure: The text to search for in the given range. Sci_TextToFind *ft = reinterpret_cast<Sci_TextToFind *>(lParam); int lengthFound = istrlen(ft->lpstrText); if (!pdoc->HasCaseFolder()) pdoc->SetCaseFolder(CaseFolderForEncoding()); int pos = pdoc->FindText(ft->chrg.cpMin, ft->chrg.cpMax, ft->lpstrText, (wParam & SCFIND_MATCHCASE) != 0, (wParam & SCFIND_WHOLEWORD) != 0, (wParam & SCFIND_WORDSTART) != 0, (wParam & SCFIND_REGEXP) != 0, wParam, &lengthFound); if (pos != -1) { ft->chrgText.cpMin = pos; ft->chrgText.cpMax = pos + lengthFound; } return pos; } /** * Relocatable search support : Searches relative to current selection * point and sets the selection to the found text range with * each search. */ /** * Anchor following searches at current selection start: This allows * multiple incremental interactive searches to be macro recorded * while still setting the selection to found text so the find/select * operation is self-contained. */ void Editor::SearchAnchor() { searchAnchor = SelectionStart().Position(); } /** * Find text from current search anchor: Must call @c SearchAnchor first. * Used for next text and previous text requests. * @return The position of the found text, -1 if not found. */ long Editor::SearchText( unsigned int iMessage, ///< Accepts both @c SCI_SEARCHNEXT and @c SCI_SEARCHPREV. uptr_t wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD, ///< @c SCFIND_WORDSTART, @c SCFIND_REGEXP or @c SCFIND_POSIX. sptr_t lParam) { ///< The text to search for. const char *txt = reinterpret_cast<char *>(lParam); int pos; int lengthFound = istrlen(txt); if (!pdoc->HasCaseFolder()) pdoc->SetCaseFolder(CaseFolderForEncoding()); if (iMessage == SCI_SEARCHNEXT) { pos = pdoc->FindText(searchAnchor, pdoc->Length(), txt, (wParam & SCFIND_MATCHCASE) != 0, (wParam & SCFIND_WHOLEWORD) != 0, (wParam & SCFIND_WORDSTART) != 0, (wParam & SCFIND_REGEXP) != 0, wParam, &lengthFound); } else { pos = pdoc->FindText(searchAnchor, 0, txt, (wParam & SCFIND_MATCHCASE) != 0, (wParam & SCFIND_WHOLEWORD) != 0, (wParam & SCFIND_WORDSTART) != 0, (wParam & SCFIND_REGEXP) != 0, wParam, &lengthFound); } if (pos != -1) { SetSelection(pos, pos + lengthFound); } return pos; } std::string Editor::CaseMapString(const std::string &s, int caseMapping) { std::string ret(s); for (size_t i=0; i<ret.size(); i++) { switch (caseMapping) { case cmUpper: if (ret[i] >= 'a' && ret[i] <= 'z') ret[i] = static_cast<char>(ret[i] - 'a' + 'A'); break; case cmLower: if (ret[i] >= 'A' && ret[i] <= 'Z') ret[i] = static_cast<char>(ret[i] - 'A' + 'a'); break; } } return ret; } /** * Search for text in the target range of the document. * @return The position of the found text, -1 if not found. */ long Editor::SearchInTarget(const char *text, int length) { int lengthFound = length; if (!pdoc->HasCaseFolder()) pdoc->SetCaseFolder(CaseFolderForEncoding()); int pos = pdoc->FindText(targetStart, targetEnd, text, (searchFlags & SCFIND_MATCHCASE) != 0, (searchFlags & SCFIND_WHOLEWORD) != 0, (searchFlags & SCFIND_WORDSTART) != 0, (searchFlags & SCFIND_REGEXP) != 0, searchFlags, &lengthFound); if (pos != -1) { targetStart = pos; targetEnd = pos + lengthFound; } return pos; } void Editor::GoToLine(int lineNo) { if (lineNo > pdoc->LinesTotal()) lineNo = pdoc->LinesTotal(); if (lineNo < 0) lineNo = 0; SetEmptySelection(pdoc->LineStart(lineNo)); ShowCaretAtCurrentPosition(); EnsureCaretVisible(); } static bool Close(Point pt1, Point pt2) { if (abs(pt1.x - pt2.x) > 3) return false; if (abs(pt1.y - pt2.y) > 3) return false; return true; } char *Editor::CopyRange(int start, int end) { char *text = 0; if (start < end) { int len = end - start; text = new char[len + 1]; for (int i = 0; i < len; i++) { text[i] = pdoc->CharAt(start + i); } text[len] = '\0'; } return text; } std::string Editor::RangeText(int start, int end) const { if (start < end) { int len = end - start; std::string ret(len, '\0'); for (int i = 0; i < len; i++) { ret[i] = pdoc->CharAt(start + i); } return ret; } return std::string(); } void Editor::CopySelectionRange(SelectionText *ss, bool allowLineCopy) { if (sel.Empty()) { if (allowLineCopy) { int currentLine = pdoc->LineFromPosition(sel.MainCaret()); int start = pdoc->LineStart(currentLine); int end = pdoc->LineEnd(currentLine); char *text = CopyRange(start, end); size_t textLen = text ? strlen(text) : 0; // include room for \r\n\0 textLen += 3; char *textWithEndl = new char[textLen]; textWithEndl[0] = '\0'; if (text) strcat(textWithEndl, text); if (pdoc->eolMode != SC_EOL_LF) strcat(textWithEndl, "\r"); if (pdoc->eolMode != SC_EOL_CR) strcat(textWithEndl, "\n"); ss->Set(textWithEndl, static_cast<int>(strlen(textWithEndl) + 1), pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false, true); delete []text; } } else { int delimiterLength = 0; if (sel.selType == Selection::selRectangle) { if (pdoc->eolMode == SC_EOL_CRLF) { delimiterLength = 2; } else { delimiterLength = 1; } } size_t size = sel.Length() + delimiterLength * sel.Count(); char *text = new char[size + 1]; int j = 0; std::vector<SelectionRange> rangesInOrder = sel.RangesCopy(); if (sel.selType == Selection::selRectangle) std::sort(rangesInOrder.begin(), rangesInOrder.end()); for (size_t r=0; r<rangesInOrder.size(); r++) { SelectionRange current = rangesInOrder[r]; for (int i = current.Start().Position(); i < current.End().Position(); i++) { text[j++] = pdoc->CharAt(i); } if (sel.selType == Selection::selRectangle) { if (pdoc->eolMode != SC_EOL_LF) { text[j++] = '\r'; } if (pdoc->eolMode != SC_EOL_CR) { text[j++] = '\n'; } } } text[size] = '\0'; ss->Set(text, static_cast<int>(size + 1), pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, sel.IsRectangular(), sel.selType == Selection::selLines); } } void Editor::CopyRangeToClipboard(int start, int end) { start = pdoc->ClampPositionIntoDocument(start); end = pdoc->ClampPositionIntoDocument(end); SelectionText selectedText; selectedText.Set(CopyRange(start, end), end - start + 1, pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false, false); CopyToClipboard(selectedText); } void Editor::CopyText(int length, const char *text) { SelectionText selectedText; selectedText.Copy(text, length + 1, pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false, false); CopyToClipboard(selectedText); } void Editor::SetDragPosition(SelectionPosition newPos) { if (newPos.Position() >= 0) { newPos = MovePositionOutsideChar(newPos, 1); posDrop = newPos; } if (!(posDrag == newPos)) { caret.on = true; SetTicking(true); InvalidateCaret(); posDrag = newPos; InvalidateCaret(); } } void Editor::DisplayCursor(Window::Cursor c) { if (cursorMode == SC_CURSORNORMAL) wMain.SetCursor(c); else wMain.SetCursor(static_cast<Window::Cursor>(cursorMode)); } bool Editor::DragThreshold(Point ptStart, Point ptNow) { int xMove = ptStart.x - ptNow.x; int yMove = ptStart.y - ptNow.y; int distanceSquared = xMove * xMove + yMove * yMove; return distanceSquared > 16; } void Editor::StartDrag() { // Always handled by subclasses //SetMouseCapture(true); //DisplayCursor(Window::cursorArrow); } void Editor::DropAt(SelectionPosition position, const char *value, bool moving, bool rectangular) { //Platform::DebugPrintf("DropAt %d %d\n", inDragDrop, position); if (inDragDrop == ddDragging) dropWentOutside = false; bool positionWasInSelection = PositionInSelection(position.Position()); bool positionOnEdgeOfSelection = (position == SelectionStart()) || (position == SelectionEnd()); if ((inDragDrop != ddDragging) || !(positionWasInSelection) || (positionOnEdgeOfSelection && !moving)) { SelectionPosition selStart = SelectionStart(); SelectionPosition selEnd = SelectionEnd(); UndoGroup ug(pdoc); SelectionPosition positionAfterDeletion = position; if ((inDragDrop == ddDragging) && moving) { // Remove dragged out text if (rectangular || sel.selType == Selection::selLines) { for (size_t r=0; r<sel.Count(); r++) { if (position >= sel.Range(r).Start()) { if (position > sel.Range(r).End()) { positionAfterDeletion.Add(-sel.Range(r).Length()); } else { positionAfterDeletion.Add(-SelectionRange(position, sel.Range(r).Start()).Length()); } } } } else { if (position > selStart) { positionAfterDeletion.Add(-SelectionRange(selEnd, selStart).Length()); } } ClearSelection(); } position = positionAfterDeletion; if (rectangular) { PasteRectangular(position, value, istrlen(value)); // Should try to select new rectangle but it may not be a rectangle now so just select the drop position SetEmptySelection(position); } else { position = MovePositionOutsideChar(position, sel.MainCaret() - position.Position()); position = SelectionPosition(InsertSpace(position.Position(), position.VirtualSpace())); if (pdoc->InsertCString(position.Position(), value)) { SelectionPosition posAfterInsertion = position; posAfterInsertion.Add(istrlen(value)); SetSelection(posAfterInsertion, position); } } } else if (inDragDrop == ddDragging) { SetEmptySelection(position); } } /** * @return true if given position is inside the selection, */ bool Editor::PositionInSelection(int pos) { pos = MovePositionOutsideChar(pos, sel.MainCaret() - pos); for (size_t r=0; r<sel.Count(); r++) { if (sel.Range(r).Contains(pos)) return true; } return false; } bool Editor::PointInSelection(Point pt) { SelectionPosition pos = SPositionFromLocation(pt, false, true); Point ptPos = LocationFromPosition(pos); for (size_t r=0; r<sel.Count(); r++) { SelectionRange range = sel.Range(r); if (range.Contains(pos)) { bool hit = true; if (pos == range.Start()) { // see if just before selection if (pt.x < ptPos.x) { hit = false; } } if (pos == range.End()) { // see if just after selection if (pt.x > ptPos.x) { hit = false; } } if (hit) return true; } } return false; } bool Editor::PointInSelMargin(Point pt) { // Really means: "Point in a margin" if (vs.fixedColumnWidth > 0) { // There is a margin PRectangle rcSelMargin = GetClientRectangle(); rcSelMargin.right = vs.textStart - vs.leftMarginWidth; rcSelMargin.left = vs.textStart - vs.fixedColumnWidth; return rcSelMargin.Contains(pt); } else { return false; } } Window::Cursor Editor::GetMarginCursor(Point pt) { int x = 0; for (int margin = 0; margin <= SC_MAX_MARGIN; margin++) { if ((pt.x >= x) && (pt.x < x + vs.ms[margin].width)) return static_cast<Window::Cursor>(vs.ms[margin].cursor); x += vs.ms[margin].width; } return Window::cursorReverseArrow; } void Editor::TrimAndSetSelection(int currentPos_, int anchor_) { sel.TrimSelection(SelectionRange(currentPos_, anchor_)); SetSelection(currentPos_, anchor_); } void Editor::LineSelection(int lineCurrentPos_, int lineAnchorPos_, bool wholeLine) { int selCurrentPos, selAnchorPos; if (wholeLine) { int lineCurrent_ = pdoc->LineFromPosition(lineCurrentPos_); int lineAnchor_ = pdoc->LineFromPosition(lineAnchorPos_); if (lineAnchorPos_ < lineCurrentPos_) { selCurrentPos = pdoc->LineStart(lineCurrent_ + 1); selAnchorPos = pdoc->LineStart(lineAnchor_); } else if (lineAnchorPos_ > lineCurrentPos_) { selCurrentPos = pdoc->LineStart(lineCurrent_); selAnchorPos = pdoc->LineStart(lineAnchor_ + 1); } else { // Same line, select it selCurrentPos = pdoc->LineStart(lineAnchor_ + 1); selAnchorPos = pdoc->LineStart(lineAnchor_); } } else { if (lineAnchorPos_ < lineCurrentPos_) { selCurrentPos = StartEndDisplayLine(lineCurrentPos_, false) + 1; selCurrentPos = pdoc->MovePositionOutsideChar(selCurrentPos, 1); selAnchorPos = StartEndDisplayLine(lineAnchorPos_, true); } else if (lineAnchorPos_ > lineCurrentPos_) { selCurrentPos = StartEndDisplayLine(lineCurrentPos_, true); selAnchorPos = StartEndDisplayLine(lineAnchorPos_, false) + 1; selAnchorPos = pdoc->MovePositionOutsideChar(selAnchorPos, 1); } else { // Same line, select it selCurrentPos = StartEndDisplayLine(lineAnchorPos_, false) + 1; selCurrentPos = pdoc->MovePositionOutsideChar(selCurrentPos, 1); selAnchorPos = StartEndDisplayLine(lineAnchorPos_, true); } } TrimAndSetSelection(selCurrentPos, selAnchorPos); } void Editor::WordSelection(int pos) { if (pos < wordSelectAnchorStartPos) { // Extend backward to the word containing pos. // Skip ExtendWordSelect if the line is empty or if pos is after the last character. // This ensures that a series of empty lines isn't counted as a single "word". if (!pdoc->IsLineEndPosition(pos)) pos = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(pos + 1, 1), -1); TrimAndSetSelection(pos, wordSelectAnchorEndPos); } else if (pos > wordSelectAnchorEndPos) { // Extend forward to the word containing the character to the left of pos. // Skip ExtendWordSelect if the line is empty or if pos is the first position on the line. // This ensures that a series of empty lines isn't counted as a single "word". if (pos > pdoc->LineStart(pdoc->LineFromPosition(pos))) pos = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(pos - 1, -1), 1); TrimAndSetSelection(pos, wordSelectAnchorStartPos); } else { // Select only the anchored word if (pos >= originalAnchorPos) TrimAndSetSelection(wordSelectAnchorEndPos, wordSelectAnchorStartPos); else TrimAndSetSelection(wordSelectAnchorStartPos, wordSelectAnchorEndPos); } } void Editor::DwellEnd(bool mouseMoved) { if (mouseMoved) ticksToDwell = dwellDelay; else ticksToDwell = SC_TIME_FOREVER; if (dwelling && (dwellDelay < SC_TIME_FOREVER)) { dwelling = false; NotifyDwelling(ptMouseLast, dwelling); } } void Editor::MouseLeave() { SetHotSpotRange(NULL); if (!HaveMouseCapture()) { ptMouseLast = Point(-1,-1); DwellEnd(true); } } static bool AllowVirtualSpace(int virtualSpaceOptions, bool rectangular) { return (!rectangular && ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0)) || (rectangular && ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) != 0)); } void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) { //Platform::DebugPrintf("ButtonDown %d %d = %d alt=%d %d\n", curTime, lastClickTime, curTime - lastClickTime, alt, inDragDrop); ptMouseLast = pt; SelectionPosition newPos = SPositionFromLocation(pt, false, false, AllowVirtualSpace(virtualSpaceOptions, alt)); newPos = MovePositionOutsideChar(newPos, sel.MainCaret() - newPos.Position()); inDragDrop = ddNone; sel.SetMoveExtends(false); if (NotifyMarginClick(pt, shift, ctrl, alt)) return; NotifyIndicatorClick(true, newPos.Position(), shift, ctrl, alt); bool inSelMargin = PointInSelMargin(pt); // In margin ctrl+(double)click should always select everything if (ctrl && inSelMargin) { SelectAll(); lastClickTime = curTime; lastClick = pt; return; } if (shift && !inSelMargin) { SetSelection(newPos); } if (((curTime - lastClickTime) < Platform::DoubleClickTime()) && Close(pt, lastClick)) { //Platform::DebugPrintf("Double click %d %d = %d\n", curTime, lastClickTime, curTime - lastClickTime); SetMouseCapture(true); if (!ctrl || !multipleSelection || (selectionType != selChar && selectionType != selWord)) SetEmptySelection(newPos.Position()); bool doubleClick = false; // Stop mouse button bounce changing selection type if (!Platform::MouseButtonBounce() || curTime != lastClickTime) { if (inSelMargin) { // Inside margin selection type should be either selSubLine or selWholeLine. if (selectionType == selSubLine) { // If it is selSubLine, we're inside a *double* click and word wrap is enabled, // so we switch to selWholeLine in order to select whole line. selectionType = selWholeLine; } else if (selectionType != selSubLine && selectionType != selWholeLine) { // If it is neither, reset selection type to line selection. selectionType = ((wrapState != eWrapNone) && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? selSubLine : selWholeLine; } } else { if (selectionType == selChar) { selectionType = selWord; doubleClick = true; } else if (selectionType == selWord) { // Since we ended up here, we're inside a *triple* click, which should always select // whole line irregardless of word wrap being enabled or not. selectionType = selWholeLine; } else { selectionType = selChar; originalAnchorPos = sel.MainCaret(); } } } if (selectionType == selWord) { int charPos = originalAnchorPos; if (sel.MainCaret() == originalAnchorPos) { charPos = PositionFromLocation(pt, false, true); charPos = MovePositionOutsideChar(charPos, -1); } int startWord, endWord; if ((sel.MainCaret() >= originalAnchorPos) && !pdoc->IsLineEndPosition(charPos)) { startWord = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(charPos + 1, 1), -1); endWord = pdoc->ExtendWordSelect(charPos, 1); } else { // Selecting backwards, or anchor beyond last character on line. In these cases, // we select the word containing the character to the *left* of the anchor. if (charPos > pdoc->LineStart(pdoc->LineFromPosition(charPos))) { startWord = pdoc->ExtendWordSelect(charPos, -1); endWord = pdoc->ExtendWordSelect(startWord, 1); } else { // Anchor at start of line; select nothing to begin with. startWord = charPos; endWord = charPos; } } wordSelectAnchorStartPos = startWord; wordSelectAnchorEndPos = endWord; wordSelectInitialCaretPos = sel.MainCaret(); WordSelection(wordSelectInitialCaretPos); } else if (selectionType == selSubLine || selectionType == selWholeLine) { lineAnchorPos = newPos.Position(); LineSelection(lineAnchorPos, lineAnchorPos, selectionType == selWholeLine); //Platform::DebugPrintf("Triple click: %d - %d\n", anchor, currentPos); } else { SetEmptySelection(sel.MainCaret()); } //Platform::DebugPrintf("Double click: %d - %d\n", anchor, currentPos); if (doubleClick) { NotifyDoubleClick(pt, shift, ctrl, alt); if (PositionIsHotspot(newPos.Position())) NotifyHotSpotDoubleClicked(newPos.Position(), shift, ctrl, alt); } } else { // Single click if (inSelMargin) { sel.selType = Selection::selStream; if (!shift) { // Single click in margin: select whole line or only subline if word wrap is enabled lineAnchorPos = newPos.Position(); selectionType = ((wrapState != eWrapNone) && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? selSubLine : selWholeLine; LineSelection(lineAnchorPos, lineAnchorPos, selectionType == selWholeLine); } else { // Single shift+click in margin: select from line anchor to clicked line if (sel.MainAnchor() > sel.MainCaret()) lineAnchorPos = sel.MainAnchor() - 1; else lineAnchorPos = sel.MainAnchor(); // Reset selection type if there is an empty selection. // This ensures that we don't end up stuck in previous selection mode, which is no longer valid. // Otherwise, if there's a non empty selection, reset selection type only if it differs from selSubLine and selWholeLine. // This ensures that we continue selecting in the same selection mode. if (sel.Empty() || (selectionType != selSubLine && selectionType != selWholeLine)) selectionType = ((wrapState != eWrapNone) && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? selSubLine : selWholeLine; LineSelection(newPos.Position(), lineAnchorPos, selectionType == selWholeLine); } SetDragPosition(SelectionPosition(invalidPosition)); SetMouseCapture(true); } else { if (PointIsHotspot(pt)) { NotifyHotSpotClicked(newPos.Position(), shift, ctrl, alt); hotSpotClickPos = PositionFromLocation(pt,true,false); } if (!shift) { if (PointInSelection(pt) && !SelectionEmpty()) inDragDrop = ddInitial; else inDragDrop = ddNone; } SetMouseCapture(true); if (inDragDrop != ddInitial) { SetDragPosition(SelectionPosition(invalidPosition)); if (!shift) { if (ctrl && multipleSelection) { SelectionRange range(newPos); sel.TentativeSelection(range); InvalidateSelection(range, true); } else { InvalidateSelection(SelectionRange(newPos), true); if (sel.Count() > 1) Redraw(); if ((sel.Count() > 1) || (sel.selType != Selection::selStream)) sel.Clear(); sel.selType = alt ? Selection::selRectangle : Selection::selStream; SetSelection(newPos, newPos); } } SelectionPosition anchorCurrent = newPos; if (shift) anchorCurrent = sel.IsRectangular() ? sel.Rectangular().anchor : sel.RangeMain().anchor; sel.selType = alt ? Selection::selRectangle : Selection::selStream; selectionType = selChar; originalAnchorPos = sel.MainCaret(); sel.Rectangular() = SelectionRange(newPos, anchorCurrent); SetRectangularRange(); } } } lastClickTime = curTime; lastClick = pt; lastXChosen = pt.x + xOffset; ShowCaretAtCurrentPosition(); } bool Editor::PositionIsHotspot(int position) { return vs.styles[pdoc->StyleAt(position) & pdoc->stylingBitsMask].hotspot; } bool Editor::PointIsHotspot(Point pt) { int pos = PositionFromLocation(pt, true); if (pos == INVALID_POSITION) return false; return PositionIsHotspot(pos); } void Editor::SetHotSpotRange(Point *pt) { if (pt) { int pos = PositionFromLocation(*pt); // If we don't limit this to word characters then the // range can encompass more than the run range and then // the underline will not be drawn properly. int hsStart_ = pdoc->ExtendStyleRange(pos, -1, vs.hotspotSingleLine); int hsEnd_ = pdoc->ExtendStyleRange(pos, 1, vs.hotspotSingleLine); // Only invalidate the range if the hotspot range has changed... if (hsStart_ != hsStart || hsEnd_ != hsEnd) { if (hsStart != -1) { InvalidateRange(hsStart, hsEnd); } hsStart = hsStart_; hsEnd = hsEnd_; InvalidateRange(hsStart, hsEnd); } } else { if (hsStart != -1) { int hsStart_ = hsStart; int hsEnd_ = hsEnd; hsStart = -1; hsEnd = -1; InvalidateRange(hsStart_, hsEnd_); } else { hsStart = -1; hsEnd = -1; } } } void Editor::GetHotSpotRange(int &hsStart_, int &hsEnd_) { hsStart_ = hsStart; hsEnd_ = hsEnd; } void Editor::ButtonMove(Point pt) { if ((ptMouseLast.x != pt.x) || (ptMouseLast.y != pt.y)) { DwellEnd(true); } SelectionPosition movePos = SPositionFromLocation(pt, false, false, AllowVirtualSpace(virtualSpaceOptions, sel.IsRectangular())); movePos = MovePositionOutsideChar(movePos, sel.MainCaret() - movePos.Position()); if (inDragDrop == ddInitial) { if (DragThreshold(ptMouseLast, pt)) { SetMouseCapture(false); SetDragPosition(movePos); CopySelectionRange(&drag); StartDrag(); } return; } ptMouseLast = pt; //Platform::DebugPrintf("Move %d %d\n", pt.x, pt.y); if (HaveMouseCapture()) { // Slow down autoscrolling/selection autoScrollTimer.ticksToWait -= timer.tickSize; if (autoScrollTimer.ticksToWait > 0) return; autoScrollTimer.ticksToWait = autoScrollDelay; // Adjust selection if (posDrag.IsValid()) { SetDragPosition(movePos); } else { if (selectionType == selChar) { if (sel.IsRectangular()) { sel.Rectangular() = SelectionRange(movePos, sel.Rectangular().anchor); SetSelection(movePos, sel.RangeMain().anchor); } else if (sel.Count() > 1) { SelectionRange range(movePos, sel.RangeMain().anchor); sel.TentativeSelection(range); InvalidateSelection(range, true); } else { SetSelection(movePos, sel.RangeMain().anchor); } } else if (selectionType == selWord) { // Continue selecting by word if (movePos.Position() == wordSelectInitialCaretPos) { // Didn't move // No need to do anything. Previously this case was lumped // in with "Moved forward", but that can be harmful in this // case: a handler for the NotifyDoubleClick re-adjusts // the selection for a fancier definition of "word" (for // example, in Perl it is useful to include the leading // '$', '%' or '@' on variables for word selection). In this // the ButtonMove() called via Tick() for auto-scrolling // could result in the fancier word selection adjustment // being unmade. } else { wordSelectInitialCaretPos = -1; WordSelection(movePos.Position()); } } else { // Continue selecting by line LineSelection(movePos.Position(), lineAnchorPos, selectionType == selWholeLine); } } // Autoscroll PRectangle rcClient = GetClientRectangle(); Point ptOrigin = GetVisibleOriginInMain(); rcClient.Move(0, -ptOrigin.y); int lineMove = DisplayFromPosition(movePos.Position()); if (pt.y > rcClient.bottom) { ScrollTo(lineMove - LinesOnScreen() + 1); Redraw(); } else if (pt.y < rcClient.top) { ScrollTo(lineMove); Redraw(); } EnsureCaretVisible(false, false, true); if (hsStart != -1 && !PositionIsHotspot(movePos.Position())) SetHotSpotRange(NULL); if (hotSpotClickPos != INVALID_POSITION && PositionFromLocation(pt,true,false) != hotSpotClickPos) { if (inDragDrop == ddNone) { DisplayCursor(Window::cursorText); } hotSpotClickPos = INVALID_POSITION; } } else { if (vs.fixedColumnWidth > 0) { // There is a margin if (PointInSelMargin(pt)) { DisplayCursor(GetMarginCursor(pt)); SetHotSpotRange(NULL); return; // No need to test for selection } } // Display regular (drag) cursor over selection if (PointInSelection(pt) && !SelectionEmpty()) { DisplayCursor(Window::cursorArrow); } else if (PointIsHotspot(pt)) { DisplayCursor(Window::cursorHand); SetHotSpotRange(&pt); } else { DisplayCursor(Window::cursorText); SetHotSpotRange(NULL); } } } void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) { //Platform::DebugPrintf("ButtonUp %d %d\n", HaveMouseCapture(), inDragDrop); SelectionPosition newPos = SPositionFromLocation(pt, false, false, AllowVirtualSpace(virtualSpaceOptions, sel.IsRectangular())); newPos = MovePositionOutsideChar(newPos, sel.MainCaret() - newPos.Position()); if (inDragDrop == ddInitial) { inDragDrop = ddNone; SetEmptySelection(newPos); selectionType = selChar; originalAnchorPos = sel.MainCaret(); } if (hotSpotClickPos != INVALID_POSITION && PointIsHotspot(pt)) { hotSpotClickPos = INVALID_POSITION; NotifyHotSpotReleaseClick(newPos.Position(), false, ctrl, false); } if (HaveMouseCapture()) { if (PointInSelMargin(pt)) { DisplayCursor(GetMarginCursor(pt)); } else { DisplayCursor(Window::cursorText); SetHotSpotRange(NULL); } ptMouseLast = pt; SetMouseCapture(false); NotifyIndicatorClick(false, newPos.Position(), false, false, false); if (inDragDrop == ddDragging) { SelectionPosition selStart = SelectionStart(); SelectionPosition selEnd = SelectionEnd(); if (selStart < selEnd) { if (drag.len) { if (ctrl) { if (pdoc->InsertString(newPos.Position(), drag.s, drag.len)) { SetSelection(newPos.Position(), newPos.Position() + drag.len); } } else if (newPos < selStart) { pdoc->DeleteChars(selStart.Position(), drag.len); if (pdoc->InsertString(newPos.Position(), drag.s, drag.len)) { SetSelection(newPos.Position(), newPos.Position() + drag.len); } } else if (newPos > selEnd) { pdoc->DeleteChars(selStart.Position(), drag.len); newPos.Add(-drag.len); if (pdoc->InsertString(newPos.Position(), drag.s, drag.len)) { SetSelection(newPos.Position(), newPos.Position() + drag.len); } } else { SetEmptySelection(newPos.Position()); } drag.Free(); } selectionType = selChar; } } else { if (selectionType == selChar) { if (sel.Count() > 1) { sel.RangeMain() = SelectionRange(newPos, sel.Range(sel.Count() - 1).anchor); InvalidateSelection(sel.RangeMain(), true); } else { SetSelection(newPos, sel.RangeMain().anchor); } } sel.CommitTentative(); } SetRectangularRange(); lastClickTime = curTime; lastClick = pt; lastXChosen = pt.x + xOffset; if (sel.selType == Selection::selStream) { SetLastXChosen(); } inDragDrop = ddNone; EnsureCaretVisible(false); } } // Called frequently to perform background UI including // caret blinking and automatic scrolling. void Editor::Tick() { if (HaveMouseCapture()) { // Auto scroll ButtonMove(ptMouseLast); } if (caret.period > 0) { timer.ticksToWait -= timer.tickSize; if (timer.ticksToWait <= 0) { caret.on = !caret.on; timer.ticksToWait = caret.period; if (caret.active) { InvalidateCaret(); } } } if (horizontalScrollBarVisible && trackLineWidth && (lineWidthMaxSeen > scrollWidth)) { scrollWidth = lineWidthMaxSeen; SetScrollBars(); } if ((dwellDelay < SC_TIME_FOREVER) && (ticksToDwell > 0) && (!HaveMouseCapture()) && (ptMouseLast.y >= 0)) { ticksToDwell -= timer.tickSize; if (ticksToDwell <= 0) { dwelling = true; NotifyDwelling(ptMouseLast, dwelling); } } } bool Editor::Idle() { bool idleDone; bool wrappingDone = wrapState == eWrapNone; if (!wrappingDone) { // Wrap lines during idle. WrapLines(false, -1); // No more wrapping if (wrapStart == wrapEnd) wrappingDone = true; } // Add more idle things to do here, but make sure idleDone is // set correctly before the function returns. returning // false will stop calling this idle funtion until SetIdle() is // called again. idleDone = wrappingDone; // && thatDone && theOtherThingDone... return !idleDone; } void Editor::SetFocusState(bool focusState) { hasFocus = focusState; NotifyFocus(hasFocus); if (hasFocus) { ShowCaretAtCurrentPosition(); } else { CancelModes(); DropCaret(); } } int Editor::PositionAfterArea(PRectangle rcArea) { // The start of the document line after the display line after the area // This often means that the line after a modification is restyled which helps // detect multiline comment additions and heals single line comments int lineAfter = topLine + (rcArea.bottom - 1) / vs.lineHeight + 1; if (lineAfter < cs.LinesDisplayed()) return pdoc->LineStart(cs.DocFromDisplay(lineAfter) + 1); else return pdoc->Length(); } // Style to a position within the view. If this causes a change at end of last line then // affects later lines so style all the viewed text. void Editor::StyleToPositionInView(Position pos) { int endWindow = (vs.marginInside) ? (PositionAfterArea(GetClientRectangle())) : (pdoc->Length()); if (pos > endWindow) pos = endWindow; int styleAtEnd = pdoc->StyleAt(pos-1); pdoc->EnsureStyledTo(pos); if ((endWindow > pos) && (styleAtEnd != pdoc->StyleAt(pos-1))) { // Style at end of line changed so is multi-line change like starting a comment // so require rest of window to be styled. pdoc->EnsureStyledTo(endWindow); } } void Editor::IdleWork() { // Style the line after the modification as this allows modifications that change just the // line of the modification to heal instead of propagating to the rest of the window. if (workNeeded.items & WorkNeeded::workStyle) StyleToPositionInView(pdoc->LineStart(pdoc->LineFromPosition(workNeeded.upTo) + 2)); NotifyUpdateUI(); workNeeded.Reset(); } void Editor::QueueIdleWork(WorkNeeded::workItems items, int upTo) { workNeeded.Need(items, upTo); } bool Editor::PaintContains(PRectangle rc) { if (rc.Empty()) { return true; } else { return rcPaint.Contains(rc); } } bool Editor::PaintContainsMargin() { if (wMargin.GetID()) { // With separate margin view, paint of text view // never contains margin. return false; } PRectangle rcSelMargin = GetClientRectangle(); rcSelMargin.right = vs.textStart; return PaintContains(rcSelMargin); } void Editor::CheckForChangeOutsidePaint(Range r) { if (paintState == painting && !paintingAllText) { //Platform::DebugPrintf("Checking range in paint %d-%d\n", r.start, r.end); if (!r.Valid()) return; PRectangle rcRange = RectangleFromRange(r.start, r.end); PRectangle rcText = GetTextRectangle(); if (rcRange.top < rcText.top) { rcRange.top = rcText.top; } if (rcRange.bottom > rcText.bottom) { rcRange.bottom = rcText.bottom; } if (!PaintContains(rcRange)) { AbandonPaint(); } } } void Editor::SetBraceHighlight(Position pos0, Position pos1, int matchStyle) { if ((pos0 != braces[0]) || (pos1 != braces[1]) || (matchStyle != bracesMatchStyle)) { if ((braces[0] != pos0) || (matchStyle != bracesMatchStyle)) { CheckForChangeOutsidePaint(Range(braces[0])); CheckForChangeOutsidePaint(Range(pos0)); braces[0] = pos0; } if ((braces[1] != pos1) || (matchStyle != bracesMatchStyle)) { CheckForChangeOutsidePaint(Range(braces[1])); CheckForChangeOutsidePaint(Range(pos1)); braces[1] = pos1; } bracesMatchStyle = matchStyle; if (paintState == notPainting) { Redraw(); } } } void Editor::SetAnnotationHeights(int start, int end) { if (vs.annotationVisible) { bool changedHeight = false; for (int line=start; line<end && line<pdoc->LinesTotal(); line++) { int linesWrapped = 1; if (wrapState != eWrapNone) { AutoSurface surface(this); AutoLineLayout ll(llc, RetrieveLineLayout(line)); if (surface && ll) { LayoutLine(line, surface, vs, ll, wrapWidth); linesWrapped = ll->lines; } } if (cs.SetHeight(line, pdoc->AnnotationLines(line) + linesWrapped)) changedHeight = true; } if (changedHeight) { Redraw(); } } } void Editor::SetDocPointer(Document *document) { //Platform::DebugPrintf("** %x setdoc to %x\n", pdoc, document); pdoc->RemoveWatcher(this, 0); pdoc->Release(); if (document == NULL) { pdoc = new Document(); } else { pdoc = document; } pdoc->AddRef(); // Ensure all positions within document sel.Clear(); targetStart = 0; targetEnd = 0; braces[0] = invalidPosition; braces[1] = invalidPosition; vs.ReleaseAllExtendedStyles(); // Reset the contraction state to fully shown. cs.Clear(); cs.InsertLines(0, pdoc->LinesTotal() - 1); SetAnnotationHeights(0, pdoc->LinesTotal()); llc.Deallocate(); NeedWrapping(); pdoc->AddWatcher(this, 0); SetScrollBars(); Redraw(); } void Editor::SetAnnotationVisible(int visible) { if (vs.annotationVisible != visible) { bool changedFromOrToHidden = ((vs.annotationVisible != 0) != (visible != 0)); vs.annotationVisible = visible; if (changedFromOrToHidden) { int dir = vs.annotationVisible ? 1 : -1; for (int line=0; line<pdoc->LinesTotal(); line++) { int annotationLines = pdoc->AnnotationLines(line); if (annotationLines > 0) { cs.SetHeight(line, cs.GetHeight(line) + annotationLines * dir); } } } Redraw(); } } /** * Recursively expand a fold, making lines visible except where they have an unexpanded parent. */ void Editor::Expand(int &line, bool doExpand) { int lineMaxSubord = pdoc->GetLastChild(line); line++; while (line <= lineMaxSubord) { if (doExpand) cs.SetVisible(line, line, true); int level = pdoc->GetLevel(line); if (level & SC_FOLDLEVELHEADERFLAG) { if (doExpand && cs.GetExpanded(line)) { Expand(line, true); } else { Expand(line, false); } } else { line++; } } } void Editor::ToggleContraction(int line) { if (line >= 0) { if ((pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG) == 0) { line = pdoc->GetFoldParent(line); if (line < 0) return; } if (cs.GetExpanded(line)) { int lineMaxSubord = pdoc->GetLastChild(line); if (lineMaxSubord > line) { cs.SetExpanded(line, 0); cs.SetVisible(line + 1, lineMaxSubord, false); int lineCurrent = pdoc->LineFromPosition(sel.MainCaret()); if (lineCurrent > line && lineCurrent <= lineMaxSubord) { // This does not re-expand the fold EnsureCaretVisible(); } SetScrollBars(); Redraw(); } } else { if (!(cs.GetVisible(line))) { EnsureLineVisible(line, false); GoToLine(line); } cs.SetExpanded(line, 1); Expand(line, true); SetScrollBars(); Redraw(); } } } int Editor::ContractedFoldNext(int lineStart) { for (int line = lineStart; line<pdoc->LinesTotal();) { if (!cs.GetExpanded(line) && (pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG)) return line; line = cs.ContractedNext(line+1); if (line < 0) return -1; } return -1; } /** * Recurse up from this line to find any folds that prevent this line from being visible * and unfold them all. */ void Editor::EnsureLineVisible(int lineDoc, bool enforcePolicy) { // In case in need of wrapping to ensure DisplayFromDoc works. if (lineDoc >= wrapStart) WrapLines(true, -1); if (!cs.GetVisible(lineDoc)) { // Back up to find a non-blank line int lookLine = lineDoc; int lookLineLevel = pdoc->GetLevel(lookLine); while ((lookLine > 0) && (lookLineLevel & SC_FOLDLEVELWHITEFLAG)) { lookLineLevel = pdoc->GetLevel(--lookLine); } int lineParent = pdoc->GetFoldParent(lookLine); if (lineParent < 0) { // Backed up to a top level line, so try to find parent of initial line lineParent = pdoc->GetFoldParent(lineDoc); } if (lineParent >= 0) { if (lineDoc != lineParent) EnsureLineVisible(lineParent, enforcePolicy); if (!cs.GetExpanded(lineParent)) { cs.SetExpanded(lineParent, 1); Expand(lineParent, true); } } SetScrollBars(); Redraw(); } if (enforcePolicy) { int lineDisplay = cs.DisplayFromDoc(lineDoc); if (visiblePolicy & VISIBLE_SLOP) { if ((topLine > lineDisplay) || ((visiblePolicy & VISIBLE_STRICT) && (topLine + visibleSlop > lineDisplay))) { SetTopLine(Platform::Clamp(lineDisplay - visibleSlop, 0, MaxScrollPos())); SetVerticalScrollPos(); Redraw(); } else if ((lineDisplay > topLine + LinesOnScreen() - 1) || ((visiblePolicy & VISIBLE_STRICT) && (lineDisplay > topLine + LinesOnScreen() - 1 - visibleSlop))) { SetTopLine(Platform::Clamp(lineDisplay - LinesOnScreen() + 1 + visibleSlop, 0, MaxScrollPos())); SetVerticalScrollPos(); Redraw(); } } else { if ((topLine > lineDisplay) || (lineDisplay > topLine + LinesOnScreen() - 1) || (visiblePolicy & VISIBLE_STRICT)) { SetTopLine(Platform::Clamp(lineDisplay - LinesOnScreen() / 2 + 1, 0, MaxScrollPos())); SetVerticalScrollPos(); Redraw(); } } } } int Editor::GetTag(char *tagValue, int tagNumber) { const char *text = 0; int length = 0; if ((tagNumber >= 1) && (tagNumber <= 9)) { char name[3] = "\\?"; name[1] = static_cast<char>(tagNumber + '0'); length = 2; text = pdoc->SubstituteByPosition(name, &length); } if (tagValue) { if (text) memcpy(tagValue, text, length + 1); else *tagValue = '\0'; } return length; } int Editor::ReplaceTarget(bool replacePatterns, const char *text, int length) { UndoGroup ug(pdoc); if (length == -1) length = istrlen(text); if (replacePatterns) { text = pdoc->SubstituteByPosition(text, &length); if (!text) { return 0; } } if (targetStart != targetEnd) pdoc->DeleteChars(targetStart, targetEnd - targetStart); targetEnd = targetStart; pdoc->InsertString(targetStart, text, length); targetEnd = targetStart + length; return length; } bool Editor::IsUnicodeMode() const { return pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage); } int Editor::CodePage() const { if (pdoc) return pdoc->dbcsCodePage; else return 0; } int Editor::WrapCount(int line) { AutoSurface surface(this); AutoLineLayout ll(llc, RetrieveLineLayout(line)); if (surface && ll) { LayoutLine(line, surface, vs, ll, wrapWidth); return ll->lines; } else { return 1; } } void Editor::AddStyledText(char *buffer, int appendLength) { // The buffer consists of alternating character bytes and style bytes int textLength = appendLength / 2; char *text = new char[textLength]; int i; for (i = 0; i < textLength; i++) { text[i] = buffer[i*2]; } pdoc->InsertString(CurrentPosition(), text, textLength); for (i = 0; i < textLength; i++) { text[i] = buffer[i*2+1]; } pdoc->StartStyling(CurrentPosition(), static_cast<char>(0xff)); pdoc->SetStyles(textLength, text); delete []text; SetEmptySelection(sel.MainCaret() + textLength); } static bool ValidMargin(unsigned long wParam) { return wParam <= SC_MAX_MARGIN; } static char *CharPtrFromSPtr(sptr_t lParam) { return reinterpret_cast<char *>(lParam); } void Editor::StyleSetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { vs.EnsureStyle(wParam); switch (iMessage) { case SCI_STYLESETFORE: vs.styles[wParam].fore = ColourDesired(lParam); break; case SCI_STYLESETBACK: vs.styles[wParam].back = ColourDesired(lParam); break; case SCI_STYLESETBOLD: vs.styles[wParam].weight = lParam != 0 ? SC_WEIGHT_BOLD : SC_WEIGHT_NORMAL; break; case SCI_STYLESETWEIGHT: vs.styles[wParam].weight = lParam; break; case SCI_STYLESETITALIC: vs.styles[wParam].italic = lParam != 0; break; case SCI_STYLESETEOLFILLED: vs.styles[wParam].eolFilled = lParam != 0; break; case SCI_STYLESETSIZE: vs.styles[wParam].size = lParam * SC_FONT_SIZE_MULTIPLIER; break; case SCI_STYLESETSIZEFRACTIONAL: vs.styles[wParam].size = lParam; break; case SCI_STYLESETFONT: if (lParam != 0) { vs.SetStyleFontName(wParam, CharPtrFromSPtr(lParam)); } break; case SCI_STYLESETUNDERLINE: vs.styles[wParam].underline = lParam != 0; break; case SCI_STYLESETCASE: vs.styles[wParam].caseForce = static_cast<Style::ecaseForced>(lParam); break; case SCI_STYLESETCHARACTERSET: vs.styles[wParam].characterSet = lParam; pdoc->SetCaseFolder(NULL); break; case SCI_STYLESETVISIBLE: vs.styles[wParam].visible = lParam != 0; break; case SCI_STYLESETCHANGEABLE: vs.styles[wParam].changeable = lParam != 0; break; case SCI_STYLESETHOTSPOT: vs.styles[wParam].hotspot = lParam != 0; break; } InvalidateStyleRedraw(); } sptr_t Editor::StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { vs.EnsureStyle(wParam); switch (iMessage) { case SCI_STYLEGETFORE: return vs.styles[wParam].fore.AsLong(); case SCI_STYLEGETBACK: return vs.styles[wParam].back.AsLong(); case SCI_STYLEGETBOLD: return vs.styles[wParam].weight > SC_WEIGHT_NORMAL; case SCI_STYLEGETWEIGHT: return vs.styles[wParam].weight; case SCI_STYLEGETITALIC: return vs.styles[wParam].italic ? 1 : 0; case SCI_STYLEGETEOLFILLED: return vs.styles[wParam].eolFilled ? 1 : 0; case SCI_STYLEGETSIZE: return vs.styles[wParam].size / SC_FONT_SIZE_MULTIPLIER; case SCI_STYLEGETSIZEFRACTIONAL: return vs.styles[wParam].size; case SCI_STYLEGETFONT: if (!vs.styles[wParam].fontName) return 0; if (lParam != 0) strcpy(CharPtrFromSPtr(lParam), vs.styles[wParam].fontName); return strlen(vs.styles[wParam].fontName); case SCI_STYLEGETUNDERLINE: return vs.styles[wParam].underline ? 1 : 0; case SCI_STYLEGETCASE: return static_cast<int>(vs.styles[wParam].caseForce); case SCI_STYLEGETCHARACTERSET: return vs.styles[wParam].characterSet; case SCI_STYLEGETVISIBLE: return vs.styles[wParam].visible ? 1 : 0; case SCI_STYLEGETCHANGEABLE: return vs.styles[wParam].changeable ? 1 : 0; case SCI_STYLEGETHOTSPOT: return vs.styles[wParam].hotspot ? 1 : 0; } return 0; } sptr_t Editor::StringResult(sptr_t lParam, const char *val) { const size_t n = strlen(val); if (lParam != 0) { char *ptr = reinterpret_cast<char *>(lParam); strcpy(ptr, val); } return n; // Not including NUL } sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { //Platform::DebugPrintf("S start wnd proc %d %d %d\n",iMessage, wParam, lParam); // Optional macro recording hook if (recordingMacro) NotifyMacroRecord(iMessage, wParam, lParam); switch (iMessage) { case SCI_GETTEXT: { if (lParam == 0) return pdoc->Length() + 1; if (wParam == 0) return 0; char *ptr = CharPtrFromSPtr(lParam); unsigned int iChar = 0; for (; iChar < wParam - 1; iChar++) ptr[iChar] = pdoc->CharAt(iChar); ptr[iChar] = '\0'; return iChar; } case SCI_SETTEXT: { if (lParam == 0) return 0; UndoGroup ug(pdoc); pdoc->DeleteChars(0, pdoc->Length()); SetEmptySelection(0); pdoc->InsertCString(0, CharPtrFromSPtr(lParam)); return 1; } case SCI_GETTEXTLENGTH: return pdoc->Length(); case SCI_CUT: Cut(); SetLastXChosen(); break; case SCI_COPY: Copy(); break; case SCI_COPYALLOWLINE: CopyAllowLine(); break; case SCI_VERTICALCENTRECARET: VerticalCentreCaret(); break; case SCI_MOVESELECTEDLINESUP: MoveSelectedLinesUp(); break; case SCI_MOVESELECTEDLINESDOWN: MoveSelectedLinesDown(); break; case SCI_COPYRANGE: CopyRangeToClipboard(wParam, lParam); break; case SCI_COPYTEXT: CopyText(wParam, CharPtrFromSPtr(lParam)); break; case SCI_PASTE: Paste(); if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) { SetLastXChosen(); } EnsureCaretVisible(); break; case SCI_CLEAR: Clear(); SetLastXChosen(); EnsureCaretVisible(); break; case SCI_UNDO: Undo(); SetLastXChosen(); break; case SCI_CANUNDO: return (pdoc->CanUndo() && !pdoc->IsReadOnly()) ? 1 : 0; case SCI_EMPTYUNDOBUFFER: pdoc->DeleteUndoHistory(); return 0; case SCI_GETFIRSTVISIBLELINE: return topLine; case SCI_SETFIRSTVISIBLELINE: ScrollTo(wParam); break; case SCI_GETLINE: { // Risk of overwriting the end of the buffer int lineStart = pdoc->LineStart(wParam); int lineEnd = pdoc->LineStart(wParam + 1); if (lParam == 0) { return lineEnd - lineStart; } char *ptr = CharPtrFromSPtr(lParam); int iPlace = 0; for (int iChar = lineStart; iChar < lineEnd; iChar++) { ptr[iPlace++] = pdoc->CharAt(iChar); } return iPlace; } case SCI_GETLINECOUNT: if (pdoc->LinesTotal() == 0) return 1; else return pdoc->LinesTotal(); case SCI_GETMODIFY: return !pdoc->IsSavePoint(); case SCI_SETSEL: { int nStart = static_cast<int>(wParam); int nEnd = static_cast<int>(lParam); if (nEnd < 0) nEnd = pdoc->Length(); if (nStart < 0) nStart = nEnd; // Remove selection InvalidateSelection(SelectionRange(nStart, nEnd)); sel.Clear(); sel.selType = Selection::selStream; SetSelection(nEnd, nStart); EnsureCaretVisible(); } break; case SCI_GETSELTEXT: { SelectionText selectedText; CopySelectionRange(&selectedText); if (lParam == 0) { return selectedText.len ? selectedText.len : 1; } else { char *ptr = CharPtrFromSPtr(lParam); int iChar = 0; if (selectedText.len) { for (; iChar < selectedText.len; iChar++) ptr[iChar] = selectedText.s[iChar]; } else { ptr[0] = '\0'; } return iChar; } } case SCI_LINEFROMPOSITION: if (static_cast<int>(wParam) < 0) return 0; return pdoc->LineFromPosition(wParam); case SCI_POSITIONFROMLINE: if (static_cast<int>(wParam) < 0) wParam = pdoc->LineFromPosition(SelectionStart().Position()); if (wParam == 0) return 0; // Even if there is no text, there is a first line that starts at 0 if (static_cast<int>(wParam) > pdoc->LinesTotal()) return -1; //if (wParam > pdoc->LineFromPosition(pdoc->Length())) // Useful test, anyway... // return -1; return pdoc->LineStart(wParam); // Replacement of the old Scintilla interpretation of EM_LINELENGTH case SCI_LINELENGTH: if ((static_cast<int>(wParam) < 0) || (static_cast<int>(wParam) > pdoc->LineFromPosition(pdoc->Length()))) return 0; return pdoc->LineStart(wParam + 1) - pdoc->LineStart(wParam); case SCI_REPLACESEL: { if (lParam == 0) return 0; UndoGroup ug(pdoc); ClearSelection(); char *replacement = CharPtrFromSPtr(lParam); pdoc->InsertCString(sel.MainCaret(), replacement); SetEmptySelection(sel.MainCaret() + istrlen(replacement)); EnsureCaretVisible(); } break; case SCI_SETTARGETSTART: targetStart = wParam; break; case SCI_GETTARGETSTART: return targetStart; case SCI_SETTARGETEND: targetEnd = wParam; break; case SCI_GETTARGETEND: return targetEnd; case SCI_TARGETFROMSELECTION: if (sel.MainCaret() < sel.MainAnchor()) { targetStart = sel.MainCaret(); targetEnd = sel.MainAnchor(); } else { targetStart = sel.MainAnchor(); targetEnd = sel.MainCaret(); } break; case SCI_REPLACETARGET: PLATFORM_ASSERT(lParam); return ReplaceTarget(false, CharPtrFromSPtr(lParam), wParam); case SCI_REPLACETARGETRE: PLATFORM_ASSERT(lParam); return ReplaceTarget(true, CharPtrFromSPtr(lParam), wParam); case SCI_SEARCHINTARGET: PLATFORM_ASSERT(lParam); return SearchInTarget(CharPtrFromSPtr(lParam), wParam); case SCI_SETSEARCHFLAGS: searchFlags = wParam; break; case SCI_GETSEARCHFLAGS: return searchFlags; case SCI_GETTAG: return GetTag(CharPtrFromSPtr(lParam), wParam); case SCI_POSITIONBEFORE: return pdoc->MovePositionOutsideChar(wParam - 1, -1, true); case SCI_POSITIONAFTER: return pdoc->MovePositionOutsideChar(wParam + 1, 1, true); case SCI_LINESCROLL: ScrollTo(topLine + lParam); HorizontalScrollTo(xOffset + static_cast<int>(wParam) * vs.spaceWidth); return 1; case SCI_SETXOFFSET: xOffset = wParam; ContainerNeedsUpdate(SC_UPDATE_H_SCROLL); SetHorizontalScrollPos(); Redraw(); break; case SCI_GETXOFFSET: return xOffset; case SCI_CHOOSECARETX: SetLastXChosen(); break; case SCI_SCROLLCARET: EnsureCaretVisible(); break; case SCI_SETREADONLY: pdoc->SetReadOnly(wParam != 0); return 1; case SCI_GETREADONLY: return pdoc->IsReadOnly(); case SCI_CANPASTE: return CanPaste(); case SCI_POINTXFROMPOSITION: if (lParam < 0) { return 0; } else { Point pt = LocationFromPosition(lParam); // Convert to view-relative return pt.x - vs.textStart + vs.fixedColumnWidth; } case SCI_POINTYFROMPOSITION: if (lParam < 0) { return 0; } else { Point pt = LocationFromPosition(lParam); return pt.y; } case SCI_FINDTEXT: return FindText(wParam, lParam); case SCI_GETTEXTRANGE: { if (lParam == 0) return 0; Sci_TextRange *tr = reinterpret_cast<Sci_TextRange *>(lParam); int cpMax = tr->chrg.cpMax; if (cpMax == -1) cpMax = pdoc->Length(); PLATFORM_ASSERT(cpMax <= pdoc->Length()); int len = cpMax - tr->chrg.cpMin; // No -1 as cpMin and cpMax are referring to inter character positions pdoc->GetCharRange(tr->lpstrText, tr->chrg.cpMin, len); // Spec says copied text is terminated with a NUL tr->lpstrText[len] = '\0'; return len; // Not including NUL } case SCI_HIDESELECTION: hideSelection = wParam != 0; Redraw(); break; case SCI_FORMATRANGE: return FormatRange(wParam != 0, reinterpret_cast<Sci_RangeToFormat *>(lParam)); case SCI_GETMARGINLEFT: return vs.leftMarginWidth; case SCI_GETMARGINRIGHT: return vs.rightMarginWidth; case SCI_SETMARGINLEFT: vs.leftMarginWidth = lParam; InvalidateStyleRedraw(); break; case SCI_SETMARGINRIGHT: vs.rightMarginWidth = lParam; InvalidateStyleRedraw(); break; // Control specific mesages case SCI_ADDTEXT: { if (lParam == 0) return 0; pdoc->InsertString(CurrentPosition(), CharPtrFromSPtr(lParam), wParam); SetEmptySelection(sel.MainCaret() + wParam); return 0; } case SCI_ADDSTYLEDTEXT: if (lParam) AddStyledText(CharPtrFromSPtr(lParam), wParam); return 0; case SCI_INSERTTEXT: { if (lParam == 0) return 0; int insertPos = wParam; if (static_cast<int>(wParam) == -1) insertPos = CurrentPosition(); int newCurrent = CurrentPosition(); char *sz = CharPtrFromSPtr(lParam); pdoc->InsertCString(insertPos, sz); if (newCurrent > insertPos) newCurrent += istrlen(sz); SetEmptySelection(newCurrent); return 0; } case SCI_APPENDTEXT: pdoc->InsertString(pdoc->Length(), CharPtrFromSPtr(lParam), wParam); return 0; case SCI_CLEARALL: ClearAll(); return 0; case SCI_DELETERANGE: pdoc->DeleteChars(wParam, lParam); return 0; case SCI_CLEARDOCUMENTSTYLE: ClearDocumentStyle(); return 0; case SCI_SETUNDOCOLLECTION: pdoc->SetUndoCollection(wParam != 0); return 0; case SCI_GETUNDOCOLLECTION: return pdoc->IsCollectingUndo(); case SCI_BEGINUNDOACTION: pdoc->BeginUndoAction(); return 0; case SCI_ENDUNDOACTION: pdoc->EndUndoAction(); return 0; case SCI_GETCARETPERIOD: return caret.period; case SCI_SETCARETPERIOD: caret.period = wParam; break; case SCI_GETWORDCHARS: return pdoc->GetCharsOfClass(CharClassify::ccWord, reinterpret_cast<unsigned char *>(lParam)); case SCI_SETWORDCHARS: { pdoc->SetDefaultCharClasses(false); if (lParam == 0) return 0; pdoc->SetCharClasses(reinterpret_cast<unsigned char *>(lParam), CharClassify::ccWord); } break; case SCI_GETWHITESPACECHARS: return pdoc->GetCharsOfClass(CharClassify::ccSpace, reinterpret_cast<unsigned char *>(lParam)); case SCI_SETWHITESPACECHARS: { if (lParam == 0) return 0; pdoc->SetCharClasses(reinterpret_cast<unsigned char *>(lParam), CharClassify::ccSpace); } break; case SCI_GETPUNCTUATIONCHARS: return pdoc->GetCharsOfClass(CharClassify::ccPunctuation, reinterpret_cast<unsigned char *>(lParam)); case SCI_SETPUNCTUATIONCHARS: { if (lParam == 0) return 0; pdoc->SetCharClasses(reinterpret_cast<unsigned char *>(lParam), CharClassify::ccPunctuation); } break; case SCI_SETCHARSDEFAULT: pdoc->SetDefaultCharClasses(true); break; case SCI_GETLENGTH: return pdoc->Length(); case SCI_ALLOCATE: pdoc->Allocate(wParam); break; case SCI_GETCHARAT: return pdoc->CharAt(wParam); case SCI_SETCURRENTPOS: if (sel.IsRectangular()) { sel.Rectangular().caret.SetPosition(wParam); SetRectangularRange(); Redraw(); } else { SetSelection(wParam, sel.MainAnchor()); } break; case SCI_GETCURRENTPOS: return sel.IsRectangular() ? sel.Rectangular().caret.Position() : sel.MainCaret(); case SCI_SETANCHOR: if (sel.IsRectangular()) { sel.Rectangular().anchor.SetPosition(wParam); SetRectangularRange(); Redraw(); } else { SetSelection(sel.MainCaret(), wParam); } break; case SCI_GETANCHOR: return sel.IsRectangular() ? sel.Rectangular().anchor.Position() : sel.MainAnchor(); case SCI_SETSELECTIONSTART: SetSelection(Platform::Maximum(sel.MainCaret(), wParam), wParam); break; case SCI_GETSELECTIONSTART: return sel.LimitsForRectangularElseMain().start.Position(); case SCI_SETSELECTIONEND: SetSelection(wParam, Platform::Minimum(sel.MainAnchor(), wParam)); break; case SCI_GETSELECTIONEND: return sel.LimitsForRectangularElseMain().end.Position(); case SCI_SETEMPTYSELECTION: SetEmptySelection(wParam); break; case SCI_SETPRINTMAGNIFICATION: printMagnification = wParam; break; case SCI_GETPRINTMAGNIFICATION: return printMagnification; case SCI_SETPRINTCOLOURMODE: printColourMode = wParam; break; case SCI_GETPRINTCOLOURMODE: return printColourMode; case SCI_SETPRINTWRAPMODE: printWrapState = (wParam == SC_WRAP_WORD) ? eWrapWord : eWrapNone; break; case SCI_GETPRINTWRAPMODE: return printWrapState; case SCI_GETSTYLEAT: if (static_cast<int>(wParam) >= pdoc->Length()) return 0; else return pdoc->StyleAt(wParam); case SCI_REDO: Redo(); break; case SCI_SELECTALL: SelectAll(); break; case SCI_SETSAVEPOINT: pdoc->SetSavePoint(); break; case SCI_GETSTYLEDTEXT: { if (lParam == 0) return 0; Sci_TextRange *tr = reinterpret_cast<Sci_TextRange *>(lParam); int iPlace = 0; for (int iChar = tr->chrg.cpMin; iChar < tr->chrg.cpMax; iChar++) { tr->lpstrText[iPlace++] = pdoc->CharAt(iChar); tr->lpstrText[iPlace++] = pdoc->StyleAt(iChar); } tr->lpstrText[iPlace] = '\0'; tr->lpstrText[iPlace + 1] = '\0'; return iPlace; } case SCI_CANREDO: return (pdoc->CanRedo() && !pdoc->IsReadOnly()) ? 1 : 0; case SCI_MARKERLINEFROMHANDLE: return pdoc->LineFromHandle(wParam); case SCI_MARKERDELETEHANDLE: pdoc->DeleteMarkFromHandle(wParam); break; case SCI_GETVIEWWS: return vs.viewWhitespace; case SCI_SETVIEWWS: vs.viewWhitespace = static_cast<WhiteSpaceVisibility>(wParam); Redraw(); break; case SCI_GETWHITESPACESIZE: return vs.whitespaceSize; case SCI_SETWHITESPACESIZE: vs.whitespaceSize = static_cast<int>(wParam); Redraw(); break; case SCI_POSITIONFROMPOINT: return PositionFromLocation(Point(wParam, lParam), false, false); case SCI_POSITIONFROMPOINTCLOSE: return PositionFromLocation(Point(wParam, lParam), true, false); case SCI_CHARPOSITIONFROMPOINT: return PositionFromLocation(Point(wParam, lParam), false, true); case SCI_CHARPOSITIONFROMPOINTCLOSE: return PositionFromLocation(Point(wParam, lParam), true, true); case SCI_GOTOLINE: GoToLine(wParam); break; case SCI_GOTOPOS: SetEmptySelection(wParam); EnsureCaretVisible(); break; case SCI_GETCURLINE: { int lineCurrentPos = pdoc->LineFromPosition(sel.MainCaret()); int lineStart = pdoc->LineStart(lineCurrentPos); unsigned int lineEnd = pdoc->LineStart(lineCurrentPos + 1); if (lParam == 0) { return 1 + lineEnd - lineStart; } PLATFORM_ASSERT(wParam > 0); char *ptr = CharPtrFromSPtr(lParam); unsigned int iPlace = 0; for (unsigned int iChar = lineStart; iChar < lineEnd && iPlace < wParam - 1; iChar++) { ptr[iPlace++] = pdoc->CharAt(iChar); } ptr[iPlace] = '\0'; return sel.MainCaret() - lineStart; } case SCI_GETENDSTYLED: return pdoc->GetEndStyled(); case SCI_GETEOLMODE: return pdoc->eolMode; case SCI_SETEOLMODE: pdoc->eolMode = wParam; break; case SCI_SETLINEENDTYPESALLOWED: if (pdoc->SetLineEndTypesAllowed(wParam)) { cs.Clear(); cs.InsertLines(0, pdoc->LinesTotal() - 1); SetAnnotationHeights(0, pdoc->LinesTotal()); InvalidateStyleRedraw(); } break; case SCI_GETLINEENDTYPESALLOWED: return pdoc->GetLineEndTypesAllowed(); case SCI_GETLINEENDTYPESACTIVE: return pdoc->GetLineEndTypesActive(); case SCI_STARTSTYLING: pdoc->StartStyling(wParam, static_cast<char>(lParam)); break; case SCI_SETSTYLING: pdoc->SetStyleFor(wParam, static_cast<char>(lParam)); break; case SCI_SETSTYLINGEX: // Specify a complete styling buffer if (lParam == 0) return 0; pdoc->SetStyles(wParam, CharPtrFromSPtr(lParam)); break; case SCI_SETBUFFEREDDRAW: bufferedDraw = wParam != 0; break; case SCI_GETBUFFEREDDRAW: return bufferedDraw; case SCI_GETTWOPHASEDRAW: return twoPhaseDraw; case SCI_SETTWOPHASEDRAW: twoPhaseDraw = wParam != 0; InvalidateStyleRedraw(); break; case SCI_SETFONTQUALITY: vs.extraFontFlag &= ~SC_EFF_QUALITY_MASK; vs.extraFontFlag |= (wParam & SC_EFF_QUALITY_MASK); InvalidateStyleRedraw(); break; case SCI_GETFONTQUALITY: return (vs.extraFontFlag & SC_EFF_QUALITY_MASK); case SCI_SETTABWIDTH: if (wParam > 0) { pdoc->tabInChars = wParam; if (pdoc->indentInChars == 0) pdoc->actualIndentInChars = pdoc->tabInChars; } InvalidateStyleRedraw(); break; case SCI_GETTABWIDTH: return pdoc->tabInChars; case SCI_SETINDENT: pdoc->indentInChars = wParam; if (pdoc->indentInChars != 0) pdoc->actualIndentInChars = pdoc->indentInChars; else pdoc->actualIndentInChars = pdoc->tabInChars; InvalidateStyleRedraw(); break; case SCI_GETINDENT: return pdoc->indentInChars; case SCI_SETUSETABS: pdoc->useTabs = wParam != 0; InvalidateStyleRedraw(); break; case SCI_GETUSETABS: return pdoc->useTabs; case SCI_SETLINEINDENTATION: pdoc->SetLineIndentation(wParam, lParam); break; case SCI_GETLINEINDENTATION: return pdoc->GetLineIndentation(wParam); case SCI_GETLINEINDENTPOSITION: return pdoc->GetLineIndentPosition(wParam); case SCI_SETTABINDENTS: pdoc->tabIndents = wParam != 0; break; case SCI_GETTABINDENTS: return pdoc->tabIndents; case SCI_SETBACKSPACEUNINDENTS: pdoc->backspaceUnindents = wParam != 0; break; case SCI_GETBACKSPACEUNINDENTS: return pdoc->backspaceUnindents; case SCI_SETMOUSEDWELLTIME: dwellDelay = wParam; ticksToDwell = dwellDelay; break; case SCI_GETMOUSEDWELLTIME: return dwellDelay; case SCI_WORDSTARTPOSITION: return pdoc->ExtendWordSelect(wParam, -1, lParam != 0); case SCI_WORDENDPOSITION: return pdoc->ExtendWordSelect(wParam, 1, lParam != 0); case SCI_SETWRAPMODE: switch (wParam) { case SC_WRAP_WORD: wrapState = eWrapWord; break; case SC_WRAP_CHAR: wrapState = eWrapChar; break; default: wrapState = eWrapNone; break; } xOffset = 0; ContainerNeedsUpdate(SC_UPDATE_H_SCROLL); InvalidateStyleRedraw(); ReconfigureScrollBars(); break; case SCI_GETWRAPMODE: return wrapState; case SCI_SETWRAPVISUALFLAGS: if (wrapVisualFlags != static_cast<int>(wParam)) { wrapVisualFlags = wParam; InvalidateStyleRedraw(); ReconfigureScrollBars(); } break; case SCI_GETWRAPVISUALFLAGS: return wrapVisualFlags; case SCI_SETWRAPVISUALFLAGSLOCATION: wrapVisualFlagsLocation = wParam; InvalidateStyleRedraw(); break; case SCI_GETWRAPVISUALFLAGSLOCATION: return wrapVisualFlagsLocation; case SCI_SETWRAPSTARTINDENT: if (wrapVisualStartIndent != static_cast<int>(wParam)) { wrapVisualStartIndent = wParam; InvalidateStyleRedraw(); ReconfigureScrollBars(); } break; case SCI_GETWRAPSTARTINDENT: return wrapVisualStartIndent; case SCI_SETWRAPINDENTMODE: if (wrapIndentMode != static_cast<int>(wParam)) { wrapIndentMode = wParam; InvalidateStyleRedraw(); ReconfigureScrollBars(); } break; case SCI_GETWRAPINDENTMODE: return wrapIndentMode; case SCI_SETLAYOUTCACHE: llc.SetLevel(wParam); break; case SCI_GETLAYOUTCACHE: return llc.GetLevel(); case SCI_SETPOSITIONCACHE: posCache.SetSize(wParam); break; case SCI_GETPOSITIONCACHE: return posCache.GetSize(); case SCI_SETSCROLLWIDTH: PLATFORM_ASSERT(wParam > 0); if ((wParam > 0) && (wParam != static_cast<unsigned int >(scrollWidth))) { lineWidthMaxSeen = 0; scrollWidth = wParam; SetScrollBars(); } break; case SCI_GETSCROLLWIDTH: return scrollWidth; case SCI_SETSCROLLWIDTHTRACKING: trackLineWidth = wParam != 0; break; case SCI_GETSCROLLWIDTHTRACKING: return trackLineWidth; case SCI_LINESJOIN: LinesJoin(); break; case SCI_LINESSPLIT: LinesSplit(wParam); break; case SCI_TEXTWIDTH: PLATFORM_ASSERT(wParam < vs.stylesSize); PLATFORM_ASSERT(lParam); return TextWidth(wParam, CharPtrFromSPtr(lParam)); case SCI_TEXTHEIGHT: return vs.lineHeight; case SCI_SETENDATLASTLINE: PLATFORM_ASSERT((wParam == 0) || (wParam == 1)); if (endAtLastLine != (wParam != 0)) { endAtLastLine = wParam != 0; SetScrollBars(); } break; case SCI_GETENDATLASTLINE: return endAtLastLine; case SCI_SETCARETSTICKY: PLATFORM_ASSERT(wParam <= SC_CARETSTICKY_WHITESPACE); if (wParam <= SC_CARETSTICKY_WHITESPACE) { caretSticky = wParam; } break; case SCI_GETCARETSTICKY: return caretSticky; case SCI_TOGGLECARETSTICKY: caretSticky = !caretSticky; break; case SCI_GETCOLUMN: return pdoc->GetColumn(wParam); case SCI_FINDCOLUMN: return pdoc->FindColumn(wParam, lParam); case SCI_SETHSCROLLBAR : if (horizontalScrollBarVisible != (wParam != 0)) { horizontalScrollBarVisible = wParam != 0; SetScrollBars(); ReconfigureScrollBars(); } break; case SCI_GETHSCROLLBAR: return horizontalScrollBarVisible; case SCI_SETVSCROLLBAR: if (verticalScrollBarVisible != (wParam != 0)) { verticalScrollBarVisible = wParam != 0; SetScrollBars(); ReconfigureScrollBars(); if (verticalScrollBarVisible) SetVerticalScrollPos(); } break; case SCI_GETVSCROLLBAR: return verticalScrollBarVisible; case SCI_SETINDENTATIONGUIDES: vs.viewIndentationGuides = IndentView(wParam); Redraw(); break; case SCI_GETINDENTATIONGUIDES: return vs.viewIndentationGuides; case SCI_SETHIGHLIGHTGUIDE: if ((highlightGuideColumn != static_cast<int>(wParam)) || (wParam > 0)) { highlightGuideColumn = wParam; Redraw(); } break; case SCI_GETHIGHLIGHTGUIDE: return highlightGuideColumn; case SCI_GETLINEENDPOSITION: return pdoc->LineEnd(wParam); case SCI_SETCODEPAGE: if (ValidCodePage(wParam)) { if (pdoc->SetDBCSCodePage(wParam)) { cs.Clear(); cs.InsertLines(0, pdoc->LinesTotal() - 1); SetAnnotationHeights(0, pdoc->LinesTotal()); InvalidateStyleRedraw(); } } break; case SCI_GETCODEPAGE: return pdoc->dbcsCodePage; #ifdef INCLUDE_DEPRECATED_FEATURES case SCI_SETUSEPALETTE: InvalidateStyleRedraw(); break; case SCI_GETUSEPALETTE: return 0; #endif // Marker definition and setting case SCI_MARKERDEFINE: if (wParam <= MARKER_MAX) { vs.markers[wParam].markType = lParam; vs.CalcLargestMarkerHeight(); } InvalidateStyleData(); RedrawSelMargin(); break; case SCI_MARKERSYMBOLDEFINED: if (wParam <= MARKER_MAX) return vs.markers[wParam].markType; else return 0; case SCI_MARKERSETFORE: if (wParam <= MARKER_MAX) vs.markers[wParam].fore = ColourDesired(lParam); InvalidateStyleData(); RedrawSelMargin(); break; case SCI_MARKERSETBACKSELECTED: if (wParam <= MARKER_MAX) vs.markers[wParam].backSelected = ColourDesired(lParam); InvalidateStyleData(); RedrawSelMargin(); break; case SCI_MARKERENABLEHIGHLIGHT: highlightDelimiter.isEnabled = wParam == 1; RedrawSelMargin(); break; case SCI_MARKERSETBACK: if (wParam <= MARKER_MAX) vs.markers[wParam].back = ColourDesired(lParam); InvalidateStyleData(); RedrawSelMargin(); break; case SCI_MARKERSETALPHA: if (wParam <= MARKER_MAX) vs.markers[wParam].alpha = lParam; InvalidateStyleRedraw(); break; case SCI_MARKERADD: { int markerID = pdoc->AddMark(wParam, lParam); return markerID; } case SCI_MARKERADDSET: if (lParam != 0) pdoc->AddMarkSet(wParam, lParam); break; case SCI_MARKERDELETE: pdoc->DeleteMark(wParam, lParam); break; case SCI_MARKERDELETEALL: pdoc->DeleteAllMarks(static_cast<int>(wParam)); break; case SCI_MARKERGET: return pdoc->GetMark(wParam); case SCI_MARKERNEXT: return pdoc->MarkerNext(wParam, lParam); case SCI_MARKERPREVIOUS: { for (int iLine = wParam; iLine >= 0; iLine--) { if ((pdoc->GetMark(iLine) & lParam) != 0) return iLine; } } return -1; case SCI_MARKERDEFINEPIXMAP: if (wParam <= MARKER_MAX) { vs.markers[wParam].SetXPM(CharPtrFromSPtr(lParam)); vs.CalcLargestMarkerHeight(); }; InvalidateStyleData(); RedrawSelMargin(); break; case SCI_RGBAIMAGESETWIDTH: sizeRGBAImage.x = wParam; break; case SCI_RGBAIMAGESETHEIGHT: sizeRGBAImage.y = wParam; break; case SCI_RGBAIMAGESETSCALE: scaleRGBAImage = wParam; break; case SCI_MARKERDEFINERGBAIMAGE: if (wParam <= MARKER_MAX) { vs.markers[wParam].SetRGBAImage(sizeRGBAImage, scaleRGBAImage / 100.0, reinterpret_cast<unsigned char *>(lParam)); vs.CalcLargestMarkerHeight(); }; InvalidateStyleData(); RedrawSelMargin(); break; case SCI_SETMARGINTYPEN: if (ValidMargin(wParam)) { vs.ms[wParam].style = lParam; InvalidateStyleRedraw(); } break; case SCI_GETMARGINTYPEN: if (ValidMargin(wParam)) return vs.ms[wParam].style; else return 0; case SCI_SETMARGINWIDTHN: if (ValidMargin(wParam)) { // Short-circuit if the width is unchanged, to avoid unnecessary redraw. if (vs.ms[wParam].width != lParam) { vs.ms[wParam].width = lParam; InvalidateStyleRedraw(); } } break; case SCI_GETMARGINWIDTHN: if (ValidMargin(wParam)) return vs.ms[wParam].width; else return 0; case SCI_SETMARGINMASKN: if (ValidMargin(wParam)) { vs.ms[wParam].mask = lParam; InvalidateStyleRedraw(); } break; case SCI_GETMARGINMASKN: if (ValidMargin(wParam)) return vs.ms[wParam].mask; else return 0; case SCI_SETMARGINSENSITIVEN: if (ValidMargin(wParam)) { vs.ms[wParam].sensitive = lParam != 0; InvalidateStyleRedraw(); } break; case SCI_GETMARGINSENSITIVEN: if (ValidMargin(wParam)) return vs.ms[wParam].sensitive ? 1 : 0; else return 0; case SCI_SETMARGINCURSORN: if (ValidMargin(wParam)) vs.ms[wParam].cursor = lParam; break; case SCI_GETMARGINCURSORN: if (ValidMargin(wParam)) return vs.ms[wParam].cursor; else return 0; case SCI_STYLECLEARALL: vs.ClearStyles(); InvalidateStyleRedraw(); break; case SCI_STYLESETFORE: case SCI_STYLESETBACK: case SCI_STYLESETBOLD: case SCI_STYLESETWEIGHT: case SCI_STYLESETITALIC: case SCI_STYLESETEOLFILLED: case SCI_STYLESETSIZE: case SCI_STYLESETSIZEFRACTIONAL: case SCI_STYLESETFONT: case SCI_STYLESETUNDERLINE: case SCI_STYLESETCASE: case SCI_STYLESETCHARACTERSET: case SCI_STYLESETVISIBLE: case SCI_STYLESETCHANGEABLE: case SCI_STYLESETHOTSPOT: StyleSetMessage(iMessage, wParam, lParam); break; case SCI_STYLEGETFORE: case SCI_STYLEGETBACK: case SCI_STYLEGETBOLD: case SCI_STYLEGETWEIGHT: case SCI_STYLEGETITALIC: case SCI_STYLEGETEOLFILLED: case SCI_STYLEGETSIZE: case SCI_STYLEGETSIZEFRACTIONAL: case SCI_STYLEGETFONT: case SCI_STYLEGETUNDERLINE: case SCI_STYLEGETCASE: case SCI_STYLEGETCHARACTERSET: case SCI_STYLEGETVISIBLE: case SCI_STYLEGETCHANGEABLE: case SCI_STYLEGETHOTSPOT: return StyleGetMessage(iMessage, wParam, lParam); case SCI_STYLERESETDEFAULT: vs.ResetDefaultStyle(); InvalidateStyleRedraw(); break; case SCI_SETSTYLEBITS: vs.EnsureStyle((1 << wParam) - 1); pdoc->SetStylingBits(wParam); break; case SCI_GETSTYLEBITS: return pdoc->stylingBits; case SCI_SETLINESTATE: return pdoc->SetLineState(wParam, lParam); case SCI_GETLINESTATE: return pdoc->GetLineState(wParam); case SCI_GETMAXLINESTATE: return pdoc->GetMaxLineState(); case SCI_GETCARETLINEVISIBLE: return vs.showCaretLineBackground; case SCI_SETCARETLINEVISIBLE: vs.showCaretLineBackground = wParam != 0; InvalidateStyleRedraw(); break; case SCI_GETCARETLINEVISIBLEALWAYS: return vs.alwaysShowCaretLineBackground; case SCI_SETCARETLINEVISIBLEALWAYS: vs.alwaysShowCaretLineBackground = wParam != 0; InvalidateStyleRedraw(); break; case SCI_GETCARETLINEBACK: return vs.caretLineBackground.AsLong(); case SCI_SETCARETLINEBACK: vs.caretLineBackground = wParam; InvalidateStyleRedraw(); break; case SCI_GETCARETLINEBACKALPHA: return vs.caretLineAlpha; case SCI_SETCARETLINEBACKALPHA: vs.caretLineAlpha = wParam; InvalidateStyleRedraw(); break; // Folding messages case SCI_VISIBLEFROMDOCLINE: return cs.DisplayFromDoc(wParam); case SCI_DOCLINEFROMVISIBLE: return cs.DocFromDisplay(wParam); case SCI_WRAPCOUNT: return WrapCount(wParam); case SCI_SETFOLDLEVEL: { int prev = pdoc->SetLevel(wParam, lParam); if (prev != lParam) RedrawSelMargin(); return prev; } case SCI_GETFOLDLEVEL: return pdoc->GetLevel(wParam); case SCI_GETLASTCHILD: return pdoc->GetLastChild(wParam, lParam); case SCI_GETFOLDPARENT: return pdoc->GetFoldParent(wParam); case SCI_SHOWLINES: cs.SetVisible(wParam, lParam, true); SetScrollBars(); Redraw(); break; case SCI_HIDELINES: if (wParam > 0) cs.SetVisible(wParam, lParam, false); SetScrollBars(); Redraw(); break; case SCI_GETLINEVISIBLE: return cs.GetVisible(wParam); case SCI_GETALLLINESVISIBLE: return cs.HiddenLines() ? 0 : 1; case SCI_SETFOLDEXPANDED: if (cs.SetExpanded(wParam, lParam != 0)) { RedrawSelMargin(); } break; case SCI_GETFOLDEXPANDED: return cs.GetExpanded(wParam); case SCI_SETFOLDFLAGS: foldFlags = wParam; Redraw(); break; case SCI_TOGGLEFOLD: ToggleContraction(wParam); break; case SCI_CONTRACTEDFOLDNEXT: return ContractedFoldNext(wParam); case SCI_ENSUREVISIBLE: EnsureLineVisible(wParam, false); break; case SCI_ENSUREVISIBLEENFORCEPOLICY: EnsureLineVisible(wParam, true); break; case SCI_SCROLLRANGE: ScrollRange(SelectionRange(lParam, wParam)); break; case SCI_SEARCHANCHOR: SearchAnchor(); break; case SCI_SEARCHNEXT: case SCI_SEARCHPREV: return SearchText(iMessage, wParam, lParam); case SCI_SETXCARETPOLICY: caretXPolicy = wParam; caretXSlop = lParam; break; case SCI_SETYCARETPOLICY: caretYPolicy = wParam; caretYSlop = lParam; break; case SCI_SETVISIBLEPOLICY: visiblePolicy = wParam; visibleSlop = lParam; break; case SCI_LINESONSCREEN: return LinesOnScreen(); case SCI_SETSELFORE: vs.selforeset = wParam != 0; vs.selforeground = ColourDesired(lParam); vs.selAdditionalForeground = ColourDesired(lParam); InvalidateStyleRedraw(); break; case SCI_SETSELBACK: vs.selbackset = wParam != 0; vs.selbackground = ColourDesired(lParam); vs.selAdditionalBackground = ColourDesired(lParam); InvalidateStyleRedraw(); break; case SCI_SETSELALPHA: vs.selAlpha = wParam; vs.selAdditionalAlpha = wParam; InvalidateStyleRedraw(); break; case SCI_GETSELALPHA: return vs.selAlpha; case SCI_GETSELEOLFILLED: return vs.selEOLFilled; case SCI_SETSELEOLFILLED: vs.selEOLFilled = wParam != 0; InvalidateStyleRedraw(); break; case SCI_SETWHITESPACEFORE: vs.whitespaceForegroundSet = wParam != 0; vs.whitespaceForeground = ColourDesired(lParam); InvalidateStyleRedraw(); break; case SCI_SETWHITESPACEBACK: vs.whitespaceBackgroundSet = wParam != 0; vs.whitespaceBackground = ColourDesired(lParam); InvalidateStyleRedraw(); break; case SCI_SETCARETFORE: vs.caretcolour = ColourDesired(wParam); InvalidateStyleRedraw(); break; case SCI_GETCARETFORE: return vs.caretcolour.AsLong(); case SCI_SETCARETSTYLE: if (wParam <= CARETSTYLE_BLOCK) vs.caretStyle = wParam; else /* Default to the line caret */ vs.caretStyle = CARETSTYLE_LINE; InvalidateStyleRedraw(); break; case SCI_GETCARETSTYLE: return vs.caretStyle; case SCI_SETCARETWIDTH: if (static_cast<int>(wParam) <= 0) vs.caretWidth = 0; else if (wParam >= 3) vs.caretWidth = 3; else vs.caretWidth = wParam; InvalidateStyleRedraw(); break; case SCI_GETCARETWIDTH: return vs.caretWidth; case SCI_ASSIGNCMDKEY: kmap.AssignCmdKey(Platform::LowShortFromLong(wParam), Platform::HighShortFromLong(wParam), lParam); break; case SCI_CLEARCMDKEY: kmap.AssignCmdKey(Platform::LowShortFromLong(wParam), Platform::HighShortFromLong(wParam), SCI_NULL); break; case SCI_CLEARALLCMDKEYS: kmap.Clear(); break; case SCI_INDICSETSTYLE: if (wParam <= INDIC_MAX) { vs.indicators[wParam].style = lParam; InvalidateStyleRedraw(); } break; case SCI_INDICGETSTYLE: return (wParam <= INDIC_MAX) ? vs.indicators[wParam].style : 0; case SCI_INDICSETFORE: if (wParam <= INDIC_MAX) { vs.indicators[wParam].fore = ColourDesired(lParam); InvalidateStyleRedraw(); } break; case SCI_INDICGETFORE: return (wParam <= INDIC_MAX) ? vs.indicators[wParam].fore.AsLong() : 0; case SCI_INDICSETUNDER: if (wParam <= INDIC_MAX) { vs.indicators[wParam].under = lParam != 0; InvalidateStyleRedraw(); } break; case SCI_INDICGETUNDER: return (wParam <= INDIC_MAX) ? vs.indicators[wParam].under : 0; case SCI_INDICSETALPHA: if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 255) { vs.indicators[wParam].fillAlpha = lParam; InvalidateStyleRedraw(); } break; case SCI_INDICGETALPHA: return (wParam <= INDIC_MAX) ? vs.indicators[wParam].fillAlpha : 0; case SCI_INDICSETOUTLINEALPHA: if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 255) { vs.indicators[wParam].outlineAlpha = lParam; InvalidateStyleRedraw(); } break; case SCI_INDICGETOUTLINEALPHA: return (wParam <= INDIC_MAX) ? vs.indicators[wParam].outlineAlpha : 0; case SCI_SETINDICATORCURRENT: pdoc->decorations.SetCurrentIndicator(wParam); break; case SCI_GETINDICATORCURRENT: return pdoc->decorations.GetCurrentIndicator(); case SCI_SETINDICATORVALUE: pdoc->decorations.SetCurrentValue(wParam); break; case SCI_GETINDICATORVALUE: return pdoc->decorations.GetCurrentValue(); case SCI_INDICATORFILLRANGE: pdoc->DecorationFillRange(wParam, pdoc->decorations.GetCurrentValue(), lParam); break; case SCI_INDICATORCLEARRANGE: pdoc->DecorationFillRange(wParam, 0, lParam); break; case SCI_INDICATORALLONFOR: return pdoc->decorations.AllOnFor(wParam); case SCI_INDICATORVALUEAT: return pdoc->decorations.ValueAt(wParam, lParam); case SCI_INDICATORSTART: return pdoc->decorations.Start(wParam, lParam); case SCI_INDICATOREND: return pdoc->decorations.End(wParam, lParam); case SCI_LINEDOWN: case SCI_LINEDOWNEXTEND: case SCI_PARADOWN: case SCI_PARADOWNEXTEND: case SCI_LINEUP: case SCI_LINEUPEXTEND: case SCI_PARAUP: case SCI_PARAUPEXTEND: case SCI_CHARLEFT: case SCI_CHARLEFTEXTEND: case SCI_CHARRIGHT: case SCI_CHARRIGHTEXTEND: case SCI_WORDLEFT: case SCI_WORDLEFTEXTEND: case SCI_WORDRIGHT: case SCI_WORDRIGHTEXTEND: case SCI_WORDLEFTEND: case SCI_WORDLEFTENDEXTEND: case SCI_WORDRIGHTEND: case SCI_WORDRIGHTENDEXTEND: case SCI_HOME: case SCI_HOMEEXTEND: case SCI_LINEEND: case SCI_LINEENDEXTEND: case SCI_HOMEWRAP: case SCI_HOMEWRAPEXTEND: case SCI_LINEENDWRAP: case SCI_LINEENDWRAPEXTEND: case SCI_DOCUMENTSTART: case SCI_DOCUMENTSTARTEXTEND: case SCI_DOCUMENTEND: case SCI_DOCUMENTENDEXTEND: case SCI_SCROLLTOSTART: case SCI_SCROLLTOEND: case SCI_STUTTEREDPAGEUP: case SCI_STUTTEREDPAGEUPEXTEND: case SCI_STUTTEREDPAGEDOWN: case SCI_STUTTEREDPAGEDOWNEXTEND: case SCI_PAGEUP: case SCI_PAGEUPEXTEND: case SCI_PAGEDOWN: case SCI_PAGEDOWNEXTEND: case SCI_EDITTOGGLEOVERTYPE: case SCI_CANCEL: case SCI_DELETEBACK: case SCI_TAB: case SCI_BACKTAB: case SCI_NEWLINE: case SCI_FORMFEED: case SCI_VCHOME: case SCI_VCHOMEEXTEND: case SCI_VCHOMEWRAP: case SCI_VCHOMEWRAPEXTEND: case SCI_VCHOMEDISPLAY: case SCI_VCHOMEDISPLAYEXTEND: case SCI_ZOOMIN: case SCI_ZOOMOUT: case SCI_DELWORDLEFT: case SCI_DELWORDRIGHT: case SCI_DELWORDRIGHTEND: case SCI_DELLINELEFT: case SCI_DELLINERIGHT: case SCI_LINECOPY: case SCI_LINECUT: case SCI_LINEDELETE: case SCI_LINETRANSPOSE: case SCI_LINEDUPLICATE: case SCI_LOWERCASE: case SCI_UPPERCASE: case SCI_LINESCROLLDOWN: case SCI_LINESCROLLUP: case SCI_WORDPARTLEFT: case SCI_WORDPARTLEFTEXTEND: case SCI_WORDPARTRIGHT: case SCI_WORDPARTRIGHTEXTEND: case SCI_DELETEBACKNOTLINE: case SCI_HOMEDISPLAY: case SCI_HOMEDISPLAYEXTEND: case SCI_LINEENDDISPLAY: case SCI_LINEENDDISPLAYEXTEND: case SCI_LINEDOWNRECTEXTEND: case SCI_LINEUPRECTEXTEND: case SCI_CHARLEFTRECTEXTEND: case SCI_CHARRIGHTRECTEXTEND: case SCI_HOMERECTEXTEND: case SCI_VCHOMERECTEXTEND: case SCI_LINEENDRECTEXTEND: case SCI_PAGEUPRECTEXTEND: case SCI_PAGEDOWNRECTEXTEND: case SCI_SELECTIONDUPLICATE: return KeyCommand(iMessage); case SCI_BRACEHIGHLIGHT: SetBraceHighlight(static_cast<int>(wParam), lParam, STYLE_BRACELIGHT); break; case SCI_BRACEHIGHLIGHTINDICATOR: if (lParam >= 0 && lParam <= INDIC_MAX) { vs.braceHighlightIndicatorSet = wParam != 0; vs.braceHighlightIndicator = lParam; } break; case SCI_BRACEBADLIGHT: SetBraceHighlight(static_cast<int>(wParam), -1, STYLE_BRACEBAD); break; case SCI_BRACEBADLIGHTINDICATOR: if (lParam >= 0 && lParam <= INDIC_MAX) { vs.braceBadLightIndicatorSet = wParam != 0; vs.braceBadLightIndicator = lParam; } break; case SCI_BRACEMATCH: // wParam is position of char to find brace for, // lParam is maximum amount of text to restyle to find it return pdoc->BraceMatch(wParam, lParam); case SCI_GETVIEWEOL: return vs.viewEOL; case SCI_SETVIEWEOL: vs.viewEOL = wParam != 0; InvalidateStyleRedraw(); break; case SCI_SETZOOM: vs.zoomLevel = wParam; InvalidateStyleRedraw(); NotifyZoom(); break; case SCI_GETZOOM: return vs.zoomLevel; case SCI_GETEDGECOLUMN: return theEdge; case SCI_SETEDGECOLUMN: theEdge = wParam; InvalidateStyleRedraw(); break; case SCI_GETEDGEMODE: return vs.edgeState; case SCI_SETEDGEMODE: vs.edgeState = wParam; InvalidateStyleRedraw(); break; case SCI_GETEDGECOLOUR: return vs.edgecolour.AsLong(); case SCI_SETEDGECOLOUR: vs.edgecolour = ColourDesired(wParam); InvalidateStyleRedraw(); break; case SCI_GETDOCPOINTER: return reinterpret_cast<sptr_t>(pdoc); case SCI_SETDOCPOINTER: CancelModes(); SetDocPointer(reinterpret_cast<Document *>(lParam)); return 0; case SCI_CREATEDOCUMENT: { Document *doc = new Document(); if (doc) { doc->AddRef(); } return reinterpret_cast<sptr_t>(doc); } case SCI_ADDREFDOCUMENT: (reinterpret_cast<Document *>(lParam))->AddRef(); break; case SCI_RELEASEDOCUMENT: (reinterpret_cast<Document *>(lParam))->Release(); break; case SCI_CREATELOADER: { Document *doc = new Document(); if (doc) { doc->AddRef(); doc->Allocate(wParam); doc->SetUndoCollection(false); } return reinterpret_cast<sptr_t>(static_cast<ILoader *>(doc)); } case SCI_SETMODEVENTMASK: modEventMask = wParam; return 0; case SCI_GETMODEVENTMASK: return modEventMask; case SCI_CONVERTEOLS: pdoc->ConvertLineEnds(wParam); SetSelection(sel.MainCaret(), sel.MainAnchor()); // Ensure selection inside document return 0; case SCI_SETLENGTHFORENCODE: lengthForEncode = wParam; return 0; case SCI_SELECTIONISRECTANGLE: return sel.selType == Selection::selRectangle ? 1 : 0; case SCI_SETSELECTIONMODE: { switch (wParam) { case SC_SEL_STREAM: sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selStream)); sel.selType = Selection::selStream; break; case SC_SEL_RECTANGLE: sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selRectangle)); sel.selType = Selection::selRectangle; break; case SC_SEL_LINES: sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selLines)); sel.selType = Selection::selLines; break; case SC_SEL_THIN: sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selThin)); sel.selType = Selection::selThin; break; default: sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selStream)); sel.selType = Selection::selStream; } InvalidateSelection(sel.RangeMain(), true); } case SCI_GETSELECTIONMODE: switch (sel.selType) { case Selection::selStream: return SC_SEL_STREAM; case Selection::selRectangle: return SC_SEL_RECTANGLE; case Selection::selLines: return SC_SEL_LINES; case Selection::selThin: return SC_SEL_THIN; default: // ?! return SC_SEL_STREAM; } case SCI_GETLINESELSTARTPOSITION: case SCI_GETLINESELENDPOSITION: { SelectionSegment segmentLine(SelectionPosition(pdoc->LineStart(wParam)), SelectionPosition(pdoc->LineEnd(wParam))); for (size_t r=0; r<sel.Count(); r++) { SelectionSegment portion = sel.Range(r).Intersect(segmentLine); if (portion.start.IsValid()) { return (iMessage == SCI_GETLINESELSTARTPOSITION) ? portion.start.Position() : portion.end.Position(); } } return INVALID_POSITION; } case SCI_SETOVERTYPE: inOverstrike = wParam != 0; break; case SCI_GETOVERTYPE: return inOverstrike ? 1 : 0; case SCI_SETFOCUS: SetFocusState(wParam != 0); break; case SCI_GETFOCUS: return hasFocus; case SCI_SETSTATUS: errorStatus = wParam; break; case SCI_GETSTATUS: return errorStatus; case SCI_SETMOUSEDOWNCAPTURES: mouseDownCaptures = wParam != 0; break; case SCI_GETMOUSEDOWNCAPTURES: return mouseDownCaptures; case SCI_SETCURSOR: cursorMode = wParam; DisplayCursor(Window::cursorText); break; case SCI_GETCURSOR: return cursorMode; case SCI_SETCONTROLCHARSYMBOL: controlCharSymbol = wParam; break; case SCI_GETCONTROLCHARSYMBOL: return controlCharSymbol; case SCI_STARTRECORD: recordingMacro = true; return 0; case SCI_STOPRECORD: recordingMacro = false; return 0; case SCI_MOVECARETINSIDEVIEW: MoveCaretInsideView(); break; case SCI_SETFOLDMARGINCOLOUR: vs.foldmarginColourSet = wParam != 0; vs.foldmarginColour = ColourDesired(lParam); InvalidateStyleRedraw(); break; case SCI_SETFOLDMARGINHICOLOUR: vs.foldmarginHighlightColourSet = wParam != 0; vs.foldmarginHighlightColour = ColourDesired(lParam); InvalidateStyleRedraw(); break; case SCI_SETHOTSPOTACTIVEFORE: vs.hotspotForegroundSet = wParam != 0; vs.hotspotForeground = ColourDesired(lParam); InvalidateStyleRedraw(); break; case SCI_GETHOTSPOTACTIVEFORE: return vs.hotspotForeground.AsLong(); case SCI_SETHOTSPOTACTIVEBACK: vs.hotspotBackgroundSet = wParam != 0; vs.hotspotBackground = ColourDesired(lParam); InvalidateStyleRedraw(); break; case SCI_GETHOTSPOTACTIVEBACK: return vs.hotspotBackground.AsLong(); case SCI_SETHOTSPOTACTIVEUNDERLINE: vs.hotspotUnderline = wParam != 0; InvalidateStyleRedraw(); break; case SCI_GETHOTSPOTACTIVEUNDERLINE: return vs.hotspotUnderline ? 1 : 0; case SCI_SETHOTSPOTSINGLELINE: vs.hotspotSingleLine = wParam != 0; InvalidateStyleRedraw(); break; case SCI_GETHOTSPOTSINGLELINE: return vs.hotspotSingleLine ? 1 : 0; case SCI_SETPASTECONVERTENDINGS: convertPastes = wParam != 0; break; case SCI_GETPASTECONVERTENDINGS: return convertPastes ? 1 : 0; case SCI_GETCHARACTERPOINTER: return reinterpret_cast<sptr_t>(pdoc->BufferPointer()); case SCI_GETRANGEPOINTER: return reinterpret_cast<sptr_t>(pdoc->RangePointer(wParam, lParam)); case SCI_GETGAPPOSITION: return pdoc->GapPosition(); case SCI_SETEXTRAASCENT: vs.extraAscent = wParam; InvalidateStyleRedraw(); break; case SCI_GETEXTRAASCENT: return vs.extraAscent; case SCI_SETEXTRADESCENT: vs.extraDescent = wParam; InvalidateStyleRedraw(); break; case SCI_GETEXTRADESCENT: return vs.extraDescent; case SCI_MARGINSETSTYLEOFFSET: vs.marginStyleOffset = wParam; InvalidateStyleRedraw(); break; case SCI_MARGINGETSTYLEOFFSET: return vs.marginStyleOffset; case SCI_SETMARGINOPTIONS: marginOptions = wParam; break; case SCI_GETMARGINOPTIONS: return marginOptions; case SCI_MARGINSETTEXT: pdoc->MarginSetText(wParam, CharPtrFromSPtr(lParam)); break; case SCI_MARGINGETTEXT: { const StyledText st = pdoc->MarginStyledText(wParam); if (lParam) { if (st.text) memcpy(CharPtrFromSPtr(lParam), st.text, st.length); else strcpy(CharPtrFromSPtr(lParam), ""); } return st.length; } case SCI_MARGINSETSTYLE: pdoc->MarginSetStyle(wParam, lParam); break; case SCI_MARGINGETSTYLE: { const StyledText st = pdoc->MarginStyledText(wParam); return st.style; } case SCI_MARGINSETSTYLES: pdoc->MarginSetStyles(wParam, reinterpret_cast<const unsigned char *>(lParam)); break; case SCI_MARGINGETSTYLES: { const StyledText st = pdoc->MarginStyledText(wParam); if (lParam) { if (st.styles) memcpy(CharPtrFromSPtr(lParam), st.styles, st.length); else strcpy(CharPtrFromSPtr(lParam), ""); } return st.styles ? st.length : 0; } case SCI_MARGINTEXTCLEARALL: pdoc->MarginClearAll(); break; case SCI_ANNOTATIONSETTEXT: pdoc->AnnotationSetText(wParam, CharPtrFromSPtr(lParam)); break; case SCI_ANNOTATIONGETTEXT: { const StyledText st = pdoc->AnnotationStyledText(wParam); if (lParam) { if (st.text) memcpy(CharPtrFromSPtr(lParam), st.text, st.length); else strcpy(CharPtrFromSPtr(lParam), ""); } return st.length; } case SCI_ANNOTATIONGETSTYLE: { const StyledText st = pdoc->AnnotationStyledText(wParam); return st.style; } case SCI_ANNOTATIONSETSTYLE: pdoc->AnnotationSetStyle(wParam, lParam); break; case SCI_ANNOTATIONSETSTYLES: pdoc->AnnotationSetStyles(wParam, reinterpret_cast<const unsigned char *>(lParam)); break; case SCI_ANNOTATIONGETSTYLES: { const StyledText st = pdoc->AnnotationStyledText(wParam); if (lParam) { if (st.styles) memcpy(CharPtrFromSPtr(lParam), st.styles, st.length); else strcpy(CharPtrFromSPtr(lParam), ""); } return st.styles ? st.length : 0; } case SCI_ANNOTATIONGETLINES: return pdoc->AnnotationLines(wParam); case SCI_ANNOTATIONCLEARALL: pdoc->AnnotationClearAll(); break; case SCI_ANNOTATIONSETVISIBLE: SetAnnotationVisible(wParam); break; case SCI_ANNOTATIONGETVISIBLE: return vs.annotationVisible; case SCI_ANNOTATIONSETSTYLEOFFSET: vs.annotationStyleOffset = wParam; InvalidateStyleRedraw(); break; case SCI_ANNOTATIONGETSTYLEOFFSET: return vs.annotationStyleOffset; case SCI_RELEASEALLEXTENDEDSTYLES: vs.ReleaseAllExtendedStyles(); break; case SCI_ALLOCATEEXTENDEDSTYLES: return vs.AllocateExtendedStyles(wParam); case SCI_ADDUNDOACTION: pdoc->AddUndoAction(wParam, lParam & UNDO_MAY_COALESCE); break; case SCI_SETMULTIPLESELECTION: multipleSelection = wParam != 0; InvalidateCaret(); break; case SCI_GETMULTIPLESELECTION: return multipleSelection; case SCI_SETADDITIONALSELECTIONTYPING: additionalSelectionTyping = wParam != 0; InvalidateCaret(); break; case SCI_GETADDITIONALSELECTIONTYPING: return additionalSelectionTyping; case SCI_SETMULTIPASTE: multiPasteMode = wParam; break; case SCI_GETMULTIPASTE: return multiPasteMode; case SCI_SETADDITIONALCARETSBLINK: additionalCaretsBlink = wParam != 0; InvalidateCaret(); break; case SCI_GETADDITIONALCARETSBLINK: return additionalCaretsBlink; case SCI_SETADDITIONALCARETSVISIBLE: additionalCaretsVisible = wParam != 0; InvalidateCaret(); break; case SCI_GETADDITIONALCARETSVISIBLE: return additionalCaretsVisible; case SCI_GETSELECTIONS: return sel.Count(); case SCI_GETSELECTIONEMPTY: return sel.Empty(); case SCI_CLEARSELECTIONS: sel.Clear(); Redraw(); break; case SCI_SETSELECTION: sel.SetSelection(SelectionRange(wParam, lParam)); Redraw(); break; case SCI_ADDSELECTION: sel.AddSelection(SelectionRange(wParam, lParam)); Redraw(); break; case SCI_SETMAINSELECTION: sel.SetMain(wParam); Redraw(); break; case SCI_GETMAINSELECTION: return sel.Main(); case SCI_SETSELECTIONNCARET: sel.Range(wParam).caret.SetPosition(lParam); Redraw(); break; case SCI_GETSELECTIONNCARET: return sel.Range(wParam).caret.Position(); case SCI_SETSELECTIONNANCHOR: sel.Range(wParam).anchor.SetPosition(lParam); Redraw(); break; case SCI_GETSELECTIONNANCHOR: return sel.Range(wParam).anchor.Position(); case SCI_SETSELECTIONNCARETVIRTUALSPACE: sel.Range(wParam).caret.SetVirtualSpace(lParam); Redraw(); break; case SCI_GETSELECTIONNCARETVIRTUALSPACE: return sel.Range(wParam).caret.VirtualSpace(); case SCI_SETSELECTIONNANCHORVIRTUALSPACE: sel.Range(wParam).anchor.SetVirtualSpace(lParam); Redraw(); break; case SCI_GETSELECTIONNANCHORVIRTUALSPACE: return sel.Range(wParam).anchor.VirtualSpace(); case SCI_SETSELECTIONNSTART: sel.Range(wParam).anchor.SetPosition(lParam); Redraw(); break; case SCI_GETSELECTIONNSTART: return sel.Range(wParam).Start().Position(); case SCI_SETSELECTIONNEND: sel.Range(wParam).caret.SetPosition(lParam); Redraw(); break; case SCI_GETSELECTIONNEND: return sel.Range(wParam).End().Position(); case SCI_SETRECTANGULARSELECTIONCARET: if (!sel.IsRectangular()) sel.Clear(); sel.selType = Selection::selRectangle; sel.Rectangular().caret.SetPosition(wParam); SetRectangularRange(); Redraw(); break; case SCI_GETRECTANGULARSELECTIONCARET: return sel.Rectangular().caret.Position(); case SCI_SETRECTANGULARSELECTIONANCHOR: if (!sel.IsRectangular()) sel.Clear(); sel.selType = Selection::selRectangle; sel.Rectangular().anchor.SetPosition(wParam); SetRectangularRange(); Redraw(); break; case SCI_GETRECTANGULARSELECTIONANCHOR: return sel.Rectangular().anchor.Position(); case SCI_SETRECTANGULARSELECTIONCARETVIRTUALSPACE: if (!sel.IsRectangular()) sel.Clear(); sel.selType = Selection::selRectangle; sel.Rectangular().caret.SetVirtualSpace(wParam); SetRectangularRange(); Redraw(); break; case SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE: return sel.Rectangular().caret.VirtualSpace(); case SCI_SETRECTANGULARSELECTIONANCHORVIRTUALSPACE: if (!sel.IsRectangular()) sel.Clear(); sel.selType = Selection::selRectangle; sel.Rectangular().anchor.SetVirtualSpace(wParam); SetRectangularRange(); Redraw(); break; case SCI_GETRECTANGULARSELECTIONANCHORVIRTUALSPACE: return sel.Rectangular().anchor.VirtualSpace(); case SCI_SETVIRTUALSPACEOPTIONS: virtualSpaceOptions = wParam; break; case SCI_GETVIRTUALSPACEOPTIONS: return virtualSpaceOptions; case SCI_SETADDITIONALSELFORE: vs.selAdditionalForeground = ColourDesired(wParam); InvalidateStyleRedraw(); break; case SCI_SETADDITIONALSELBACK: vs.selAdditionalBackground = ColourDesired(wParam); InvalidateStyleRedraw(); break; case SCI_SETADDITIONALSELALPHA: vs.selAdditionalAlpha = wParam; InvalidateStyleRedraw(); break; case SCI_GETADDITIONALSELALPHA: return vs.selAdditionalAlpha; case SCI_SETADDITIONALCARETFORE: vs.additionalCaretColour = ColourDesired(wParam); InvalidateStyleRedraw(); break; case SCI_GETADDITIONALCARETFORE: return vs.additionalCaretColour.AsLong(); case SCI_ROTATESELECTION: sel.RotateMain(); InvalidateSelection(sel.RangeMain(), true); break; case SCI_SWAPMAINANCHORCARET: InvalidateSelection(sel.RangeMain()); sel.RangeMain() = SelectionRange(sel.RangeMain().anchor, sel.RangeMain().caret); break; case SCI_CHANGELEXERSTATE: pdoc->ChangeLexerState(wParam, lParam); break; case SCI_SETIDENTIFIER: SetCtrlID(wParam); break; case SCI_GETIDENTIFIER: return GetCtrlID(); case SCI_SETTECHNOLOGY: // No action by default break; case SCI_GETTECHNOLOGY: return technology; case SCI_COUNTCHARACTERS: return pdoc->CountCharacters(wParam, lParam); default: return DefWndProc(iMessage, wParam, lParam); } //Platform::DebugPrintf("end wnd proc\n"); return 0l; } |
Added src/Editor.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 |
// Scintilla source code edit control /** @file Editor.h ** Defines the main editor class. **/ // Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef EDITOR_H #define EDITOR_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif /** */ class Caret { public: bool active; bool on; int period; Caret(); }; /** */ class Timer { public: bool ticking; int ticksToWait; enum {tickSize = 100}; TickerID tickerID; Timer(); }; /** */ class Idler { public: bool state; IdlerID idlerID; Idler(); }; /** * When platform has a way to generate an event before painting, * accumulate needed styling range and other work items in * WorkNeeded to avoid unnecessary work inside paint handler */ class WorkNeeded { public: enum workItems { workNone=0, workStyle=1, workUpdateUI=2 }; bool active; enum workItems items; Position upTo; WorkNeeded() : active(false), items(workNone), upTo(0) {} void Reset() { active = false; items = workNone; upTo = 0; } void Need(workItems items_, Position pos) { if ((items_ & workStyle) && (upTo < pos)) upTo = pos; items = static_cast<workItems>(items | items_); } }; /** * Hold a piece of text selected for copying or dragging. * The text is expected to hold a terminating '\0' and this is counted in len. */ class SelectionText { public: char *s; int len; bool rectangular; bool lineCopy; int codePage; int characterSet; SelectionText() : s(0), len(0), rectangular(false), lineCopy(false), codePage(0), characterSet(0) {} ~SelectionText() { Free(); } void Free() { Set(0, 0, 0, 0, false, false); } void Set(char *s_, int len_, int codePage_, int characterSet_, bool rectangular_, bool lineCopy_) { delete []s; s = s_; if (s) len = len_; else len = 0; codePage = codePage_; characterSet = characterSet_; rectangular = rectangular_; lineCopy = lineCopy_; FixSelectionForClipboard(); } void Copy(const char *s_, int len_, int codePage_, int characterSet_, bool rectangular_, bool lineCopy_) { delete []s; s = 0; s = new char[len_]; len = len_; for (int i = 0; i < len_; i++) { s[i] = s_[i]; } codePage = codePage_; characterSet = characterSet_; rectangular = rectangular_; lineCopy = lineCopy_; FixSelectionForClipboard(); } void Copy(const SelectionText &other) { Copy(other.s, other.len, other.codePage, other.characterSet, other.rectangular, other.lineCopy); } private: void FixSelectionForClipboard() { // Replace null characters by spaces. // To avoid that the content of the clipboard is truncated in the paste operation // when the clipboard contains null characters. for (int i = 0; i < len - 1; ++i) { if (s[i] == '\0') s[i] = ' '; } } }; /** */ class Editor : public DocWatcher { // Private so Editor objects can not be copied Editor(const Editor &); Editor &operator=(const Editor &); protected: // ScintillaBase subclass needs access to much of Editor /** On GTK+, Scintilla is a container widget holding two scroll bars * whereas on Windows there is just one window with both scroll bars turned on. */ Window wMain; ///< The Scintilla parent window Window wMargin; ///< May be separate when using a scroll view for wMain /** Style resources may be expensive to allocate so are cached between uses. * When a style attribute is changed, this cache is flushed. */ bool stylesValid; ViewStyle vs; int technology; Point sizeRGBAImage; float scaleRGBAImage; int printMagnification; int printColourMode; int printWrapState; int cursorMode; int controlCharSymbol; // Highlight current folding block HighlightDelimiter highlightDelimiter; bool hasFocus; bool hideSelection; bool inOverstrike; bool mouseDownCaptures; /** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to * the screen. This avoids flashing but is about 30% slower. */ bool bufferedDraw; /** In twoPhaseDraw mode, drawing is performed in two phases, first the background * and then the foreground. This avoids chopping off characters that overlap the next run. */ bool twoPhaseDraw; int xOffset; ///< Horizontal scrolled amount in pixels int xCaretMargin; ///< Ensure this many pixels visible on both sides of caret bool horizontalScrollBarVisible; int scrollWidth; bool trackLineWidth; int lineWidthMaxSeen; bool verticalScrollBarVisible; bool endAtLastLine; int caretSticky; int marginOptions; bool multipleSelection; bool additionalSelectionTyping; int multiPasteMode; bool additionalCaretsBlink; bool additionalCaretsVisible; int virtualSpaceOptions; Surface *pixmapLine; Surface *pixmapSelMargin; Surface *pixmapSelPattern; Surface *pixmapSelPatternOffset1; Surface *pixmapIndentGuide; Surface *pixmapIndentGuideHighlight; LineLayoutCache llc; PositionCache posCache; KeyMap kmap; Caret caret; Timer timer; Timer autoScrollTimer; enum { autoScrollDelay = 200 }; Idler idler; Point lastClick; unsigned int lastClickTime; int dwellDelay; int ticksToDwell; bool dwelling; enum { selChar, selWord, selSubLine, selWholeLine } selectionType; Point ptMouseLast; enum { ddNone, ddInitial, ddDragging } inDragDrop; bool dropWentOutside; SelectionPosition posDrag; SelectionPosition posDrop; int hotSpotClickPos; int lastXChosen; int lineAnchorPos; int originalAnchorPos; int wordSelectAnchorStartPos; int wordSelectAnchorEndPos; int wordSelectInitialCaretPos; int targetStart; int targetEnd; int searchFlags; int topLine; int posTopLine; int lengthForEncode; int needUpdateUI; Position braces[2]; int bracesMatchStyle; int highlightGuideColumn; int theEdge; enum { notPainting, painting, paintAbandoned } paintState; PRectangle rcPaint; bool paintingAllText; bool willRedrawAll; WorkNeeded workNeeded; int modEventMask; SelectionText drag; Selection sel; bool primarySelection; int caretXPolicy; int caretXSlop; ///< Ensure this many pixels visible on both sides of caret int caretYPolicy; int caretYSlop; ///< Ensure this many lines visible on both sides of caret int visiblePolicy; int visibleSlop; int searchAnchor; bool recordingMacro; int foldFlags; ContractionState cs; // Hotspot support int hsStart; int hsEnd; // Wrapping support enum { eWrapNone, eWrapWord, eWrapChar } wrapState; enum { wrapLineLarge = 0x7ffffff }; int wrapWidth; int wrapStart; int wrapEnd; int wrapVisualFlags; int wrapVisualFlagsLocation; int wrapVisualStartIndent; int wrapIndentMode; // SC_WRAPINDENT_FIXED, _SAME, _INDENT bool convertPastes; int marginNumberPadding; // the right-side padding of the number margin int ctrlCharPadding; // the padding around control character text blobs int lastSegItalicsOffset; // the offset so as not to clip italic characters at EOLs Document *pdoc; Editor(); virtual ~Editor(); virtual void Initialise() = 0; virtual void Finalise(); void InvalidateStyleData(); void InvalidateStyleRedraw(); void RefreshStyleData(); void DropGraphics(bool freeObjects); void AllocateGraphics(); // The top left visible point in main window coordinates. Will be 0,0 except for // scroll views where it will be equivalent to the current scroll position. virtual Point GetVisibleOriginInMain(); Point DocumentPointFromView(Point ptView); // Convert a point from view space to document int TopLineOfMain(); // Return the line at Main's y coordinate 0 virtual PRectangle GetClientRectangle(); PRectangle GetTextRectangle(); int LinesOnScreen(); int LinesToScroll(); int MaxScrollPos(); SelectionPosition ClampPositionIntoDocument(SelectionPosition sp) const; Point LocationFromPosition(SelectionPosition pos); Point LocationFromPosition(int pos); int XFromPosition(int pos); int XFromPosition(SelectionPosition sp); SelectionPosition SPositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false, bool virtualSpace=true); int PositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false); SelectionPosition SPositionFromLineX(int lineDoc, int x); int PositionFromLineX(int line, int x); int LineFromLocation(Point pt); void SetTopLine(int topLineNew); bool AbandonPaint(); void RedrawRect(PRectangle rc); void Redraw(); void RedrawSelMargin(int line=-1, bool allAfter=false); PRectangle RectangleFromRange(int start, int end); void InvalidateRange(int start, int end); bool UserVirtualSpace() const { return ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0); } int CurrentPosition(); bool SelectionEmpty(); SelectionPosition SelectionStart(); SelectionPosition SelectionEnd(); void SetRectangularRange(); void ThinRectangularRange(); void InvalidateSelection(SelectionRange newMain, bool invalidateWholeSelection=false); void SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_); void SetSelection(int currentPos_, int anchor_); void SetSelection(SelectionPosition currentPos_); void SetSelection(int currentPos_); void SetEmptySelection(SelectionPosition currentPos_); void SetEmptySelection(int currentPos_); bool RangeContainsProtected(int start, int end) const; bool SelectionContainsProtected(); int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true) const; SelectionPosition MovePositionOutsideChar(SelectionPosition pos, int moveDir, bool checkLineEnd=true) const; int MovePositionTo(SelectionPosition newPos, Selection::selTypes sel=Selection::noSel, bool ensureVisible=true); int MovePositionTo(int newPos, Selection::selTypes sel=Selection::noSel, bool ensureVisible=true); SelectionPosition MovePositionSoVisible(SelectionPosition pos, int moveDir); SelectionPosition MovePositionSoVisible(int pos, int moveDir); Point PointMainCaret(); void SetLastXChosen(); void ScrollTo(int line, bool moveThumb=true); virtual void ScrollText(int linesToMove); void HorizontalScrollTo(int xPos); void VerticalCentreCaret(); void MoveSelectedLines(int lineDelta); void MoveSelectedLinesUp(); void MoveSelectedLinesDown(); void MoveCaretInsideView(bool ensureVisible=true); int DisplayFromPosition(int pos); struct XYScrollPosition { int xOffset; int topLine; XYScrollPosition(int xOffset_, int topLine_) : xOffset(xOffset_), topLine(topLine_) {} bool operator==(const XYScrollPosition &other) const { return (xOffset == other.xOffset) && (topLine == other.topLine); } }; enum XYScrollOptions { xysUseMargin=0x1, xysVertical=0x2, xysHorizontal=0x4, xysDefault=xysUseMargin|xysVertical|xysHorizontal}; XYScrollPosition XYScrollToMakeVisible(const SelectionRange range, const XYScrollOptions options); void SetXYScroll(XYScrollPosition newXY); void EnsureCaretVisible(bool useMargin=true, bool vert=true, bool horiz=true); void ScrollRange(SelectionRange range); void ShowCaretAtCurrentPosition(); void DropCaret(); void InvalidateCaret(); virtual void UpdateSystemCaret(); void NeedWrapping(int docLineStart = 0, int docLineEnd = wrapLineLarge); bool WrapOneLine(Surface *surface, int lineToWrap); bool WrapLines(bool fullWrap, int priorityWrapLineStart); void LinesJoin(); void LinesSplit(int pixelWidth); int SubstituteMarkerIfEmpty(int markerCheck, int markerDefault); void PaintSelMargin(Surface *surface, PRectangle &rc); LineLayout *RetrieveLineLayout(int lineNumber); void LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout *ll, int width=LineLayout::wrapWidthInfinite); ColourDesired SelectionBackground(ViewStyle &vsDraw, bool main); ColourDesired TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourDesired background, int inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll); void DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight); void DrawWrapMarker(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourDesired wrapColour); void DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll, int line, int lineEnd, int xStart, int subLine, XYACCUMULATOR subLineStart, bool overrideBackground, ColourDesired background, bool drawWrapMark, ColourDesired wrapColour); void DrawIndicator(int indicNum, int startPos, int endPos, Surface *surface, ViewStyle &vsDraw, int xStart, PRectangle rcLine, LineLayout *ll, int subLine); void DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart, PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under); void DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart, PRectangle rcLine, LineLayout *ll, int subLine); void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart, PRectangle rcLine, LineLayout *ll, int subLine); void DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine, int xStart, int offset, int posCaret, PRectangle rcCaret, ColourDesired caretColour); void DrawCarets(Surface *surface, ViewStyle &vsDraw, int line, int xStart, PRectangle rcLine, LineLayout *ll, int subLine); void RefreshPixMaps(Surface *surfaceWindow); void Paint(Surface *surfaceWindow, PRectangle rcArea); long FormatRange(bool draw, Sci_RangeToFormat *pfr); int TextWidth(int style, const char *text); virtual void SetVerticalScrollPos() = 0; virtual void SetHorizontalScrollPos() = 0; virtual bool ModifyScrollBars(int nMax, int nPage) = 0; virtual void ReconfigureScrollBars(); void SetScrollBars(); void ChangeSize(); void FilterSelections(); int InsertSpace(int position, unsigned int spaces); void AddChar(char ch); virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false); void InsertPaste(SelectionPosition selStart, const char *text, int len); void ClearSelection(bool retainMultipleSelections=false); void ClearAll(); void ClearDocumentStyle(); void Cut(); void PasteRectangular(SelectionPosition pos, const char *ptr, int len); virtual void Copy() = 0; virtual void CopyAllowLine(); virtual bool CanPaste(); virtual void Paste() = 0; void Clear(); void SelectAll(); void Undo(); void Redo(); void DelChar(); void DelCharBack(bool allowLineStartDeletion); virtual void ClaimSelection() = 0; virtual void NotifyChange() = 0; virtual void NotifyFocus(bool focus); virtual void SetCtrlID(int identifier); virtual int GetCtrlID() { return ctrlID; } virtual void NotifyParent(SCNotification scn) = 0; virtual void NotifyStyleToNeeded(int endStyleNeeded); void NotifyChar(int ch); void NotifySavePoint(bool isSavePoint); void NotifyModifyAttempt(); virtual void NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt); void NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt); void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt); void NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool alt); bool NotifyUpdateUI(); void NotifyPainted(); void NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt); bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt); void NotifyNeedShown(int pos, int len); void NotifyDwelling(Point pt, bool state); void NotifyZoom(); void NotifyModifyAttempt(Document *document, void *userData); void NotifySavePoint(Document *document, void *userData, bool atSavePoint); void CheckModificationForWrap(DocModification mh); void NotifyModified(Document *document, DocModification mh, void *userData); void NotifyDeleted(Document *document, void *userData); void NotifyStyleNeeded(Document *doc, void *userData, int endPos); void NotifyLexerChanged(Document *doc, void *userData); void NotifyErrorOccurred(Document *doc, void *userData, int status); void NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam); void ContainerNeedsUpdate(int flags); void PageMove(int direction, Selection::selTypes sel=Selection::noSel, bool stuttered = false); enum { cmSame, cmUpper, cmLower } caseMap; virtual std::string CaseMapString(const std::string &s, int caseMapping); void ChangeCaseOfSelection(int caseMapping); void LineTranspose(); void Duplicate(bool forLine); virtual void CancelModes(); void NewLine(); void CursorUpOrDown(int direction, Selection::selTypes sel=Selection::noSel); void ParaUpOrDown(int direction, Selection::selTypes sel=Selection::noSel); int StartEndDisplayLine(int pos, bool start); virtual int KeyCommand(unsigned int iMessage); virtual int KeyDefault(int /* key */, int /*modifiers*/); int KeyDownWithModifiers(int key, int modifiers, bool *consumed); int KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed=0); void Indent(bool forwards); virtual CaseFolder *CaseFolderForEncoding(); long FindText(uptr_t wParam, sptr_t lParam); void SearchAnchor(); long SearchText(unsigned int iMessage, uptr_t wParam, sptr_t lParam); long SearchInTarget(const char *text, int length); void GoToLine(int lineNo); virtual void CopyToClipboard(const SelectionText &selectedText) = 0; char *CopyRange(int start, int end); std::string RangeText(int start, int end) const; void CopySelectionRange(SelectionText *ss, bool allowLineCopy=false); void CopyRangeToClipboard(int start, int end); void CopyText(int length, const char *text); void SetDragPosition(SelectionPosition newPos); virtual void DisplayCursor(Window::Cursor c); virtual bool DragThreshold(Point ptStart, Point ptNow); virtual void StartDrag(); void DropAt(SelectionPosition position, const char *value, bool moving, bool rectangular); /** PositionInSelection returns true if position in selection. */ bool PositionInSelection(int pos); bool PointInSelection(Point pt); bool PointInSelMargin(Point pt); Window::Cursor GetMarginCursor(Point pt); void TrimAndSetSelection(int currentPos_, int anchor_); void LineSelection(int lineCurrentPos_, int lineAnchorPos_, bool wholeLine); void WordSelection(int pos); void DwellEnd(bool mouseMoved); void MouseLeave(); virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt); void ButtonMove(Point pt); void ButtonUp(Point pt, unsigned int curTime, bool ctrl); void Tick(); bool Idle(); virtual void SetTicking(bool on) = 0; virtual bool SetIdle(bool) { return false; } virtual void SetMouseCapture(bool on) = 0; virtual bool HaveMouseCapture() = 0; void SetFocusState(bool focusState); int PositionAfterArea(PRectangle rcArea); void StyleToPositionInView(Position pos); virtual void IdleWork(); virtual void QueueIdleWork(WorkNeeded::workItems items, int upTo=0); virtual bool PaintContains(PRectangle rc); bool PaintContainsMargin(); void CheckForChangeOutsidePaint(Range r); void SetBraceHighlight(Position pos0, Position pos1, int matchStyle); void SetAnnotationHeights(int start, int end); void SetDocPointer(Document *document); void SetAnnotationVisible(int visible); void Expand(int &line, bool doExpand); void ToggleContraction(int line); int ContractedFoldNext(int lineStart); void EnsureLineVisible(int lineDoc, bool enforcePolicy); int GetTag(char *tagValue, int tagNumber); int ReplaceTarget(bool replacePatterns, const char *text, int length=-1); bool PositionIsHotspot(int position); bool PointIsHotspot(Point pt); void SetHotSpotRange(Point *pt); void GetHotSpotRange(int &hsStart, int &hsEnd); int CodePage() const; virtual bool ValidCodePage(int /* codePage */) const { return true; } int WrapCount(int line); void AddStyledText(char *buffer, int appendLength); virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0; void StyleSetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam); sptr_t StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam); static const char *StringFromEOLMode(int eolMode); static sptr_t StringResult(sptr_t lParam, const char *val); public: // Public so the COM thunks can access it. bool IsUnicodeMode() const; // Public so scintilla_send_message can use it. virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); // Public so scintilla_set_id can use it. int ctrlID; // Public so COM methods for drag and drop can set it. int errorStatus; friend class AutoSurface; friend class SelectionLineIterator; }; /** * A smart pointer class to ensure Surfaces are set up and deleted correctly. */ class AutoSurface { private: Surface *surf; public: AutoSurface(Editor *ed, int technology = -1) : surf(0) { if (ed->wMain.GetID()) { surf = Surface::Allocate(technology != -1 ? technology : ed->technology); if (surf) { surf->Init(ed->wMain.GetID()); surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage()); surf->SetDBCSMode(ed->CodePage()); } } } AutoSurface(SurfaceID sid, Editor *ed, int technology = -1) : surf(0) { if (ed->wMain.GetID()) { surf = Surface::Allocate(technology != -1 ? technology : ed->technology); if (surf) { surf->Init(sid, ed->wMain.GetID()); surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage()); surf->SetDBCSMode(ed->CodePage()); } } } ~AutoSurface() { delete surf; } Surface *operator->() const { return surf; } operator Surface *() const { return surf; } }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/ExternalLexer.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
// Scintilla source code edit control /** @file ExternalLexer.cxx ** Support external lexers in DLLs. **/ // Copyright 2001 Simon Steele <ss@pnotepad.org>, portions copyright Neil Hodgson. // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include <assert.h> #include <string> #include "Platform.h" #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "LexerModule.h" #include "Catalogue.h" #include "ExternalLexer.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif LexerManager *LexerManager::theInstance = NULL; //------------------------------------------ // // ExternalLexerModule // //------------------------------------------ void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) { fneFactory = fFactory; fnFactory = fFactory(index); } //------------------------------------------ // // LexerLibrary // //------------------------------------------ LexerLibrary::LexerLibrary(const char *ModuleName) { // Initialise some members... first = NULL; last = NULL; // Load the DLL lib = DynamicLibrary::Load(ModuleName); if (lib->IsValid()) { m_sModuleName = ModuleName; //Cannot use reinterpret_cast because: ANSI C++ forbids casting between pointers to functions and objects GetLexerCountFn GetLexerCount = (GetLexerCountFn)(sptr_t)lib->FindFunction("GetLexerCount"); if (GetLexerCount) { ExternalLexerModule *lex; LexerMinder *lm; // Find functions in the DLL GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName"); GetLexerFactoryFunction fnFactory = (GetLexerFactoryFunction)(sptr_t)lib->FindFunction("GetLexerFactory"); // Assign a buffer for the lexer name. char lexname[100]; strcpy(lexname, ""); int nl = GetLexerCount(); for (int i = 0; i < nl; i++) { GetLexerName(i, lexname, 100); lex = new ExternalLexerModule(SCLEX_AUTOMATIC, NULL, lexname, NULL); Catalogue::AddLexerModule(lex); // Create a LexerMinder so we don't leak the ExternalLexerModule... lm = new LexerMinder; lm->self = lex; lm->next = NULL; if (first != NULL) { last->next = lm; last = lm; } else { first = lm; last = lm; } // The external lexer needs to know how to call into its DLL to // do its lexing and folding, we tell it here. lex->SetExternal(fnFactory, i); } } } next = NULL; } LexerLibrary::~LexerLibrary() { Release(); delete lib; } void LexerLibrary::Release() { LexerMinder *lm; LexerMinder *lmNext; lm = first; while (NULL != lm) { lmNext = lm->next; delete lm->self; delete lm; lm = lmNext; } first = NULL; last = NULL; } //------------------------------------------ // // LexerManager // //------------------------------------------ /// Return the single LexerManager instance... LexerManager *LexerManager::GetInstance() { if (!theInstance) theInstance = new LexerManager; return theInstance; } /// Delete any LexerManager instance... void LexerManager::DeleteInstance() { delete theInstance; theInstance = NULL; } /// protected constructor - this is a singleton... LexerManager::LexerManager() { first = NULL; last = NULL; } LexerManager::~LexerManager() { Clear(); } void LexerManager::Load(const char *path) { LoadLexerLibrary(path); } void LexerManager::LoadLexerLibrary(const char *module) { for (LexerLibrary *ll = first; ll; ll= ll->next) { if (strcmp(ll->m_sModuleName.c_str(), module) == 0) return; } LexerLibrary *lib = new LexerLibrary(module); if (NULL != first) { last->next = lib; last = lib; } else { first = lib; last = lib; } } void LexerManager::Clear() { if (NULL != first) { LexerLibrary *cur = first; LexerLibrary *next; while (cur) { next = cur->next; delete cur; cur = next; } first = NULL; last = NULL; } } //------------------------------------------ // // LexerManager // //------------------------------------------ LMMinder::~LMMinder() { LexerManager::DeleteInstance(); } LMMinder minder; |
Added src/ExternalLexer.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
// Scintilla source code edit control /** @file ExternalLexer.h ** Support external lexers in DLLs. **/ // Copyright 2001 Simon Steele <ss@pnotepad.org>, portions copyright Neil Hodgson. // The License.txt file describes the conditions under which this software may be distributed. #ifndef EXTERNALLEXER_H #define EXTERNALLEXER_H #if PLAT_WIN #define EXT_LEXER_DECL __stdcall #else #define EXT_LEXER_DECL #endif #ifdef SCI_NAMESPACE namespace Scintilla { #endif typedef void*(EXT_LEXER_DECL *GetLexerFunction)(unsigned int Index); typedef int (EXT_LEXER_DECL *GetLexerCountFn)(); typedef void (EXT_LEXER_DECL *GetLexerNameFn)(unsigned int Index, char *name, int buflength); typedef LexerFactoryFunction(EXT_LEXER_DECL *GetLexerFactoryFunction)(unsigned int Index); /// Sub-class of LexerModule to use an external lexer. class ExternalLexerModule : public LexerModule { protected: GetLexerFactoryFunction fneFactory; char name[100]; public: ExternalLexerModule(int language_, LexerFunction fnLexer_, const char *languageName_=0, LexerFunction fnFolder_=0) : LexerModule(language_, fnLexer_, 0, fnFolder_), fneFactory(0) { strncpy(name, languageName_, sizeof(name)); name[sizeof(name)-1] = '\0'; languageName = name; } virtual void SetExternal(GetLexerFactoryFunction fFactory, int index); }; /// LexerMinder points to an ExternalLexerModule - so we don't leak them. class LexerMinder { public: ExternalLexerModule *self; LexerMinder *next; }; /// LexerLibrary exists for every External Lexer DLL, contains LexerMinders. class LexerLibrary { DynamicLibrary *lib; LexerMinder *first; LexerMinder *last; public: LexerLibrary(const char *ModuleName); ~LexerLibrary(); void Release(); LexerLibrary *next; std::string m_sModuleName; }; /// LexerManager manages external lexers, contains LexerLibrarys. class LexerManager { public: ~LexerManager(); static LexerManager *GetInstance(); static void DeleteInstance(); void Load(const char *path); void Clear(); private: LexerManager(); static LexerManager *theInstance; void LoadLexerLibrary(const char *module); LexerLibrary *first; LexerLibrary *last; }; class LMMinder { public: ~LMMinder(); }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/FontQuality.h.
> > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// Scintilla source code edit control /** @file FontQuality.h ** Definitions to control font anti-aliasing. **/ // Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #define SC_EFF_QUALITY_MASK 0xF #define SC_EFF_QUALITY_DEFAULT 0 #define SC_EFF_QUALITY_NON_ANTIALIASED 1 #define SC_EFF_QUALITY_ANTIALIASED 2 #define SC_EFF_QUALITY_LCD_OPTIMIZED 3 #define SCWIN_TECH_GDI 0 #define SCWIN_TECH_DIRECTWRITE 1 |
Added src/Indicator.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
// Scintilla source code edit control /** @file Indicator.cxx ** Defines the style of indicators which are text decorations such as underlining. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <vector> #include <map> #include "Platform.h" #include "Scintilla.h" #include "XPM.h" #include "Indicator.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static PRectangle PixelGridAlign(const PRectangle &rc) { // Move left and right side to nearest pixel to avoid blurry visuals return PRectangle(int(rc.left + 0.5), rc.top, int(rc.right + 0.5), rc.bottom); } void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine) { surface->PenColour(fore); int ymid = (rc.bottom + rc.top) / 2; if (style == INDIC_SQUIGGLE) { int x = int(rc.left+0.5); int xLast = int(rc.right+0.5); int y = 0; surface->MoveTo(x, rc.top + y); while (x < xLast) { if ((x + 2) > xLast) { if (xLast > x) y = 1; x = xLast; } else { x += 2; y = 2 - y; } surface->LineTo(x, rc.top + y); } } else if (style == INDIC_SQUIGGLEPIXMAP) { PRectangle rcSquiggle = PixelGridAlign(rc); int width = Platform::Minimum(4000, rcSquiggle.Width()); RGBAImage image(width, 3, 1.0, 0); enum { alphaFull = 0xff, alphaSide = 0x2f, alphaSide2=0x5f }; for (int x = 0; x < width; x++) { if (x%2) { // Two halfway columns have a full pixel in middle flanked by light pixels image.SetPixel(x, 0, fore, alphaSide); image.SetPixel(x, 1, fore, alphaFull); image.SetPixel(x, 2, fore, alphaSide); } else { // Extreme columns have a full pixel at bottom or top and a mid-tone pixel in centre image.SetPixel(x, (x%4) ? 0 : 2, fore, alphaFull); image.SetPixel(x, 1, fore, alphaSide2); } } surface->DrawRGBAImage(rcSquiggle, image.GetWidth(), image.GetHeight(), image.Pixels()); } else if (style == INDIC_SQUIGGLELOW) { surface->MoveTo(rc.left, rc.top); int x = rc.left + 3; int y = 0; while (x < rc.right) { surface->LineTo(x-1, rc.top + y); y = 1 - y; surface->LineTo(x, rc.top + y); x += 3; } surface->LineTo(rc.right, rc.top + y); // Finish the line } else if (style == INDIC_TT) { surface->MoveTo(rc.left, ymid); int x = rc.left + 5; while (x < rc.right) { surface->LineTo(x, ymid); surface->MoveTo(x-3, ymid); surface->LineTo(x-3, ymid+2); x++; surface->MoveTo(x, ymid); x += 5; } surface->LineTo(rc.right, ymid); // Finish the line if (x - 3 <= rc.right) { surface->MoveTo(x-3, ymid); surface->LineTo(x-3, ymid+2); } } else if (style == INDIC_DIAGONAL) { int x = rc.left; while (x < rc.right) { surface->MoveTo(x, rc.top+2); int endX = x+3; int endY = rc.top - 1; if (endX > rc.right) { endY += endX - rc.right; endX = rc.right; } surface->LineTo(endX, endY); x += 4; } } else if (style == INDIC_STRIKE) { surface->MoveTo(rc.left, rc.top - 4); surface->LineTo(rc.right, rc.top - 4); } else if (style == INDIC_HIDDEN) { // Draw nothing } else if (style == INDIC_BOX) { surface->MoveTo(rc.left, ymid+1); surface->LineTo(rc.right, ymid+1); surface->LineTo(rc.right, rcLine.top+1); surface->LineTo(rc.left, rcLine.top+1); surface->LineTo(rc.left, ymid+1); } else if (style == INDIC_ROUNDBOX || style == INDIC_STRAIGHTBOX) { PRectangle rcBox = rcLine; rcBox.top = rcLine.top + 1; rcBox.left = rc.left; rcBox.right = rc.right; surface->AlphaRectangle(rcBox, (style == INDIC_ROUNDBOX) ? 1 : 0, fore, fillAlpha, fore, outlineAlpha, 0); } else if (style == INDIC_DOTBOX) { PRectangle rcBox = PixelGridAlign(rc); rcBox.top = rcLine.top + 1; rcBox.bottom = rcLine.bottom; // Cap width at 4000 to avoid large allocations when mistakes made int width = Platform::Minimum(rcBox.Width(), 4000); RGBAImage image(width, rcBox.Height(), 1.0, 0); // Draw horizontal lines top and bottom for (int x=0; x<width; x++) { for (int y=0; y<rcBox.Height(); y += rcBox.Height()-1) { image.SetPixel(x, y, fore, ((x + y) % 2) ? outlineAlpha : fillAlpha); } } // Draw vertical lines left and right for (int y=1; y<rcBox.Height(); y++) { for (int x=0; x<width; x += width-1) { image.SetPixel(x, y, fore, ((x + y) % 2) ? outlineAlpha : fillAlpha); } } surface->DrawRGBAImage(rcBox, image.GetWidth(), image.GetHeight(), image.Pixels()); } else if (style == INDIC_DASH) { int x = rc.left; while (x < rc.right) { surface->MoveTo(x, ymid); surface->LineTo(Platform::Minimum(x + 4, rc.right), ymid); x += 7; } } else if (style == INDIC_DOTS) { int x = rc.left; while (x < rc.right) { PRectangle rcDot(x, ymid, x+1, ymid+1); surface->FillRectangle(rcDot, fore); x += 2; } } else { // Either INDIC_PLAIN or unknown surface->MoveTo(rc.left, ymid); surface->LineTo(rc.right, ymid); } } |
Added src/Indicator.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
// Scintilla source code edit control /** @file Indicator.h ** Defines the style of indicators which are text decorations such as underlining. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef INDICATOR_H #define INDICATOR_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif /** */ class Indicator { public: int style; bool under; ColourDesired fore; int fillAlpha; int outlineAlpha; Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30), outlineAlpha(50) { } void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine); }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/KeyMap.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
// Scintilla source code edit control /** @file KeyMap.cxx ** Defines a mapping between keystrokes and commands. **/ // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include "Platform.h" #include "Scintilla.h" #include "KeyMap.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif KeyMap::KeyMap() : kmap(0), len(0), alloc(0) { for (int i = 0; MapDefault[i].key; i++) { AssignCmdKey(MapDefault[i].key, MapDefault[i].modifiers, MapDefault[i].msg); } } KeyMap::~KeyMap() { Clear(); } void KeyMap::Clear() { delete []kmap; kmap = 0; len = 0; alloc = 0; } void KeyMap::AssignCmdKey(int key, int modifiers, unsigned int msg) { if ((len+1) >= alloc) { KeyToCommand *ktcNew = new KeyToCommand[alloc + 5]; if (!ktcNew) return; for (int k = 0; k < len; k++) ktcNew[k] = kmap[k]; alloc += 5; delete []kmap; kmap = ktcNew; } for (int keyIndex = 0; keyIndex < len; keyIndex++) { if ((key == kmap[keyIndex].key) && (modifiers == kmap[keyIndex].modifiers)) { kmap[keyIndex].msg = msg; return; } } kmap[len].key = key; kmap[len].modifiers = modifiers; kmap[len].msg = msg; len++; } unsigned int KeyMap::Find(int key, int modifiers) { for (int i = 0; i < len; i++) { if ((key == kmap[i].key) && (modifiers == kmap[i].modifiers)) { return kmap[i].msg; } } return 0; } #if PLAT_GTK_MACOSX #define OS_X_KEYS 1 #else #define OS_X_KEYS 0 #endif // Define a modifier that is exactly Ctrl key on all platforms // Most uses of Ctrl map to Cmd on OS X but some can't so use SCI_[S]CTRL_META #if OS_X_KEYS #define SCI_CTRL_META SCI_META #define SCI_SCTRL_META (SCI_META | SCI_SHIFT) #else #define SCI_CTRL_META SCI_CTRL #define SCI_SCTRL_META (SCI_CTRL | SCI_SHIFT) #endif const KeyToCommand KeyMap::MapDefault[] = { #if OS_X_KEYS {SCK_DOWN, SCI_CTRL, SCI_DOCUMENTEND}, {SCK_DOWN, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND}, {SCK_UP, SCI_CTRL, SCI_DOCUMENTSTART}, {SCK_UP, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND}, {SCK_LEFT, SCI_CTRL, SCI_VCHOME}, {SCK_LEFT, SCI_CSHIFT, SCI_VCHOMEEXTEND}, {SCK_RIGHT, SCI_CTRL, SCI_LINEEND}, {SCK_RIGHT, SCI_CSHIFT, SCI_LINEENDEXTEND}, #endif {SCK_DOWN, SCI_NORM, SCI_LINEDOWN}, {SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND}, {SCK_DOWN, SCI_CTRL_META, SCI_LINESCROLLDOWN}, {SCK_DOWN, SCI_ASHIFT, SCI_LINEDOWNRECTEXTEND}, {SCK_UP, SCI_NORM, SCI_LINEUP}, {SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND}, {SCK_UP, SCI_CTRL_META, SCI_LINESCROLLUP}, {SCK_UP, SCI_ASHIFT, SCI_LINEUPRECTEXTEND}, {'[', SCI_CTRL, SCI_PARAUP}, {'[', SCI_CSHIFT, SCI_PARAUPEXTEND}, {']', SCI_CTRL, SCI_PARADOWN}, {']', SCI_CSHIFT, SCI_PARADOWNEXTEND}, {SCK_LEFT, SCI_NORM, SCI_CHARLEFT}, {SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND}, {SCK_LEFT, SCI_CTRL_META, SCI_WORDLEFT}, {SCK_LEFT, SCI_SCTRL_META, SCI_WORDLEFTEXTEND}, {SCK_LEFT, SCI_ASHIFT, SCI_CHARLEFTRECTEXTEND}, {SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT}, {SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND}, {SCK_RIGHT, SCI_CTRL_META, SCI_WORDRIGHT}, {SCK_RIGHT, SCI_SCTRL_META, SCI_WORDRIGHTEXTEND}, {SCK_RIGHT, SCI_ASHIFT, SCI_CHARRIGHTRECTEXTEND}, {'/', SCI_CTRL, SCI_WORDPARTLEFT}, {'/', SCI_CSHIFT, SCI_WORDPARTLEFTEXTEND}, {'\\', SCI_CTRL, SCI_WORDPARTRIGHT}, {'\\', SCI_CSHIFT, SCI_WORDPARTRIGHTEXTEND}, {SCK_HOME, SCI_NORM, SCI_VCHOME}, {SCK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND}, {SCK_HOME, SCI_CTRL, SCI_DOCUMENTSTART}, {SCK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND}, {SCK_HOME, SCI_ALT, SCI_HOMEDISPLAY}, {SCK_HOME, SCI_ASHIFT, SCI_VCHOMERECTEXTEND}, {SCK_END, SCI_NORM, SCI_LINEEND}, {SCK_END, SCI_SHIFT, SCI_LINEENDEXTEND}, {SCK_END, SCI_CTRL, SCI_DOCUMENTEND}, {SCK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND}, {SCK_END, SCI_ALT, SCI_LINEENDDISPLAY}, {SCK_END, SCI_ASHIFT, SCI_LINEENDRECTEXTEND}, {SCK_PRIOR, SCI_NORM, SCI_PAGEUP}, {SCK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND}, {SCK_PRIOR, SCI_ASHIFT, SCI_PAGEUPRECTEXTEND}, {SCK_NEXT, SCI_NORM, SCI_PAGEDOWN}, {SCK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND}, {SCK_NEXT, SCI_ASHIFT, SCI_PAGEDOWNRECTEXTEND}, {SCK_DELETE, SCI_NORM, SCI_CLEAR}, {SCK_DELETE, SCI_SHIFT, SCI_CUT}, {SCK_DELETE, SCI_CTRL, SCI_DELWORDRIGHT}, {SCK_DELETE, SCI_CSHIFT, SCI_DELLINERIGHT}, {SCK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE}, {SCK_INSERT, SCI_SHIFT, SCI_PASTE}, {SCK_INSERT, SCI_CTRL, SCI_COPY}, {SCK_ESCAPE, SCI_NORM, SCI_CANCEL}, {SCK_BACK, SCI_NORM, SCI_DELETEBACK}, {SCK_BACK, SCI_SHIFT, SCI_DELETEBACK}, {SCK_BACK, SCI_CTRL, SCI_DELWORDLEFT}, {SCK_BACK, SCI_ALT, SCI_UNDO}, {SCK_BACK, SCI_CSHIFT, SCI_DELLINELEFT}, {'Z', SCI_CTRL, SCI_UNDO}, #if OS_X_KEYS {'Z', SCI_CSHIFT, SCI_REDO}, #else {'Y', SCI_CTRL, SCI_REDO}, #endif {'X', SCI_CTRL, SCI_CUT}, {'C', SCI_CTRL, SCI_COPY}, {'V', SCI_CTRL, SCI_PASTE}, {'A', SCI_CTRL, SCI_SELECTALL}, {SCK_TAB, SCI_NORM, SCI_TAB}, {SCK_TAB, SCI_SHIFT, SCI_BACKTAB}, {SCK_RETURN, SCI_NORM, SCI_NEWLINE}, {SCK_RETURN, SCI_SHIFT, SCI_NEWLINE}, {SCK_ADD, SCI_CTRL, SCI_ZOOMIN}, {SCK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT}, {SCK_DIVIDE, SCI_CTRL, SCI_SETZOOM}, {'L', SCI_CTRL, SCI_LINECUT}, {'L', SCI_CSHIFT, SCI_LINEDELETE}, {'T', SCI_CSHIFT, SCI_LINECOPY}, {'T', SCI_CTRL, SCI_LINETRANSPOSE}, {'D', SCI_CTRL, SCI_SELECTIONDUPLICATE}, {'U', SCI_CTRL, SCI_LOWERCASE}, {'U', SCI_CSHIFT, SCI_UPPERCASE}, {0,0,0}, }; |
Added src/KeyMap.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
// Scintilla source code edit control /** @file KeyMap.h ** Defines a mapping between keystrokes and commands. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef KEYTOCOMMAND_H #define KEYTOCOMMAND_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif #define SCI_NORM 0 #define SCI_SHIFT SCMOD_SHIFT #define SCI_CTRL SCMOD_CTRL #define SCI_ALT SCMOD_ALT #define SCI_META SCMOD_META #define SCI_CSHIFT (SCI_CTRL | SCI_SHIFT) #define SCI_ASHIFT (SCI_ALT | SCI_SHIFT) /** */ class KeyToCommand { public: int key; int modifiers; unsigned int msg; }; /** */ class KeyMap { KeyToCommand *kmap; int len; int alloc; static const KeyToCommand MapDefault[]; public: KeyMap(); ~KeyMap(); void Clear(); void AssignCmdKey(int key, int modifiers, unsigned int msg); unsigned int Find(int key, int modifiers); // 0 returned on failure }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/LexGen.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 |
#!/usr/bin/env python # LexGen.py - implemented 2002 by Neil Hodgson neilh@scintilla.org # Released to the public domain. # Regenerate the Scintilla and SciTE source files that list # all the lexers and all the properties files. # Should be run whenever a new lexer is added or removed. # Requires Python 2.4 or later # Most files are regenerated in place with templates stored in comments. # The VS .NET project file is generated into a different file as the # VS .NET environment will not retain comments when modifying the file. # The files are copied to a string apart from sections between a # ++Autogenerated comment and a --Autogenerated comment which is # generated by the CopyWithInsertion function. After the whole # string is instantiated, it is compared with the target file and # if different the file is rewritten. # Does not regenerate the Visual C++ 6 project files but does the VS .NET # project file. import string import sys import os import glob # EOL constants CR = "\r" LF = "\n" CRLF = "\r\n" if sys.platform == "win32": NATIVE = CRLF else: # Yes, LF is the native EOL even on Mac OS X. CR is just for # Mac OS <=9 (a.k.a. "Mac Classic") NATIVE = LF # Automatically generated sections contain start and end comments, # a definition line and the results. # The results are replaced by regenerating based on the definition line. # The definition line is a comment prefix followed by "**". # If there is a digit after the ** then this indicates which list to use # and the digit and next character are not part of the definition # Backslash is used as an escape within the definition line. # The part between \( and \) is repeated for each item in the list. # \* is replaced by each list item. \t, and \n are tab and newline. def CopyWithInsertion(input, commentPrefix, retainDefs, eolType, *lists): copying = 1 listid = 0 output = [] for line in input.splitlines(0): isStartGenerated = line.startswith(commentPrefix + "++Autogenerated") if copying and not isStartGenerated: output.append(line) if isStartGenerated: if retainDefs: output.append(line) copying = 0 definition = "" elif not copying and line.startswith(commentPrefix + "**"): if retainDefs: output.append(line) definition = line[len(commentPrefix + "**"):] if (commentPrefix == "<!--") and (" -->" in definition): definition = definition.replace(" -->", "") listid = 0 if definition[0] in string.digits: listid = int(definition[:1]) definition = definition[2:] # Hide double slashes as a control character definition = definition.replace("\\\\", "\001") # Do some normal C style transforms definition = definition.replace("\\n", "\n") definition = definition.replace("\\t", "\t") # Get the doubled backslashes back as single backslashes definition = definition.replace("\001", "\\") startRepeat = definition.find("\\(") endRepeat = definition.find("\\)") intro = definition[:startRepeat] out = "" if intro.endswith("\n"): pos = 0 else: pos = len(intro) out += intro middle = definition[startRepeat+2:endRepeat] for i in lists[listid]: item = middle.replace("\\*", i) if pos and (pos + len(item) >= 80): out += "\\\n" pos = 0 out += item pos += len(item) if item.endswith("\n"): pos = 0 outro = definition[endRepeat+2:] out += outro out = out.replace("\n", eolType) # correct EOLs in generated content output.append(out) elif line.startswith(commentPrefix + "--Autogenerated"): copying = 1 if retainDefs: output.append(line) output = [line.rstrip(" \t") for line in output] # trim trailing whitespace return eolType.join(output) + eolType def UpdateFile(filename, updated): """ If the file is different to updated then copy updated into the file else leave alone so CVS and make don't treat it as modified. """ try: infile = open(filename, "rb") except IOError: # File is not there yet out = open(filename, "wb") out.write(updated.encode('utf-8')) out.close() print("New %s" % filename) return original = infile.read() infile.close() original = original.decode('utf-8') if updated != original: os.unlink(filename) out = open(filename, "wb") out.write(updated.encode('utf-8')) out.close() print("Changed %s " % filename) #~ else: #~ print "Unchanged", filename def Generate(inpath, outpath, commentPrefix, eolType, *lists): """Generate 'outpath' from 'inpath'. "eolType" indicates the type of EOLs to use in the generated file. It should be one of following constants: LF, CRLF, CR, or NATIVE. """ #print "generate '%s' -> '%s' (comment prefix: %r, eols: %r)"\ # % (inpath, outpath, commentPrefix, eolType) try: infile = open(inpath, "rb") except IOError: print("Can not open %s" % inpath) return original = infile.read() infile.close() original = original.decode('utf-8') updated = CopyWithInsertion(original, commentPrefix, inpath == outpath, eolType, *lists) UpdateFile(outpath, updated) def Regenerate(filename, commentPrefix, eolType, *lists): """Regenerate the given file. "eolType" indicates the type of EOLs to use in the generated file. It should be one of following constants: LF, CRLF, CR, or NATIVE. """ Generate(filename, filename, commentPrefix, eolType, *lists) def FindModules(lexFile): modules = [] f = open(lexFile) for l in f.readlines(): if l.startswith("LexerModule"): l = l.replace("(", " ") modules.append(l.split()[1]) return modules # Properties that start with lexer. or fold. are automatically found but there are some # older properties that don't follow this pattern so must be explicitly listed. knownIrregularProperties = [ "fold", "styling.within.preprocessor", "tab.timmy.whinge.level", "asp.default.language", "html.tags.case.sensitive", "ps.level", "ps.tokenize", "sql.backslash.escapes", "nsis.uservars", "nsis.ignorecase" ] def FindProperties(lexFile): properties = {} f = open(lexFile) for l in f.readlines(): if ("GetProperty" in l or "DefineProperty" in l) and "\"" in l: l = l.strip() if not l.startswith("//"): # Drop comments propertyName = l.split("\"")[1] if propertyName.lower() == propertyName: # Only allow lower case property names if propertyName in knownIrregularProperties or \ propertyName.startswith("fold.") or \ propertyName.startswith("lexer."): properties[propertyName] = 1 return properties def FindPropertyDocumentation(lexFile): documents = {} f = open(lexFile) name = "" for l in f.readlines(): l = l.strip() if "// property " in l: propertyName = l.split()[2] if propertyName.lower() == propertyName: # Only allow lower case property names name = propertyName documents[name] = "" elif "DefineProperty" in l and "\"" in l: propertyName = l.split("\"")[1] if propertyName.lower() == propertyName: # Only allow lower case property names name = propertyName documents[name] = "" elif name: if l.startswith("//"): if documents[name]: documents[name] += " " documents[name] += l[2:].strip() elif l.startswith("\""): l = l[1:].strip() if l.endswith(";"): l = l[:-1].strip() if l.endswith(")"): l = l[:-1].strip() if l.endswith("\""): l = l[:-1] # Fix escaped double quotes l = l.replace("\\\"", "\"") documents[name] += l else: name = "" for name in list(documents.keys()): if documents[name] == "": del documents[name] return documents def ciCompare(a,b): return cmp(a.lower(), b.lower()) def ciKey(a): return a.lower() def sortListInsensitive(l): try: # Try key function l.sort(key=ciKey) except TypeError: # Earlier version of Python, so use comparison function l.sort(ciCompare) def UpdateLineInFile(path, linePrefix, lineReplace): lines = [] with open(path, "r") as f: for l in f.readlines(): l = l.rstrip() if l.startswith(linePrefix): lines.append(lineReplace) else: lines.append(l) contents = NATIVE.join(lines) + NATIVE UpdateFile(path, contents) def UpdateVersionNumbers(root): with open(root + "scintilla/version.txt") as f: version = f.read() versionDotted = version[0] + '.' + version[1] + '.' + version[2] versionCommad = version[0] + ', ' + version[1] + ', ' + version[2] + ', 0' UpdateLineInFile(root + "scintilla/win32/ScintRes.rc", "#define VERSION_SCINTILLA", "#define VERSION_SCINTILLA \"" + versionDotted + "\"") UpdateLineInFile(root + "scintilla/win32/ScintRes.rc", "#define VERSION_WORDS", "#define VERSION_WORDS " + versionCommad) UpdateLineInFile(root + "scintilla/qt/ScintillaEditBase/ScintillaEditBase.pro", "VERSION =", "VERSION = " + versionDotted) UpdateLineInFile(root + "scintilla/qt/ScintillaEdit/ScintillaEdit.pro", "VERSION =", "VERSION = " + versionDotted) UpdateLineInFile(root + "scintilla/doc/ScintillaDownload.html", " Release", " Release " + versionDotted) UpdateLineInFile(root + "scintilla/doc/index.html", ' <font color="#FFCC99" size="3"> Release version', ' <font color="#FFCC99" size="3"> Release version ' + versionDotted + '<br />') if os.path.exists(root + "scite"): UpdateLineInFile(root + "scite/src/SciTE.h", "#define VERSION_SCITE", "#define VERSION_SCITE \"" + versionDotted + "\"") UpdateLineInFile(root + "scite/src/SciTE.h", "#define VERSION_WORDS", "#define VERSION_WORDS " + versionCommad) UpdateLineInFile(root + "scite/doc/SciTEDownload.html", " Release", " Release " + versionDotted) UpdateLineInFile(root + "scite/doc/SciTE.html", ' <font color="#FFCC99" size="3"> Release version', ' <font color="#FFCC99" size="3"> Release version ' + versionDotted + '<br />') def RegenerateAll(): root="../../" # Find all the lexer source code files lexFilePaths = glob.glob(root + "scintilla/lexers/Lex*.cxx") sortListInsensitive(lexFilePaths) lexFiles = [os.path.basename(f)[:-4] for f in lexFilePaths] print(lexFiles) lexerModules = [] lexerProperties = {} propertyDocuments = {} for lexFile in lexFilePaths: lexerModules.extend(FindModules(lexFile)) for k in FindProperties(lexFile).keys(): lexerProperties[k] = 1 documents = FindPropertyDocumentation(lexFile) for k in documents.keys(): propertyDocuments[k] = documents[k] sortListInsensitive(lexerModules) lexerProperties = list(lexerProperties.keys()) sortListInsensitive(lexerProperties) # Generate HTML to document each property # This is done because tags can not be safely put inside comments in HTML documentProperties = list(propertyDocuments.keys()) sortListInsensitive(documentProperties) propertiesHTML = [] for k in documentProperties: propertiesHTML.append("\t<tr id='property-%s'>\n\t<td>%s</td>\n\t<td>%s</td>\n\t</tr>" % (k, k, propertyDocuments[k])) # Find all the SciTE properties files otherProps = ["abbrev.properties", "Embedded.properties", "SciTEGlobal.properties", "SciTE.properties"] if os.path.exists(root + "scite"): propFilePaths = glob.glob(root + "scite/src/*.properties") sortListInsensitive(propFilePaths) propFiles = [os.path.basename(f) for f in propFilePaths if os.path.basename(f) not in otherProps] sortListInsensitive(propFiles) print(propFiles) Regenerate(root + "scintilla/src/Catalogue.cxx", "//", NATIVE, lexerModules) Regenerate(root + "scintilla/win32/scintilla.mak", "#", NATIVE, lexFiles) Regenerate(root + "scintilla/win32/scintilla_vc6.mak", "#", NATIVE, lexFiles) if os.path.exists(root + "scite"): Regenerate(root + "scite/win32/makefile", "#", NATIVE, propFiles) Regenerate(root + "scite/win32/scite.mak", "#", NATIVE, propFiles) Regenerate(root + "scite/src/SciTEProps.cxx", "//", NATIVE, lexerProperties) Regenerate(root + "scite/doc/SciTEDoc.html", "<!--", NATIVE, propertiesHTML) Generate(root + "scite/boundscheck/vcproj.gen", root + "scite/boundscheck/SciTE.vcproj", "#", NATIVE, lexFiles) UpdateVersionNumbers(root) RegenerateAll() |
Added src/LineMarker.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 |
// Scintilla source code edit control /** @file LineMarker.cxx ** Defines the look of a line marker in the margin . **/ // Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <string.h> #include <math.h> #include <vector> #include <map> #include "Platform.h" #include "Scintilla.h" #include "XPM.h" #include "LineMarker.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif void LineMarker::SetXPM(const char *textForm) { delete pxpm; pxpm = new XPM(textForm); markType = SC_MARK_PIXMAP; } void LineMarker::SetXPM(const char *const *linesForm) { delete pxpm; pxpm = new XPM(linesForm); markType = SC_MARK_PIXMAP; } void LineMarker::SetRGBAImage(Point sizeRGBAImage, float scale, const unsigned char *pixelsRGBAImage) { delete image; image = new RGBAImage(sizeRGBAImage.x, sizeRGBAImage.y, scale, pixelsRGBAImage); markType = SC_MARK_RGBAIMAGE; } static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore, ColourDesired back) { PRectangle rc; rc.left = centreX - armSize; rc.top = centreY - armSize; rc.right = centreX + armSize + 1; rc.bottom = centreY + armSize + 1; surface->RectangleDraw(rc, back, fore); } static void DrawCircle(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore, ColourDesired back) { PRectangle rcCircle; rcCircle.left = centreX - armSize; rcCircle.top = centreY - armSize; rcCircle.right = centreX + armSize + 1; rcCircle.bottom = centreY + armSize + 1; surface->Ellipse(rcCircle, back, fore); } static void DrawPlus(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore) { PRectangle rcV(centreX, centreY - armSize + 2, centreX + 1, centreY + armSize - 2 + 1); surface->FillRectangle(rcV, fore); PRectangle rcH(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY+1); surface->FillRectangle(rcH, fore); } static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore) { PRectangle rcH(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY+1); surface->FillRectangle(rcH, fore); } void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, typeOfFold tFold, int marginStyle) { ColourDesired head = back; ColourDesired body = back; ColourDesired tail = back; switch (tFold) { case LineMarker::head : case LineMarker::headWithTail : head = backSelected; tail = backSelected; break; case LineMarker::body : head = backSelected; body = backSelected; break; case LineMarker::tail : body = backSelected; tail = backSelected; break; default : // LineMarker::undefined break; } if ((markType == SC_MARK_PIXMAP) && (pxpm)) { pxpm->Draw(surface, rcWhole); return; } if ((markType == SC_MARK_RGBAIMAGE) && (image)) { // Make rectangle just large enough to fit image centred on centre of rcWhole PRectangle rcImage; rcImage.top = static_cast<int>(((rcWhole.top + rcWhole.bottom) - image->GetScaledHeight()) / 2); rcImage.bottom = rcImage.top + image->GetScaledHeight(); rcImage.left = static_cast<int>(((rcWhole.left + rcWhole.right) - image->GetScaledWidth()) / 2); rcImage.right = rcImage.left + image->GetScaledWidth(); surface->DrawRGBAImage(rcImage, image->GetWidth(), image->GetHeight(), image->Pixels()); return; } // Restrict most shapes a bit PRectangle rc = rcWhole; rc.top++; rc.bottom--; int minDim = Platform::Minimum(rc.Width(), rc.Height()); minDim--; // Ensure does not go beyond edge int centreX = floor((rc.right + rc.left) / 2.0); int centreY = floor((rc.bottom + rc.top) / 2.0); int dimOn2 = minDim / 2; int dimOn4 = minDim / 4; int blobSize = dimOn2-1; int armSize = dimOn2-2; if (marginStyle == SC_MARGIN_NUMBER || marginStyle == SC_MARGIN_TEXT || marginStyle == SC_MARGIN_RTEXT) { // On textual margins move marker to the left to try to avoid overlapping the text centreX = rc.left + dimOn2 + 1; } if (markType == SC_MARK_ROUNDRECT) { PRectangle rcRounded = rc; rcRounded.left = rc.left + 1; rcRounded.right = rc.right - 1; surface->RoundedRectangle(rcRounded, fore, back); } else if (markType == SC_MARK_CIRCLE) { PRectangle rcCircle; rcCircle.left = centreX - dimOn2; rcCircle.top = centreY - dimOn2; rcCircle.right = centreX + dimOn2; rcCircle.bottom = centreY + dimOn2; surface->Ellipse(rcCircle, fore, back); } else if (markType == SC_MARK_ARROW) { Point pts[] = { Point(centreX - dimOn4, centreY - dimOn2), Point(centreX - dimOn4, centreY + dimOn2), Point(centreX + dimOn2 - dimOn4, centreY), }; surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), fore, back); } else if (markType == SC_MARK_ARROWDOWN) { Point pts[] = { Point(centreX - dimOn2, centreY - dimOn4), Point(centreX + dimOn2, centreY - dimOn4), Point(centreX, centreY + dimOn2 - dimOn4), }; surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), fore, back); } else if (markType == SC_MARK_PLUS) { Point pts[] = { Point(centreX - armSize, centreY - 1), Point(centreX - 1, centreY - 1), Point(centreX - 1, centreY - armSize), Point(centreX + 1, centreY - armSize), Point(centreX + 1, centreY - 1), Point(centreX + armSize, centreY -1), Point(centreX + armSize, centreY +1), Point(centreX + 1, centreY + 1), Point(centreX + 1, centreY + armSize), Point(centreX - 1, centreY + armSize), Point(centreX - 1, centreY + 1), Point(centreX - armSize, centreY + 1), }; surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), fore, back); } else if (markType == SC_MARK_MINUS) { Point pts[] = { Point(centreX - armSize, centreY - 1), Point(centreX + armSize, centreY -1), Point(centreX + armSize, centreY +1), Point(centreX - armSize, centreY + 1), }; surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), fore, back); } else if (markType == SC_MARK_SMALLRECT) { PRectangle rcSmall; rcSmall.left = rc.left + 1; rcSmall.top = rc.top + 2; rcSmall.right = rc.right - 1; rcSmall.bottom = rc.bottom - 2; surface->RectangleDraw(rcSmall, fore, back); } else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND || markType == SC_MARK_UNDERLINE || markType == SC_MARK_AVAILABLE) { // An invisible marker so don't draw anything } else if (markType == SC_MARK_VLINE) { surface->PenColour(body); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, rcWhole.bottom); } else if (markType == SC_MARK_LCORNER) { surface->PenColour(tail); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY); surface->LineTo(rc.right - 1, centreY); } else if (markType == SC_MARK_TCORNER) { surface->PenColour(tail); surface->MoveTo(centreX, centreY); surface->LineTo(rc.right - 1, centreY); surface->PenColour(body); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY + 1); surface->PenColour(head); surface->LineTo(centreX, rcWhole.bottom); } else if (markType == SC_MARK_LCORNERCURVE) { surface->PenColour(tail); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY-3); surface->LineTo(centreX+3, centreY); surface->LineTo(rc.right - 1, centreY); } else if (markType == SC_MARK_TCORNERCURVE) { surface->PenColour(tail); surface->MoveTo(centreX, centreY-3); surface->LineTo(centreX+3, centreY); surface->LineTo(rc.right - 1, centreY); surface->PenColour(body); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY-2); surface->PenColour(head); surface->LineTo(centreX, rcWhole.bottom); } else if (markType == SC_MARK_BOXPLUS) { DrawBox(surface, centreX, centreY, blobSize, fore, head); DrawPlus(surface, centreX, centreY, blobSize, tail); } else if (markType == SC_MARK_BOXPLUSCONNECTED) { if (tFold == LineMarker::headWithTail) surface->PenColour(tail); else surface->PenColour(body); surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); surface->PenColour(body); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY - blobSize); DrawBox(surface, centreX, centreY, blobSize, fore, head); DrawPlus(surface, centreX, centreY, blobSize, tail); if (tFold == LineMarker::body) { surface->PenColour(tail); surface->MoveTo(centreX + 1, centreY + blobSize); surface->LineTo(centreX + blobSize + 1, centreY + blobSize); surface->MoveTo(centreX + blobSize, centreY + blobSize); surface->LineTo(centreX + blobSize, centreY - blobSize); surface->MoveTo(centreX + 1, centreY - blobSize); surface->LineTo(centreX + blobSize + 1, centreY - blobSize); } } else if (markType == SC_MARK_BOXMINUS) { DrawBox(surface, centreX, centreY, blobSize, fore, head); DrawMinus(surface, centreX, centreY, blobSize, tail); surface->PenColour(head); surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); } else if (markType == SC_MARK_BOXMINUSCONNECTED) { DrawBox(surface, centreX, centreY, blobSize, fore, head); DrawMinus(surface, centreX, centreY, blobSize, tail); surface->PenColour(head); surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); surface->PenColour(body); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY - blobSize); if (tFold == LineMarker::body) { surface->PenColour(tail); surface->MoveTo(centreX + 1, centreY + blobSize); surface->LineTo(centreX + blobSize + 1, centreY + blobSize); surface->MoveTo(centreX + blobSize, centreY + blobSize); surface->LineTo(centreX + blobSize, centreY - blobSize); surface->MoveTo(centreX + 1, centreY - blobSize); surface->LineTo(centreX + blobSize + 1, centreY - blobSize); } } else if (markType == SC_MARK_CIRCLEPLUS) { DrawCircle(surface, centreX, centreY, blobSize, fore, head); DrawPlus(surface, centreX, centreY, blobSize, tail); } else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) { if (tFold == LineMarker::headWithTail) surface->PenColour(tail); else surface->PenColour(body); surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); surface->PenColour(body); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY - blobSize); DrawCircle(surface, centreX, centreY, blobSize, fore, head); DrawPlus(surface, centreX, centreY, blobSize, tail); } else if (markType == SC_MARK_CIRCLEMINUS) { DrawCircle(surface, centreX, centreY, blobSize, fore, head); DrawMinus(surface, centreX, centreY, blobSize, tail); surface->PenColour(head); surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); } else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) { DrawCircle(surface, centreX, centreY, blobSize, fore, head); DrawMinus(surface, centreX, centreY, blobSize, tail); surface->PenColour(head); surface->MoveTo(centreX, centreY + blobSize); surface->LineTo(centreX, rcWhole.bottom); surface->PenColour(body); surface->MoveTo(centreX, rcWhole.top); surface->LineTo(centreX, centreY - blobSize); } else if (markType >= SC_MARK_CHARACTER) { char character[1]; character[0] = static_cast<char>(markType - SC_MARK_CHARACTER); XYPOSITION width = surface->WidthText(fontForCharacter, character, 1); rc.left += (rc.Width() - width) / 2; rc.right = rc.left + width; surface->DrawTextClipped(rc, fontForCharacter, rc.bottom - 2, character, 1, fore, back); } else if (markType == SC_MARK_DOTDOTDOT) { int right = centreX - 6; for (int b=0; b<3; b++) { PRectangle rcBlob(right, rc.bottom - 4, right + 2, rc.bottom-2); surface->FillRectangle(rcBlob, fore); right += 5; } } else if (markType == SC_MARK_ARROWS) { surface->PenColour(fore); int right = centreX - 2; for (int b=0; b<3; b++) { surface->MoveTo(right - 4, centreY - 4); surface->LineTo(right, centreY); surface->LineTo(right - 5, centreY + 5); right += 4; } } else if (markType == SC_MARK_SHORTARROW) { Point pts[] = { Point(centreX, centreY + dimOn2), Point(centreX + dimOn2, centreY), Point(centreX, centreY - dimOn2), Point(centreX, centreY - dimOn4), Point(centreX - dimOn4, centreY - dimOn4), Point(centreX - dimOn4, centreY + dimOn4), Point(centreX, centreY + dimOn4), Point(centreX, centreY + dimOn2), }; surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]), fore, back); } else if (markType == SC_MARK_LEFTRECT) { PRectangle rcLeft = rcWhole; rcLeft.right = rcLeft.left + 4; surface->FillRectangle(rcLeft, back); } else { // SC_MARK_FULLRECT surface->FillRectangle(rcWhole, back); } } |
Added src/LineMarker.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
// Scintilla source code edit control /** @file LineMarker.h ** Defines the look of a line marker in the margin . **/ // Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef LINEMARKER_H #define LINEMARKER_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif /** */ class LineMarker { public: enum typeOfFold { undefined, head, body, tail, headWithTail }; int markType; ColourDesired fore; ColourDesired back; ColourDesired backSelected; int alpha; XPM *pxpm; RGBAImage *image; LineMarker() { markType = SC_MARK_CIRCLE; fore = ColourDesired(0,0,0); back = ColourDesired(0xff,0xff,0xff); backSelected = ColourDesired(0xff,0x00,0x00); alpha = SC_ALPHA_NOALPHA; pxpm = NULL; image = NULL; } LineMarker(const LineMarker &) { // Defined to avoid pxpm being blindly copied, not as a complete copy constructor markType = SC_MARK_CIRCLE; fore = ColourDesired(0,0,0); back = ColourDesired(0xff,0xff,0xff); backSelected = ColourDesired(0xff,0x00,0x00); alpha = SC_ALPHA_NOALPHA; pxpm = NULL; image = NULL; } ~LineMarker() { delete pxpm; delete image; } LineMarker &operator=(const LineMarker &other) { // Defined to avoid pxpm being blindly copied, not as a complete assignment operator if (this != &other) { markType = SC_MARK_CIRCLE; fore = ColourDesired(0,0,0); back = ColourDesired(0xff,0xff,0xff); backSelected = ColourDesired(0xff,0x00,0x00); alpha = SC_ALPHA_NOALPHA; delete pxpm; pxpm = NULL; delete image; image = NULL; } return *this; } void SetXPM(const char *textForm); void SetXPM(const char *const *linesForm); void SetRGBAImage(Point sizeRGBAImage, float scale, const unsigned char *pixelsRGBAImage); void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter, typeOfFold tFold, int marginStyle); }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/Partitioning.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
// Scintilla source code edit control /** @file Partitioning.h ** Data structure used to partition an interval. Used for holding line start/end positions. **/ // Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef PARTITIONING_H #define PARTITIONING_H /// A split vector of integers with a method for adding a value to all elements /// in a range. /// Used by the Partitioning class. class SplitVectorWithRangeAdd : public SplitVector<int> { public: SplitVectorWithRangeAdd(int growSize_) { SetGrowSize(growSize_); ReAllocate(growSize_); } ~SplitVectorWithRangeAdd() { } void RangeAddDelta(int start, int end, int delta) { // end is 1 past end, so end-start is number of elements to change int i = 0; int rangeLength = end - start; int range1Length = rangeLength; int part1Left = part1Length - start; if (range1Length > part1Left) range1Length = part1Left; while (i < range1Length) { body[start++] += delta; i++; } start += gapLength; while (i < rangeLength) { body[start++] += delta; i++; } } }; /// Divide an interval into multiple partitions. /// Useful for breaking a document down into sections such as lines. /// A 0 length interval has a single 0 length partition, numbered 0 /// If interval not 0 length then each partition non-zero length /// When needed, positions after the interval are considered part of the last partition /// but the end of the last partition can be found with PositionFromPartition(last+1). class Partitioning { private: // To avoid calculating all the partition positions whenever any text is inserted // there may be a step somewhere in the list. int stepPartition; int stepLength; SplitVectorWithRangeAdd *body; // Move step forward void ApplyStep(int partitionUpTo) { if (stepLength != 0) { body->RangeAddDelta(stepPartition+1, partitionUpTo + 1, stepLength); } stepPartition = partitionUpTo; if (stepPartition >= body->Length()-1) { stepPartition = body->Length()-1; stepLength = 0; } } // Move step backward void BackStep(int partitionDownTo) { if (stepLength != 0) { body->RangeAddDelta(partitionDownTo+1, stepPartition+1, -stepLength); } stepPartition = partitionDownTo; } void Allocate(int growSize) { body = new SplitVectorWithRangeAdd(growSize); stepPartition = 0; stepLength = 0; body->Insert(0, 0); // This value stays 0 for ever body->Insert(1, 0); // This is the end of the first partition and will be the start of the second } public: Partitioning(int growSize) { Allocate(growSize); } ~Partitioning() { delete body; body = 0; } int Partitions() const { return body->Length()-1; } void InsertPartition(int partition, int pos) { if (stepPartition < partition) { ApplyStep(partition); } body->Insert(partition, pos); stepPartition++; } void SetPartitionStartPosition(int partition, int pos) { ApplyStep(partition+1); if ((partition < 0) || (partition > body->Length())) { return; } body->SetValueAt(partition, pos); } void InsertText(int partitionInsert, int delta) { // Point all the partitions after the insertion point further along in the buffer if (stepLength != 0) { if (partitionInsert >= stepPartition) { // Fill in up to the new insertion point ApplyStep(partitionInsert); stepLength += delta; } else if (partitionInsert >= (stepPartition - body->Length() / 10)) { // Close to step but before so move step back BackStep(partitionInsert); stepLength += delta; } else { ApplyStep(body->Length()-1); stepPartition = partitionInsert; stepLength = delta; } } else { stepPartition = partitionInsert; stepLength = delta; } } void RemovePartition(int partition) { if (partition > stepPartition) { ApplyStep(partition); stepPartition--; } else { stepPartition--; } body->Delete(partition); } int PositionFromPartition(int partition) const { PLATFORM_ASSERT(partition >= 0); PLATFORM_ASSERT(partition < body->Length()); if ((partition < 0) || (partition >= body->Length())) { return 0; } int pos = body->ValueAt(partition); if (partition > stepPartition) pos += stepLength; return pos; } /// Return value in range [0 .. Partitions() - 1] even for arguments outside interval int PartitionFromPosition(int pos) const { if (body->Length() <= 1) return 0; if (pos >= (PositionFromPartition(body->Length()-1))) return body->Length() - 1 - 1; int lower = 0; int upper = body->Length()-1; do { int middle = (upper + lower + 1) / 2; // Round high int posMiddle = body->ValueAt(middle); if (middle > stepPartition) posMiddle += stepLength; if (pos < posMiddle) { upper = middle - 1; } else { lower = middle; } } while (lower < upper); return lower; } void DeleteAll() { int growSize = body->GetGrowSize(); delete body; Allocate(growSize); } }; #endif |
Added src/PerLine.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 |
// Scintilla source code edit control /** @file PerLine.cxx ** Manages data associated with each line of the document **/ // Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <string.h> #include "Platform.h" #include "Scintilla.h" #include "SplitVector.h" #include "Partitioning.h" #include "CellBuffer.h" #include "PerLine.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif MarkerHandleSet::MarkerHandleSet() { root = 0; } MarkerHandleSet::~MarkerHandleSet() { MarkerHandleNumber *mhn = root; while (mhn) { MarkerHandleNumber *mhnToFree = mhn; mhn = mhn->next; delete mhnToFree; } root = 0; } int MarkerHandleSet::Length() const { int c = 0; MarkerHandleNumber *mhn = root; while (mhn) { c++; mhn = mhn->next; } return c; } int MarkerHandleSet::NumberFromHandle(int handle) const { MarkerHandleNumber *mhn = root; while (mhn) { if (mhn->handle == handle) { return mhn->number; } mhn = mhn->next; } return - 1; } int MarkerHandleSet::MarkValue() const { unsigned int m = 0; MarkerHandleNumber *mhn = root; while (mhn) { m |= (1 << mhn->number); mhn = mhn->next; } return m; } bool MarkerHandleSet::Contains(int handle) const { MarkerHandleNumber *mhn = root; while (mhn) { if (mhn->handle == handle) { return true; } mhn = mhn->next; } return false; } bool MarkerHandleSet::InsertHandle(int handle, int markerNum) { MarkerHandleNumber *mhn = new MarkerHandleNumber; if (!mhn) return false; mhn->handle = handle; mhn->number = markerNum; mhn->next = root; root = mhn; return true; } void MarkerHandleSet::RemoveHandle(int handle) { MarkerHandleNumber **pmhn = &root; while (*pmhn) { MarkerHandleNumber *mhn = *pmhn; if (mhn->handle == handle) { *pmhn = mhn->next; delete mhn; return; } pmhn = &((*pmhn)->next); } } bool MarkerHandleSet::RemoveNumber(int markerNum, bool all) { bool performedDeletion = false; MarkerHandleNumber **pmhn = &root; while (*pmhn) { MarkerHandleNumber *mhn = *pmhn; if (mhn->number == markerNum) { *pmhn = mhn->next; delete mhn; performedDeletion = true; if (!all) break; } else { pmhn = &((*pmhn)->next); } } return performedDeletion; } void MarkerHandleSet::CombineWith(MarkerHandleSet *other) { MarkerHandleNumber **pmhn = &root; while (*pmhn) { pmhn = &((*pmhn)->next); } *pmhn = other->root; other->root = 0; } LineMarkers::~LineMarkers() { Init(); } void LineMarkers::Init() { for (int line = 0; line < markers.Length(); line++) { delete markers[line]; markers[line] = 0; } markers.DeleteAll(); } void LineMarkers::InsertLine(int line) { if (markers.Length()) { markers.Insert(line, 0); } } void LineMarkers::RemoveLine(int line) { // Retain the markers from the deleted line by oring them into the previous line if (markers.Length()) { if (line > 0) { MergeMarkers(line - 1); } markers.Delete(line); } } int LineMarkers::LineFromHandle(int markerHandle) { if (markers.Length()) { for (int line = 0; line < markers.Length(); line++) { if (markers[line]) { if (markers[line]->Contains(markerHandle)) { return line; } } } } return -1; } void LineMarkers::MergeMarkers(int pos) { if (markers[pos + 1] != NULL) { if (markers[pos] == NULL) markers[pos] = new MarkerHandleSet; markers[pos]->CombineWith(markers[pos + 1]); delete markers[pos + 1]; markers[pos + 1] = NULL; } } int LineMarkers::MarkValue(int line) { if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line]) return markers[line]->MarkValue(); else return 0; } int LineMarkers::MarkerNext(int lineStart, int mask) const { if (lineStart < 0) lineStart = 0; int length = markers.Length(); for (int iLine = lineStart; iLine < length; iLine++) { MarkerHandleSet *onLine = markers[iLine]; if (onLine && ((onLine->MarkValue() & mask) != 0)) //if ((pdoc->GetMark(iLine) & lParam) != 0) return iLine; } return -1; } int LineMarkers::AddMark(int line, int markerNum, int lines) { handleCurrent++; if (!markers.Length()) { // No existing markers so allocate one element per line markers.InsertValue(0, lines, 0); } if (line >= markers.Length()) { return -1; } if (!markers[line]) { // Need new structure to hold marker handle markers[line] = new MarkerHandleSet(); if (!markers[line]) return -1; } markers[line]->InsertHandle(handleCurrent, markerNum); return handleCurrent; } bool LineMarkers::DeleteMark(int line, int markerNum, bool all) { bool someChanges = false; if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line]) { if (markerNum == -1) { someChanges = true; delete markers[line]; markers[line] = NULL; } else { someChanges = markers[line]->RemoveNumber(markerNum, all); if (markers[line]->Length() == 0) { delete markers[line]; markers[line] = NULL; } } } return someChanges; } void LineMarkers::DeleteMarkFromHandle(int markerHandle) { int line = LineFromHandle(markerHandle); if (line >= 0) { markers[line]->RemoveHandle(markerHandle); if (markers[line]->Length() == 0) { delete markers[line]; markers[line] = NULL; } } } LineLevels::~LineLevels() { } void LineLevels::Init() { levels.DeleteAll(); } void LineLevels::InsertLine(int line) { if (levels.Length()) { int level = (line < levels.Length()) ? levels[line] : SC_FOLDLEVELBASE; levels.InsertValue(line, 1, level); } } void LineLevels::RemoveLine(int line) { if (levels.Length()) { // Move up following lines but merge header flag from this line // to line before to avoid a temporary disappearence causing expansion. int firstHeader = levels[line] & SC_FOLDLEVELHEADERFLAG; levels.Delete(line); if (line == levels.Length()-1) // Last line loses the header flag levels[line-1] &= ~SC_FOLDLEVELHEADERFLAG; else if (line > 0) levels[line-1] |= firstHeader; } } void LineLevels::ExpandLevels(int sizeNew) { levels.InsertValue(levels.Length(), sizeNew - levels.Length(), SC_FOLDLEVELBASE); } void LineLevels::ClearLevels() { levels.DeleteAll(); } int LineLevels::SetLevel(int line, int level, int lines) { int prev = 0; if ((line >= 0) && (line < lines)) { if (!levels.Length()) { ExpandLevels(lines + 1); } prev = levels[line]; if (prev != level) { levels[line] = level; } } return prev; } int LineLevels::GetLevel(int line) { if (levels.Length() && (line >= 0) && (line < levels.Length())) { return levels[line]; } else { return SC_FOLDLEVELBASE; } } LineState::~LineState() { } void LineState::Init() { lineStates.DeleteAll(); } void LineState::InsertLine(int line) { if (lineStates.Length()) { lineStates.EnsureLength(line); int val = (line < lineStates.Length()) ? lineStates[line] : 0; lineStates.Insert(line, val); } } void LineState::RemoveLine(int line) { if (lineStates.Length() > line) { lineStates.Delete(line); } } int LineState::SetLineState(int line, int state) { lineStates.EnsureLength(line + 1); int stateOld = lineStates[line]; lineStates[line] = state; return stateOld; } int LineState::GetLineState(int line) { if (line < 0) return 0; lineStates.EnsureLength(line + 1); return lineStates[line]; } int LineState::GetMaxLineState() { return lineStates.Length(); } static int NumberLines(const char *text) { if (text) { int newLines = 0; while (*text) { if (*text == '\n') newLines++; text++; } return newLines+1; } else { return 0; } } // Each allocated LineAnnotation is a char array which starts with an AnnotationHeader // and then has text and optional styles. static const int IndividualStyles = 0x100; struct AnnotationHeader { short style; // Style IndividualStyles implies array of styles short lines; int length; }; LineAnnotation::~LineAnnotation() { ClearAll(); } void LineAnnotation::Init() { ClearAll(); } void LineAnnotation::InsertLine(int line) { if (annotations.Length()) { annotations.EnsureLength(line); annotations.Insert(line, 0); } } void LineAnnotation::RemoveLine(int line) { if (annotations.Length() && (line < annotations.Length())) { delete []annotations[line]; annotations.Delete(line); } } bool LineAnnotation::AnySet() const { return annotations.Length() > 0; } bool LineAnnotation::MultipleStyles(int line) const { if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) return reinterpret_cast<AnnotationHeader *>(annotations[line])->style == IndividualStyles; else return 0; } int LineAnnotation::Style(int line) { if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) return reinterpret_cast<AnnotationHeader *>(annotations[line])->style; else return 0; } const char *LineAnnotation::Text(int line) const { if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) return annotations[line]+sizeof(AnnotationHeader); else return 0; } const unsigned char *LineAnnotation::Styles(int line) const { if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line] && MultipleStyles(line)) return reinterpret_cast<unsigned char *>(annotations[line] + sizeof(AnnotationHeader) + Length(line)); else return 0; } static char *AllocateAnnotation(int length, int style) { size_t len = sizeof(AnnotationHeader) + length + ((style == IndividualStyles) ? length : 0); char *ret = new char[len]; memset(ret, 0, len); return ret; } void LineAnnotation::SetText(int line, const char *text) { if (text && (line >= 0)) { annotations.EnsureLength(line+1); int style = Style(line); if (annotations[line]) { delete []annotations[line]; } annotations[line] = AllocateAnnotation(static_cast<int>(strlen(text)), style); AnnotationHeader *pah = reinterpret_cast<AnnotationHeader *>(annotations[line]); pah->style = static_cast<short>(style); pah->length = static_cast<int>(strlen(text)); pah->lines = static_cast<short>(NumberLines(text)); memcpy(annotations[line]+sizeof(AnnotationHeader), text, pah->length); } else { if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) { delete []annotations[line]; annotations[line] = 0; } } } void LineAnnotation::ClearAll() { for (int line = 0; line < annotations.Length(); line++) { delete []annotations[line]; annotations[line] = 0; } annotations.DeleteAll(); } void LineAnnotation::SetStyle(int line, int style) { annotations.EnsureLength(line+1); if (!annotations[line]) { annotations[line] = AllocateAnnotation(0, style); } reinterpret_cast<AnnotationHeader *>(annotations[line])->style = static_cast<short>(style); } void LineAnnotation::SetStyles(int line, const unsigned char *styles) { if (line >= 0) { annotations.EnsureLength(line+1); if (!annotations[line]) { annotations[line] = AllocateAnnotation(0, IndividualStyles); } else { AnnotationHeader *pahSource = reinterpret_cast<AnnotationHeader *>(annotations[line]); if (pahSource->style != IndividualStyles) { char *allocation = AllocateAnnotation(pahSource->length, IndividualStyles); AnnotationHeader *pahAlloc = reinterpret_cast<AnnotationHeader *>(allocation); pahAlloc->length = pahSource->length; pahAlloc->lines = pahSource->lines; memcpy(allocation + sizeof(AnnotationHeader), annotations[line] + sizeof(AnnotationHeader), pahSource->length); delete []annotations[line]; annotations[line] = allocation; } } AnnotationHeader *pah = reinterpret_cast<AnnotationHeader *>(annotations[line]); pah->style = IndividualStyles; memcpy(annotations[line] + sizeof(AnnotationHeader) + pah->length, styles, pah->length); } } int LineAnnotation::Length(int line) const { if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) return reinterpret_cast<AnnotationHeader *>(annotations[line])->length; else return 0; } int LineAnnotation::Lines(int line) const { if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) return reinterpret_cast<AnnotationHeader *>(annotations[line])->lines; else return 0; } |
Added src/PerLine.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
// Scintilla source code edit control /** @file PerLine.h ** Manages data associated with each line of the document **/ // Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef PERLINE_H #define PERLINE_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif /** * This holds the marker identifier and the marker type to display. * MarkerHandleNumbers are members of lists. */ struct MarkerHandleNumber { int handle; int number; MarkerHandleNumber *next; }; /** * A marker handle set contains any number of MarkerHandleNumbers. */ class MarkerHandleSet { MarkerHandleNumber *root; public: MarkerHandleSet(); ~MarkerHandleSet(); int Length() const; int NumberFromHandle(int handle) const; int MarkValue() const; ///< Bit set of marker numbers. bool Contains(int handle) const; bool InsertHandle(int handle, int markerNum); void RemoveHandle(int handle); bool RemoveNumber(int markerNum, bool all); void CombineWith(MarkerHandleSet *other); }; class LineMarkers : public PerLine { SplitVector<MarkerHandleSet *> markers; /// Handles are allocated sequentially and should never have to be reused as 32 bit ints are very big. int handleCurrent; public: LineMarkers() : handleCurrent(0) { } virtual ~LineMarkers(); virtual void Init(); virtual void InsertLine(int line); virtual void RemoveLine(int line); int MarkValue(int line); int MarkerNext(int lineStart, int mask) const; int AddMark(int line, int marker, int lines); void MergeMarkers(int pos); bool DeleteMark(int line, int markerNum, bool all); void DeleteMarkFromHandle(int markerHandle); int LineFromHandle(int markerHandle); }; class LineLevels : public PerLine { SplitVector<int> levels; public: virtual ~LineLevels(); virtual void Init(); virtual void InsertLine(int line); virtual void RemoveLine(int line); void ExpandLevels(int sizeNew=-1); void ClearLevels(); int SetLevel(int line, int level, int lines); int GetLevel(int line); }; class LineState : public PerLine { SplitVector<int> lineStates; public: LineState() { } virtual ~LineState(); virtual void Init(); virtual void InsertLine(int line); virtual void RemoveLine(int line); int SetLineState(int line, int state); int GetLineState(int line); int GetMaxLineState(); }; class LineAnnotation : public PerLine { SplitVector<char *> annotations; public: LineAnnotation() { } virtual ~LineAnnotation(); virtual void Init(); virtual void InsertLine(int line); virtual void RemoveLine(int line); bool AnySet() const; bool MultipleStyles(int line) const; int Style(int line); const char *Text(int line) const; const unsigned char *Styles(int line) const; void SetText(int line, const char *text); void ClearAll(); void SetStyle(int line, int style); void SetStyles(int line, const unsigned char *styles); int Length(int line) const; int Lines(int line) const; }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/PositionCache.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 |
// Scintilla source code edit control /** @file PositionCache.cxx ** Classes for caching layout information. **/ // Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <ctype.h> #include <string> #include <vector> #include <map> #include "Platform.h" #include "Scintilla.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" #include "ContractionState.h" #include "CellBuffer.h" #include "KeyMap.h" #include "Indicator.h" #include "XPM.h" #include "LineMarker.h" #include "Style.h" #include "ViewStyle.h" #include "CharClassify.h" #include "Decoration.h" #include "ILexer.h" #include "Document.h" #include "Selection.h" #include "PositionCache.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static inline bool IsControlCharacter(int ch) { // iscntrl returns true for lots of chars > 127 which are displayable return ch >= 0 && ch < ' '; } LineLayout::LineLayout(int maxLineLength_) : lineStarts(0), lenLineStarts(0), lineNumber(-1), inCache(false), maxLineLength(-1), numCharsInLine(0), numCharsBeforeEOL(0), validity(llInvalid), xHighlightGuide(0), highlightColumn(0), psel(NULL), containsCaret(false), edgeColumn(0), chars(0), styles(0), styleBitsSet(0), indicators(0), positions(0), hsStart(0), hsEnd(0), widthLine(wrapWidthInfinite), lines(1), wrapIndent(0) { bracePreviousStyles[0] = 0; bracePreviousStyles[1] = 0; Resize(maxLineLength_); } LineLayout::~LineLayout() { Free(); } void LineLayout::Resize(int maxLineLength_) { if (maxLineLength_ > maxLineLength) { Free(); chars = new char[maxLineLength_ + 1]; styles = new unsigned char[maxLineLength_ + 1]; indicators = new char[maxLineLength_ + 1]; // Extra position allocated as sometimes the Windows // GetTextExtentExPoint API writes an extra element. positions = new XYPOSITION[maxLineLength_ + 1 + 1]; maxLineLength = maxLineLength_; } } void LineLayout::Free() { delete []chars; chars = 0; delete []styles; styles = 0; delete []indicators; indicators = 0; delete []positions; positions = 0; delete []lineStarts; lineStarts = 0; } void LineLayout::Invalidate(validLevel validity_) { if (validity > validity_) validity = validity_; } int LineLayout::LineStart(int line) const { if (line <= 0) { return 0; } else if ((line >= lines) || !lineStarts) { return numCharsInLine; } else { return lineStarts[line]; } } int LineLayout::LineLastVisible(int line) const { if (line < 0) { return 0; } else if ((line >= lines-1) || !lineStarts) { return numCharsBeforeEOL; } else { return lineStarts[line+1]; } } bool LineLayout::InLine(int offset, int line) const { return ((offset >= LineStart(line)) && (offset < LineStart(line + 1))) || ((offset == numCharsInLine) && (line == (lines-1))); } void LineLayout::SetLineStart(int line, int start) { if ((line >= lenLineStarts) && (line != 0)) { int newMaxLines = line + 20; int *newLineStarts = new int[newMaxLines]; for (int i = 0; i < newMaxLines; i++) { if (i < lenLineStarts) newLineStarts[i] = lineStarts[i]; else newLineStarts[i] = 0; } delete []lineStarts; lineStarts = newLineStarts; lenLineStarts = newMaxLines; } lineStarts[line] = start; } void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[], char bracesMatchStyle, int xHighlight, bool ignoreStyle) { if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) { int braceOffset = braces[0] - rangeLine.start; if (braceOffset < numCharsInLine) { bracePreviousStyles[0] = styles[braceOffset]; styles[braceOffset] = bracesMatchStyle; } } if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) { int braceOffset = braces[1] - rangeLine.start; if (braceOffset < numCharsInLine) { bracePreviousStyles[1] = styles[braceOffset]; styles[braceOffset] = bracesMatchStyle; } } if ((braces[0] >= rangeLine.start && braces[1] <= rangeLine.end) || (braces[1] >= rangeLine.start && braces[0] <= rangeLine.end)) { xHighlightGuide = xHighlight; } } void LineLayout::RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle) { if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) { int braceOffset = braces[0] - rangeLine.start; if (braceOffset < numCharsInLine) { styles[braceOffset] = bracePreviousStyles[0]; } } if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) { int braceOffset = braces[1] - rangeLine.start; if (braceOffset < numCharsInLine) { styles[braceOffset] = bracePreviousStyles[1]; } } xHighlightGuide = 0; } int LineLayout::FindBefore(XYPOSITION x, int lower, int upper) const { do { int middle = (upper + lower + 1) / 2; // Round high XYPOSITION posMiddle = positions[middle]; if (x < posMiddle) { upper = middle - 1; } else { lower = middle; } } while (lower < upper); return lower; } int LineLayout::EndLineStyle() const { return styles[numCharsBeforeEOL > 0 ? numCharsBeforeEOL-1 : 0]; } LineLayoutCache::LineLayoutCache() : level(0), length(0), size(0), cache(0), allInvalidated(false), styleClock(-1), useCount(0) { Allocate(0); } LineLayoutCache::~LineLayoutCache() { Deallocate(); } void LineLayoutCache::Allocate(int length_) { PLATFORM_ASSERT(cache == NULL); allInvalidated = false; length = length_; size = length; if (size > 1) { size = (size / 16 + 1) * 16; } if (size > 0) { cache = new LineLayout * [size]; } for (int i = 0; i < size; i++) cache[i] = 0; } void LineLayoutCache::AllocateForLevel(int linesOnScreen, int linesInDoc) { PLATFORM_ASSERT(useCount == 0); int lengthForLevel = 0; if (level == llcCaret) { lengthForLevel = 1; } else if (level == llcPage) { lengthForLevel = linesOnScreen + 1; } else if (level == llcDocument) { lengthForLevel = linesInDoc; } if (lengthForLevel > size) { Deallocate(); Allocate(lengthForLevel); } else { if (lengthForLevel < length) { for (int i = lengthForLevel; i < length; i++) { delete cache[i]; cache[i] = 0; } } length = lengthForLevel; } PLATFORM_ASSERT(length == lengthForLevel); PLATFORM_ASSERT(cache != NULL || length == 0); } void LineLayoutCache::Deallocate() { PLATFORM_ASSERT(useCount == 0); for (int i = 0; i < length; i++) delete cache[i]; delete []cache; cache = 0; length = 0; size = 0; } void LineLayoutCache::Invalidate(LineLayout::validLevel validity_) { if (cache && !allInvalidated) { for (int i = 0; i < length; i++) { if (cache[i]) { cache[i]->Invalidate(validity_); } } if (validity_ == LineLayout::llInvalid) { allInvalidated = true; } } } void LineLayoutCache::SetLevel(int level_) { allInvalidated = false; if ((level_ != -1) && (level != level_)) { level = level_; Deallocate(); } } LineLayout *LineLayoutCache::Retrieve(int lineNumber, int lineCaret, int maxChars, int styleClock_, int linesOnScreen, int linesInDoc) { AllocateForLevel(linesOnScreen, linesInDoc); if (styleClock != styleClock_) { Invalidate(LineLayout::llCheckTextAndStyle); styleClock = styleClock_; } allInvalidated = false; int pos = -1; LineLayout *ret = 0; if (level == llcCaret) { pos = 0; } else if (level == llcPage) { if (lineNumber == lineCaret) { pos = 0; } else if (length > 1) { pos = 1 + (lineNumber % (length - 1)); } } else if (level == llcDocument) { pos = lineNumber; } if (pos >= 0) { PLATFORM_ASSERT(useCount == 0); if (cache && (pos < length)) { if (cache[pos]) { if ((cache[pos]->lineNumber != lineNumber) || (cache[pos]->maxLineLength < maxChars)) { delete cache[pos]; cache[pos] = 0; } } if (!cache[pos]) { cache[pos] = new LineLayout(maxChars); } if (cache[pos]) { cache[pos]->lineNumber = lineNumber; cache[pos]->inCache = true; ret = cache[pos]; useCount++; } } } if (!ret) { ret = new LineLayout(maxChars); ret->lineNumber = lineNumber; } return ret; } void LineLayoutCache::Dispose(LineLayout *ll) { allInvalidated = false; if (ll) { if (!ll->inCache) { delete ll; } else { useCount--; } } } void BreakFinder::Insert(int val) { // Expand if needed if (saeLen >= saeSize) { saeSize *= 2; int *selAndEdgeNew = new int[saeSize]; for (unsigned int j = 0; j<saeLen; j++) { selAndEdgeNew[j] = selAndEdge[j]; } delete []selAndEdge; selAndEdge = selAndEdgeNew; } if (val >= nextBreak) { for (unsigned int j = 0; j<saeLen; j++) { if (val == selAndEdge[j]) { return; } if (val < selAndEdge[j]) { for (unsigned int k = saeLen; k>j; k--) { selAndEdge[k] = selAndEdge[k-1]; } saeLen++; selAndEdge[j] = val; return; } } // Not less than any so append selAndEdge[saeLen++] = val; } } extern bool BadUTF(const char *s, int len, int &trailBytes); static int NextBadU(const char *s, int p, int len, int &trailBytes) { while (p < len) { p++; if (BadUTF(s + p, len - p, trailBytes)) return p; } return -1; } BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, int xStart, bool breakForSelection, Document *pdoc_) : ll(ll_), lineStart(lineStart_), lineEnd(lineEnd_), posLineStart(posLineStart_), nextBreak(lineStart_), saeSize(0), saeLen(0), saeCurrentPos(0), saeNext(0), subBreak(-1), pdoc(pdoc_) { saeSize = 8; selAndEdge = new int[saeSize]; for (unsigned int j=0; j < saeSize; j++) { selAndEdge[j] = 0; } // Search for first visible break // First find the first visible character nextBreak = ll->FindBefore(xStart, lineStart, lineEnd); // Now back to a style break while ((nextBreak > lineStart) && (ll->styles[nextBreak] == ll->styles[nextBreak - 1])) { nextBreak--; } if (breakForSelection) { SelectionPosition posStart(posLineStart); SelectionPosition posEnd(posLineStart + lineEnd); SelectionSegment segmentLine(posStart, posEnd); for (size_t r=0; r<ll->psel->Count(); r++) { SelectionSegment portion = ll->psel->Range(r).Intersect(segmentLine); if (!(portion.start == portion.end)) { if (portion.start.IsValid()) Insert(portion.start.Position() - posLineStart - 1); if (portion.end.IsValid()) Insert(portion.end.Position() - posLineStart - 1); } } } Insert(ll->edgeColumn - 1); Insert(lineEnd - 1); if (pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage)) { int trailBytes=0; for (int pos = -1;;) { pos = NextBadU(ll->chars, pos, lineEnd, trailBytes); if (pos < 0) break; Insert(pos-1); Insert(pos); } } saeNext = (saeLen > 0) ? selAndEdge[0] : -1; } BreakFinder::~BreakFinder() { delete []selAndEdge; } int BreakFinder::First() const { return nextBreak; } int BreakFinder::Next() { if (subBreak == -1) { int prev = nextBreak; while (nextBreak < lineEnd) { if ((ll->styles[nextBreak] != ll->styles[nextBreak + 1]) || (nextBreak == saeNext) || IsControlCharacter(ll->chars[nextBreak]) || IsControlCharacter(ll->chars[nextBreak + 1])) { if (nextBreak == saeNext) { saeCurrentPos++; saeNext = (saeLen > saeCurrentPos) ? selAndEdge[saeCurrentPos] : -1; } nextBreak++; if ((nextBreak - prev) < lengthStartSubdivision) { return nextBreak; } break; } nextBreak++; } if ((nextBreak - prev) < lengthStartSubdivision) { return nextBreak; } subBreak = prev; } // Splitting up a long run from prev to nextBreak in lots of approximately lengthEachSubdivision. // For very long runs add extra breaks after spaces or if no spaces before low punctuation. if ((nextBreak - subBreak) <= lengthEachSubdivision) { subBreak = -1; return nextBreak; } else { subBreak += pdoc->SafeSegment(ll->chars + subBreak, nextBreak-subBreak, lengthEachSubdivision); if (subBreak >= nextBreak) { subBreak = -1; return nextBreak; } else { return subBreak; } } } PositionCacheEntry::PositionCacheEntry() : styleNumber(0), len(0), clock(0), positions(0) { } void PositionCacheEntry::Set(unsigned int styleNumber_, const char *s_, unsigned int len_, XYPOSITION *positions_, unsigned int clock_) { Clear(); styleNumber = styleNumber_; len = len_; clock = clock_; if (s_ && positions_) { positions = new XYPOSITION[len + (len + 1) / 2]; for (unsigned int i=0; i<len; i++) { positions[i] = static_cast<XYPOSITION>(positions_[i]); } memcpy(reinterpret_cast<char *>(positions + len), s_, len); } } PositionCacheEntry::~PositionCacheEntry() { Clear(); } void PositionCacheEntry::Clear() { delete []positions; positions = 0; styleNumber = 0; len = 0; clock = 0; } bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, XYPOSITION *positions_) const { if ((styleNumber == styleNumber_) && (len == len_) && (memcmp(reinterpret_cast<char *>(positions + len), s_, len)== 0)) { for (unsigned int i=0; i<len; i++) { positions_[i] = positions[i]; } return true; } else { return false; } } int PositionCacheEntry::Hash(unsigned int styleNumber_, const char *s, unsigned int len_) { unsigned int ret = s[0] << 7; for (unsigned int i=0; i<len_; i++) { ret *= 1000003; ret ^= s[i]; } ret *= 1000003; ret ^= len_; ret *= 1000003; ret ^= styleNumber_; return ret; } bool PositionCacheEntry::NewerThan(const PositionCacheEntry &other) const { return clock > other.clock; } void PositionCacheEntry::ResetClock() { if (clock > 0) { clock = 1; } } PositionCache::PositionCache() { size = 0x400; clock = 1; pces = new PositionCacheEntry[size]; allClear = true; } PositionCache::~PositionCache() { Clear(); delete []pces; } void PositionCache::Clear() { if (!allClear) { for (size_t i=0; i<size; i++) { pces[i].Clear(); } } clock = 1; allClear = true; } void PositionCache::SetSize(size_t size_) { Clear(); delete []pces; size = size_; pces = new PositionCacheEntry[size]; } void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber, const char *s, unsigned int len, XYPOSITION *positions, Document *pdoc) { allClear = false; int probe = -1; if ((size > 0) && (len < 30)) { // Only store short strings in the cache so it doesn't churn with // long comments with only a single comment. // Two way associative: try two probe positions. int hashValue = PositionCacheEntry::Hash(styleNumber, s, len); probe = static_cast<int>(hashValue % size); if (pces[probe].Retrieve(styleNumber, s, len, positions)) { return; } int probe2 = static_cast<int>((hashValue * 37) % size); if (pces[probe2].Retrieve(styleNumber, s, len, positions)) { return; } // Not found. Choose the oldest of the two slots to replace if (pces[probe].NewerThan(pces[probe2])) { probe = probe2; } } if (len > BreakFinder::lengthStartSubdivision) { // Break up into segments unsigned int startSegment = 0; XYPOSITION xStartSegment = 0; while (startSegment < len) { unsigned int lenSegment = pdoc->SafeSegment(s + startSegment, len - startSegment, BreakFinder::lengthEachSubdivision); surface->MeasureWidths(vstyle.styles[styleNumber].font, s + startSegment, lenSegment, positions + startSegment); for (unsigned int inSeg = 0; inSeg < lenSegment; inSeg++) { positions[startSegment + inSeg] += xStartSegment; } xStartSegment = positions[startSegment + lenSegment - 1]; startSegment += lenSegment; } } else { surface->MeasureWidths(vstyle.styles[styleNumber].font, s, len, positions); } if (probe >= 0) { clock++; if (clock > 60000) { // Since there are only 16 bits for the clock, wrap it round and // reset all cache entries so none get stuck with a high clock. for (size_t i=0; i<size; i++) { pces[i].ResetClock(); } clock = 2; } pces[probe].Set(styleNumber, s, len, positions, clock); } } |
Added src/PositionCache.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
// Scintilla source code edit control /** @file PositionCache.h ** Classes for caching layout information. **/ // Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef POSITIONCACHE_H #define POSITIONCACHE_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif static inline bool IsEOLChar(char ch) { return (ch == '\r') || (ch == '\n'); } /** */ class LineLayout { private: friend class LineLayoutCache; int *lineStarts; int lenLineStarts; /// Drawing is only performed for @a maxLineLength characters on each line. int lineNumber; bool inCache; public: enum { wrapWidthInfinite = 0x7ffffff }; int maxLineLength; int numCharsInLine; int numCharsBeforeEOL; enum validLevel { llInvalid, llCheckTextAndStyle, llPositions, llLines } validity; int xHighlightGuide; bool highlightColumn; Selection *psel; bool containsCaret; int edgeColumn; char *chars; unsigned char *styles; int styleBitsSet; char *indicators; XYPOSITION *positions; char bracePreviousStyles[2]; // Hotspot support int hsStart; int hsEnd; // Wrapped line support int widthLine; int lines; XYPOSITION wrapIndent; // In pixels LineLayout(int maxLineLength_); virtual ~LineLayout(); void Resize(int maxLineLength_); void Free(); void Invalidate(validLevel validity_); int LineStart(int line) const; int LineLastVisible(int line) const; bool InLine(int offset, int line) const; void SetLineStart(int line, int start); void SetBracesHighlight(Range rangeLine, Position braces[], char bracesMatchStyle, int xHighlight, bool ignoreStyle); void RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle); int FindBefore(XYPOSITION x, int lower, int upper) const; int EndLineStyle() const; }; /** */ class LineLayoutCache { int level; int length; int size; LineLayout **cache; bool allInvalidated; int styleClock; int useCount; void Allocate(int length_); void AllocateForLevel(int linesOnScreen, int linesInDoc); public: LineLayoutCache(); virtual ~LineLayoutCache(); void Deallocate(); enum { llcNone=SC_CACHE_NONE, llcCaret=SC_CACHE_CARET, llcPage=SC_CACHE_PAGE, llcDocument=SC_CACHE_DOCUMENT }; void Invalidate(LineLayout::validLevel validity_); void SetLevel(int level_); int GetLevel() const { return level; } LineLayout *Retrieve(int lineNumber, int lineCaret, int maxChars, int styleClock_, int linesOnScreen, int linesInDoc); void Dispose(LineLayout *ll); }; class PositionCacheEntry { unsigned int styleNumber:8; unsigned int len:8; unsigned int clock:16; XYPOSITION *positions; public: PositionCacheEntry(); ~PositionCacheEntry(); void Set(unsigned int styleNumber_, const char *s_, unsigned int len_, XYPOSITION *positions_, unsigned int clock); void Clear(); bool Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, XYPOSITION *positions_) const; static int Hash(unsigned int styleNumber_, const char *s, unsigned int len); bool NewerThan(const PositionCacheEntry &other) const; void ResetClock(); }; // Class to break a line of text into shorter runs at sensible places. class BreakFinder { LineLayout *ll; int lineStart; int lineEnd; int posLineStart; int nextBreak; int *selAndEdge; unsigned int saeSize; unsigned int saeLen; unsigned int saeCurrentPos; int saeNext; int subBreak; Document *pdoc; void Insert(int val); // Private so BreakFinder objects can not be copied BreakFinder(const BreakFinder &); public: // If a whole run is longer than lengthStartSubdivision then subdivide // into smaller runs at spaces or punctuation. enum { lengthStartSubdivision = 300 }; // Try to make each subdivided run lengthEachSubdivision or shorter. enum { lengthEachSubdivision = 100 }; BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, int xStart, bool breakForSelection, Document *pdoc_); ~BreakFinder(); int First() const; int Next(); }; class PositionCache { PositionCacheEntry *pces; size_t size; unsigned int clock; bool allClear; // Private so PositionCache objects can not be copied PositionCache(const PositionCache &); public: PositionCache(); ~PositionCache(); void Clear(); void SetSize(size_t size_); size_t GetSize() const { return size; } void MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber, const char *s, unsigned int len, XYPOSITION *positions, Document *pdoc); }; inline bool IsSpaceOrTab(int ch) { return ch == ' ' || ch == '\t'; } #ifdef SCI_NAMESPACE } #endif #endif |
Added src/RESearch.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 |
// Scintilla source code edit control /** @file RESearch.cxx ** Regular expression search library. **/ /* * regex - Regular expression pattern matching and replacement * * By: Ozan S. Yigit (oz) * Dept. of Computer Science * York University * * Original code available from http://www.cs.yorku.ca/~oz/ * Translation to C++ by Neil Hodgson neilh@scintilla.org * Removed all use of register. * Converted to modern function prototypes. * Put all global/static variables into an object so this code can be * used from multiple threads, etc. * Some extensions by Philippe Lhoste PhiLho(a)GMX.net * '?' extensions by Michael Mullin masmullin@gmail.com * * These routines are the PUBLIC DOMAIN equivalents of regex * routines as found in 4.nBSD UN*X, with minor extensions. * * These routines are derived from various implementations found * in software tools books, and Conroy's grep. They are NOT derived * from licensed/restricted software. * For more interesting/academic/complicated implementations, * see Henry Spencer's regexp routines, or GNU Emacs pattern * matching module. * * Modification history removed. * * Interfaces: * RESearch::Compile: compile a regular expression into a NFA. * * const char *RESearch::Compile(const char *pattern, int length, * bool caseSensitive, bool posix) * * Returns a short error string if they fail. * * RESearch::Execute: execute the NFA to match a pattern. * * int RESearch::Execute(characterIndexer &ci, int lp, int endp) * * RESearch::Substitute: substitute the matched portions in a new string. * * int RESearch::Substitute(CharacterIndexer &ci, char *src, char *dst) * * re_fail: failure routine for RESearch::Execute. (no longer used) * * void re_fail(char *msg, char op) * * Regular Expressions: * * [1] char matches itself, unless it is a special * character (metachar): . \ [ ] * + ? ^ $ * and ( ) if posix option. * * [2] . matches any character. * * [3] \ matches the character following it, except: * - \a, \b, \f, \n, \r, \t, \v match the corresponding C * escape char, respectively BEL, BS, FF, LF, CR, TAB and VT; * Note that \r and \n are never matched because Scintilla * regex searches are made line per line * (stripped of end-of-line chars). * - if not in posix mode, when followed by a * left or right round bracket (see [8]); * - when followed by a digit 1 to 9 (see [9]); * - when followed by a left or right angle bracket * (see [10]); * - when followed by d, D, s, S, w or W (see [11]); * - when followed by x and two hexa digits (see [12]. * Backslash is used as an escape character for all * other meta-characters, and itself. * * [4] [set] matches one of the characters in the set. * If the first character in the set is "^", * it matches the characters NOT in the set, i.e. * complements the set. A shorthand S-E (start dash end) * is used to specify a set of characters S up to * E, inclusive. S and E must be characters, otherwise * the dash is taken literally (eg. in expression [\d-a]). * The special characters "]" and "-" have no special * meaning if they appear as the first chars in the set. * To include both, put - first: [-]A-Z] * (or just backslash them). * examples: match: * * [-]|] matches these 3 chars, * * []-|] matches from ] to | chars * * [a-z] any lowercase alpha * * [^-]] any char except - and ] * * [^A-Z] any char except uppercase * alpha * * [a-zA-Z] any alpha * * [5] * any regular expression form [1] to [4] * (except [8], [9] and [10] forms of [3]), * followed by closure char (*) * matches zero or more matches of that form. * * [6] + same as [5], except it matches one or more. * * [5-6] Both [5] and [6] are greedy (they match as much as possible). * Unless they are followed by the 'lazy' quantifier (?) * In which case both [5] and [6] try to match as little as possible * * [7] ? same as [5] except it matches zero or one. * * [8] a regular expression in the form [1] to [13], enclosed * as \(form\) (or (form) with posix flag) matches what * form matches. The enclosure creates a set of tags, * used for [9] and for pattern substitution. * The tagged forms are numbered starting from 1. * * [9] a \ followed by a digit 1 to 9 matches whatever a * previously tagged regular expression ([8]) matched. * * [10] \< a regular expression starting with a \< construct * \> and/or ending with a \> construct, restricts the * pattern matching to the beginning of a word, and/or * the end of a word. A word is defined to be a character * string beginning and/or ending with the characters * A-Z a-z 0-9 and _. Scintilla extends this definition * by user setting. The word must also be preceded and/or * followed by any character outside those mentioned. * * [11] \l a backslash followed by d, D, s, S, w or W, * becomes a character class (both inside and * outside sets []). * d: decimal digits * D: any char except decimal digits * s: whitespace (space, \t \n \r \f \v) * S: any char except whitespace (see above) * w: alphanumeric & underscore (changed by user setting) * W: any char except alphanumeric & underscore (see above) * * [12] \xHH a backslash followed by x and two hexa digits, * becomes the character whose Ascii code is equal * to these digits. If not followed by two digits, * it is 'x' char itself. * * [13] a composite regular expression xy where x and y * are in the form [1] to [12] matches the longest * match of x followed by a match for y. * * [14] ^ a regular expression starting with a ^ character * $ and/or ending with a $ character, restricts the * pattern matching to the beginning of the line, * or the end of line. [anchors] Elsewhere in the * pattern, ^ and $ are treated as ordinary characters. * * * Acknowledgements: * * HCR's Hugh Redelmeier has been most helpful in various * stages of development. He convinced me to include BOW * and EOW constructs, originally invented by Rob Pike at * the University of Toronto. * * References: * Software tools Kernighan & Plauger * Software tools in Pascal Kernighan & Plauger * Grep [rsx-11 C dist] David Conroy * ed - text editor Un*x Programmer's Manual * Advanced editing on Un*x B. W. Kernighan * RegExp routines Henry Spencer * * Notes: * * This implementation uses a bit-set representation for character * classes for speed and compactness. Each character is represented * by one bit in a 256-bit block. Thus, CCL always takes a * constant 32 bytes in the internal nfa, and RESearch::Execute does a single * bit comparison to locate the character in the set. * * Examples: * * pattern: foo*.* * compile: CHR f CHR o CLO CHR o END CLO ANY END END * matches: fo foo fooo foobar fobar foxx ... * * pattern: fo[ob]a[rz] * compile: CHR f CHR o CCL bitset CHR a CCL bitset END * matches: fobar fooar fobaz fooaz * * pattern: foo\\+ * compile: CHR f CHR o CHR o CHR \ CLO CHR \ END END * matches: foo\ foo\\ foo\\\ ... * * pattern: \(foo\)[1-3]\1 (same as foo[1-3]foo) * compile: BOT 1 CHR f CHR o CHR o EOT 1 CCL bitset REF 1 END * matches: foo1foo foo2foo foo3foo * * pattern: \(fo.*\)-\1 * compile: BOT 1 CHR f CHR o CLO ANY END EOT 1 CHR - REF 1 END * matches: foo-foo fo-fo fob-fob foobar-foobar ... */ #include <stdlib.h> #include "CharClassify.h" #include "RESearch.h" // Shut up annoying Visual C++ warnings: #ifdef _MSC_VER #pragma warning(disable: 4514) #endif #ifdef SCI_NAMESPACE using namespace Scintilla; #endif #define OKP 1 #define NOP 0 #define CHR 1 #define ANY 2 #define CCL 3 #define BOL 4 #define EOL 5 #define BOT 6 #define EOT 7 #define BOW 8 #define EOW 9 #define REF 10 #define CLO 11 #define CLQ 12 /* 0 to 1 closure */ #define LCLO 13 /* lazy closure */ #define END 0 /* * The following defines are not meant to be changeable. * They are for readability only. */ #define BLKIND 0370 #define BITIND 07 const char bitarr[] = { 1, 2, 4, 8, 16, 32, 64, '\200' }; #define badpat(x) (*nfa = END, x) /* * Character classification table for word boundary operators BOW * and EOW is passed in by the creator of this object (Scintilla * Document). The Document default state is that word chars are: * 0-9, a-z, A-Z and _ */ RESearch::RESearch(CharClassify *charClassTable) { failure = 0; charClass = charClassTable; Init(); } RESearch::~RESearch() { Clear(); } void RESearch::Init() { sta = NOP; /* status of lastpat */ bol = 0; for (int i = 0; i < MAXTAG; i++) pat[i] = 0; for (int j = 0; j < BITBLK; j++) bittab[j] = 0; } void RESearch::Clear() { for (int i = 0; i < MAXTAG; i++) { delete []pat[i]; pat[i] = 0; bopat[i] = NOTFOUND; eopat[i] = NOTFOUND; } } bool RESearch::GrabMatches(CharacterIndexer &ci) { bool success = true; for (unsigned int i = 0; i < MAXTAG; i++) { if ((bopat[i] != NOTFOUND) && (eopat[i] != NOTFOUND)) { unsigned int len = eopat[i] - bopat[i]; pat[i] = new char[len + 1]; if (pat[i]) { for (unsigned int j = 0; j < len; j++) pat[i][j] = ci.CharAt(bopat[i] + j); pat[i][len] = '\0'; } else { success = false; } } } return success; } void RESearch::ChSet(unsigned char c) { bittab[((c) & BLKIND) >> 3] |= bitarr[(c) & BITIND]; } void RESearch::ChSetWithCase(unsigned char c, bool caseSensitive) { if (caseSensitive) { ChSet(c); } else { if ((c >= 'a') && (c <= 'z')) { ChSet(c); ChSet(static_cast<unsigned char>(c - 'a' + 'A')); } else if ((c >= 'A') && (c <= 'Z')) { ChSet(c); ChSet(static_cast<unsigned char>(c - 'A' + 'a')); } else { ChSet(c); } } } unsigned char escapeValue(unsigned char ch) { switch (ch) { case 'a': return '\a'; case 'b': return '\b'; case 'f': return '\f'; case 'n': return '\n'; case 'r': return '\r'; case 't': return '\t'; case 'v': return '\v'; } return 0; } static int GetHexaChar(unsigned char hd1, unsigned char hd2) { int hexValue = 0; if (hd1 >= '0' && hd1 <= '9') { hexValue += 16 * (hd1 - '0'); } else if (hd1 >= 'A' && hd1 <= 'F') { hexValue += 16 * (hd1 - 'A' + 10); } else if (hd1 >= 'a' && hd1 <= 'f') { hexValue += 16 * (hd1 - 'a' + 10); } else return -1; if (hd2 >= '0' && hd2 <= '9') { hexValue += hd2 - '0'; } else if (hd2 >= 'A' && hd2 <= 'F') { hexValue += hd2 - 'A' + 10; } else if (hd2 >= 'a' && hd2 <= 'f') { hexValue += hd2 - 'a' + 10; } else return -1; return hexValue; } /** * Called when the parser finds a backslash not followed * by a valid expression (like \( in non-Posix mode). * @param pattern: pointer on the char after the backslash. * @param incr: (out) number of chars to skip after expression evaluation. * @return the char if it resolves to a simple char, * or -1 for a char class. In this case, bittab is changed. */ int RESearch::GetBackslashExpression( const char *pattern, int &incr) { // Since error reporting is primitive and messages are not used anyway, // I choose to interpret unexpected syntax in a logical way instead // of reporting errors. Otherwise, we can stick on, eg., PCRE behavior. incr = 0; // Most of the time, will skip the char "naturally". int c; int result = -1; unsigned char bsc = *pattern; if (!bsc) { // Avoid overrun result = '\\'; // \ at end of pattern, take it literally return result; } switch (bsc) { case 'a': case 'b': case 'n': case 'f': case 'r': case 't': case 'v': result = escapeValue(bsc); break; case 'x': { unsigned char hd1 = *(pattern + 1); unsigned char hd2 = *(pattern + 2); int hexValue = GetHexaChar(hd1, hd2); if (hexValue >= 0) { result = hexValue; incr = 2; // Must skip the digits } else { result = 'x'; // \x without 2 digits: see it as 'x' } } break; case 'd': for (c = '0'; c <= '9'; c++) { ChSet(static_cast<unsigned char>(c)); } break; case 'D': for (c = 0; c < MAXCHR; c++) { if (c < '0' || c > '9') { ChSet(static_cast<unsigned char>(c)); } } break; case 's': ChSet(' '); ChSet('\t'); ChSet('\n'); ChSet('\r'); ChSet('\f'); ChSet('\v'); break; case 'S': for (c = 0; c < MAXCHR; c++) { if (c != ' ' && !(c >= 0x09 && c <= 0x0D)) { ChSet(static_cast<unsigned char>(c)); } } break; case 'w': for (c = 0; c < MAXCHR; c++) { if (iswordc(static_cast<unsigned char>(c))) { ChSet(static_cast<unsigned char>(c)); } } break; case 'W': for (c = 0; c < MAXCHR; c++) { if (!iswordc(static_cast<unsigned char>(c))) { ChSet(static_cast<unsigned char>(c)); } } break; default: result = bsc; } return result; } const char *RESearch::Compile(const char *pattern, int length, bool caseSensitive, bool posix) { char *mp=nfa; /* nfa pointer */ char *lp; /* saved pointer */ char *sp=nfa; /* another one */ char *mpMax = mp + MAXNFA - BITBLK - 10; int tagi = 0; /* tag stack index */ int tagc = 1; /* actual tag count */ int n; char mask; /* xor mask -CCL/NCL */ int c1, c2, prevChar; if (!pattern || !length) { if (sta) return 0; else return badpat("No previous regular expression"); } sta = NOP; const char *p=pattern; /* pattern pointer */ for (int i=0; i<length; i++, p++) { if (mp > mpMax) return badpat("Pattern too long"); lp = mp; switch (*p) { case '.': /* match any char */ *mp++ = ANY; break; case '^': /* match beginning */ if (p == pattern) *mp++ = BOL; else { *mp++ = CHR; *mp++ = *p; } break; case '$': /* match endofline */ if (!*(p+1)) *mp++ = EOL; else { *mp++ = CHR; *mp++ = *p; } break; case '[': /* match char class */ *mp++ = CCL; prevChar = 0; i++; if (*++p == '^') { mask = '\377'; i++; p++; } else mask = 0; if (*p == '-') { /* real dash */ i++; prevChar = *p; ChSet(*p++); } if (*p == ']') { /* real brace */ i++; prevChar = *p; ChSet(*p++); } while (*p && *p != ']') { if (*p == '-') { if (prevChar < 0) { // Previous def. was a char class like \d, take dash literally prevChar = *p; ChSet(*p); } else if (*(p+1)) { if (*(p+1) != ']') { c1 = prevChar + 1; i++; c2 = static_cast<unsigned char>(*++p); if (c2 == '\\') { if (!*(p+1)) // End of RE return badpat("Missing ]"); else { i++; p++; int incr; c2 = GetBackslashExpression(p, incr); i += incr; p += incr; if (c2 >= 0) { // Convention: \c (c is any char) is case sensitive, whatever the option ChSet(static_cast<unsigned char>(c2)); prevChar = c2; } else { // bittab is already changed prevChar = -1; } } } if (prevChar < 0) { // Char after dash is char class like \d, take dash literally prevChar = '-'; ChSet('-'); } else { // Put all chars between c1 and c2 included in the char set while (c1 <= c2) { ChSetWithCase(static_cast<unsigned char>(c1++), caseSensitive); } } } else { // Dash before the ], take it literally prevChar = *p; ChSet(*p); } } else { return badpat("Missing ]"); } } else if (*p == '\\' && *(p+1)) { i++; p++; int incr; int c = GetBackslashExpression(p, incr); i += incr; p += incr; if (c >= 0) { // Convention: \c (c is any char) is case sensitive, whatever the option ChSet(static_cast<unsigned char>(c)); prevChar = c; } else { // bittab is already changed prevChar = -1; } } else { prevChar = static_cast<unsigned char>(*p); ChSetWithCase(*p, caseSensitive); } i++; p++; } if (!*p) return badpat("Missing ]"); for (n = 0; n < BITBLK; bittab[n++] = 0) *mp++ = static_cast<char>(mask ^ bittab[n]); break; case '*': /* match 0 or more... */ case '+': /* match 1 or more... */ case '?': if (p == pattern) return badpat("Empty closure"); lp = sp; /* previous opcode */ if (*lp == CLO || *lp == LCLO) /* equivalence... */ break; switch (*lp) { case BOL: case BOT: case EOT: case BOW: case EOW: case REF: return badpat("Illegal closure"); default: break; } if (*p == '+') for (sp = mp; lp < sp; lp++) *mp++ = *lp; *mp++ = END; *mp++ = END; sp = mp; while (--mp > lp) *mp = mp[-1]; if (*p == '?') *mp = CLQ; else if (*(p+1) == '?') *mp = LCLO; else *mp = CLO; mp = sp; break; case '\\': /* tags, backrefs... */ i++; switch (*++p) { case '<': *mp++ = BOW; break; case '>': if (*sp == BOW) return badpat("Null pattern inside \\<\\>"); *mp++ = EOW; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = *p-'0'; if (tagi > 0 && tagstk[tagi] == n) return badpat("Cyclical reference"); if (tagc > n) { *mp++ = static_cast<char>(REF); *mp++ = static_cast<char>(n); } else return badpat("Undetermined reference"); break; default: if (!posix && *p == '(') { if (tagc < MAXTAG) { tagstk[++tagi] = tagc; *mp++ = BOT; *mp++ = static_cast<char>(tagc++); } else return badpat("Too many \\(\\) pairs"); } else if (!posix && *p == ')') { if (*sp == BOT) return badpat("Null pattern inside \\(\\)"); if (tagi > 0) { *mp++ = static_cast<char>(EOT); *mp++ = static_cast<char>(tagstk[tagi--]); } else return badpat("Unmatched \\)"); } else { int incr; int c = GetBackslashExpression(p, incr); i += incr; p += incr; if (c >= 0) { *mp++ = CHR; *mp++ = static_cast<unsigned char>(c); } else { *mp++ = CCL; mask = 0; for (n = 0; n < BITBLK; bittab[n++] = 0) *mp++ = static_cast<char>(mask ^ bittab[n]); } } } break; default : /* an ordinary char */ if (posix && *p == '(') { if (tagc < MAXTAG) { tagstk[++tagi] = tagc; *mp++ = BOT; *mp++ = static_cast<char>(tagc++); } else return badpat("Too many () pairs"); } else if (posix && *p == ')') { if (*sp == BOT) return badpat("Null pattern inside ()"); if (tagi > 0) { *mp++ = static_cast<char>(EOT); *mp++ = static_cast<char>(tagstk[tagi--]); } else return badpat("Unmatched )"); } else { unsigned char c = *p; if (!c) // End of RE c = '\\'; // We take it as raw backslash if (caseSensitive || !iswordc(c)) { *mp++ = CHR; *mp++ = c; } else { *mp++ = CCL; mask = 0; ChSetWithCase(c, false); for (n = 0; n < BITBLK; bittab[n++] = 0) *mp++ = static_cast<char>(mask ^ bittab[n]); } } break; } sp = lp; } if (tagi > 0) return badpat((posix ? "Unmatched (" : "Unmatched \\(")); *mp = END; sta = OKP; return 0; } /* * RESearch::Execute: * execute nfa to find a match. * * special cases: (nfa[0]) * BOL * Match only once, starting from the * beginning. * CHR * First locate the character without * calling PMatch, and if found, call * PMatch for the remaining string. * END * RESearch::Compile failed, poor luser did not * check for it. Fail fast. * * If a match is found, bopat[0] and eopat[0] are set * to the beginning and the end of the matched fragment, * respectively. * */ int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) { unsigned char c; int ep = NOTFOUND; char *ap = nfa; bol = lp; failure = 0; Clear(); switch (*ap) { case BOL: /* anchored: match from BOL only */ ep = PMatch(ci, lp, endp, ap); break; case EOL: /* just searching for end of line normal path doesn't work */ if (*(ap+1) == END) { lp = endp; ep = lp; break; } else { return 0; } case CHR: /* ordinary char: locate it fast */ c = *(ap+1); while ((lp < endp) && (static_cast<unsigned char>(ci.CharAt(lp)) != c)) lp++; if (lp >= endp) /* if EOS, fail, else fall thru. */ return 0; default: /* regular matching all the way. */ while (lp < endp) { ep = PMatch(ci, lp, endp, ap); if (ep != NOTFOUND) break; lp++; } break; case END: /* munged automaton. fail always */ return 0; } if (ep == NOTFOUND) return 0; bopat[0] = lp; eopat[0] = ep; return 1; } /* * PMatch: internal routine for the hard part * * This code is partly snarfed from an early grep written by * David Conroy. The backref and tag stuff, and various other * innovations are by oz. * * special case optimizations: (nfa[n], nfa[n+1]) * CLO ANY * We KNOW .* will match everything upto the * end of line. Thus, directly go to the end of * line, without recursive PMatch calls. As in * the other closure cases, the remaining pattern * must be matched by moving backwards on the * string recursively, to find a match for xy * (x is ".*" and y is the remaining pattern) * where the match satisfies the LONGEST match for * x followed by a match for y. * CLO CHR * We can again scan the string forward for the * single char and at the point of failure, we * execute the remaining nfa recursively, same as * above. * * At the end of a successful match, bopat[n] and eopat[n] * are set to the beginning and end of subpatterns matched * by tagged expressions (n = 1 to 9). */ extern void re_fail(char *,char); #define isinset(x,y) ((x)[((y)&BLKIND)>>3] & bitarr[(y)&BITIND]) /* * skip values for CLO XXX to skip past the closure */ #define ANYSKIP 2 /* [CLO] ANY END */ #define CHRSKIP 3 /* [CLO] CHR chr END */ #define CCLSKIP 34 /* [CLO] CCL 32 bytes END */ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) { int op, c, n; int e; /* extra pointer for CLO */ int bp; /* beginning of subpat... */ int ep; /* ending of subpat... */ int are; /* to save the line ptr. */ int llp; /* lazy lp for LCLO */ while ((op = *ap++) != END) switch (op) { case CHR: if (ci.CharAt(lp++) != *ap++) return NOTFOUND; break; case ANY: if (lp++ >= endp) return NOTFOUND; break; case CCL: if (lp >= endp) return NOTFOUND; c = ci.CharAt(lp++); if (!isinset(ap,c)) return NOTFOUND; ap += BITBLK; break; case BOL: if (lp != bol) return NOTFOUND; break; case EOL: if (lp < endp) return NOTFOUND; break; case BOT: bopat[static_cast<int>(*ap++)] = lp; break; case EOT: eopat[static_cast<int>(*ap++)] = lp; break; case BOW: if ((lp!=bol && iswordc(ci.CharAt(lp-1))) || !iswordc(ci.CharAt(lp))) return NOTFOUND; break; case EOW: if (lp==bol || !iswordc(ci.CharAt(lp-1)) || iswordc(ci.CharAt(lp))) return NOTFOUND; break; case REF: n = *ap++; bp = bopat[n]; ep = eopat[n]; while (bp < ep) if (ci.CharAt(bp++) != ci.CharAt(lp++)) return NOTFOUND; break; case LCLO: case CLQ: case CLO: are = lp; switch (*ap) { case ANY: if (op == CLO || op == LCLO) while (lp < endp) lp++; else if (lp < endp) lp++; n = ANYSKIP; break; case CHR: c = *(ap+1); if (op == CLO || op == LCLO) while ((lp < endp) && (c == ci.CharAt(lp))) lp++; else if ((lp < endp) && (c == ci.CharAt(lp))) lp++; n = CHRSKIP; break; case CCL: while ((lp < endp) && isinset(ap+1,ci.CharAt(lp))) lp++; n = CCLSKIP; break; default: failure = true; //re_fail("closure: bad nfa.", *ap); return NOTFOUND; } ap += n; llp = lp; e = NOTFOUND; while (llp >= are) { int q; if ((q = PMatch(ci, llp, endp, ap)) != NOTFOUND) { e = q; lp = llp; if (op != LCLO) return e; } if (*ap == END) return e; --llp; } if (*ap == EOT) PMatch(ci, lp, endp, ap); return e; default: //re_fail("RESearch::Execute: bad nfa.", static_cast<char>(op)); return NOTFOUND; } return lp; } /* * RESearch::Substitute: * substitute the matched portions of the src in dst. * * & substitute the entire matched pattern. * * \digit substitute a subpattern, with the given tag number. * Tags are numbered from 1 to 9. If the particular * tagged subpattern does not exist, null is substituted. */ int RESearch::Substitute(CharacterIndexer &ci, char *src, char *dst) { unsigned char c; int pin; int bp; int ep; if (!*src || !bopat[0]) return 0; while ((c = *src++) != 0) { switch (c) { case '&': pin = 0; break; case '\\': c = *src++; if (c >= '0' && c <= '9') { pin = c - '0'; break; } default: *dst++ = c; continue; } if ((bp = bopat[pin]) != 0 && (ep = eopat[pin]) != 0) { while (ci.CharAt(bp) && bp < ep) *dst++ = ci.CharAt(bp++); if (bp < ep) return 0; } } *dst = '\0'; return 1; } |
Added src/RESearch.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
// Scintilla source code edit control /** @file RESearch.h ** Interface to the regular expression search library. **/ // Written by Neil Hodgson <neilh@scintilla.org> // Based on the work of Ozan S. Yigit. // This file is in the public domain. #ifndef RESEARCH_H #define RESEARCH_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif /* * The following defines are not meant to be changeable. * They are for readability only. */ #define MAXCHR 256 #define CHRBIT 8 #define BITBLK MAXCHR/CHRBIT class CharacterIndexer { public: virtual char CharAt(int index)=0; virtual ~CharacterIndexer() { } }; class RESearch { public: RESearch(CharClassify *charClassTable); ~RESearch(); bool GrabMatches(CharacterIndexer &ci); const char *Compile(const char *pattern, int length, bool caseSensitive, bool posix); int Execute(CharacterIndexer &ci, int lp, int endp); int Substitute(CharacterIndexer &ci, char *src, char *dst); enum { MAXTAG=10 }; enum { MAXNFA=2048 }; enum { NOTFOUND=-1 }; int bopat[MAXTAG]; int eopat[MAXTAG]; char *pat[MAXTAG]; private: void Init(); void Clear(); void ChSet(unsigned char c); void ChSetWithCase(unsigned char c, bool caseSensitive); int GetBackslashExpression(const char *pattern, int &incr); int PMatch(CharacterIndexer &ci, int lp, int endp, char *ap); int bol; int tagstk[MAXTAG]; /* subpat tag stack */ char nfa[MAXNFA]; /* automaton */ int sta; unsigned char bittab[BITBLK]; /* bit table for CCL pre-set bits */ int failure; CharClassify *charClass; bool iswordc(unsigned char x) { return charClass->IsWord(x); } }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/RunStyles.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
/** @file RunStyles.cxx ** Data structure used to store sparse styles. **/ // Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdio.h> #include <string.h> #include <stdlib.h> #include <stdarg.h> #include "Platform.h" #include "Scintilla.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // Find the first run at a position int RunStyles::RunFromPosition(int position) const { int run = starts->PartitionFromPosition(position); // Go to first element with this position while ((run > 0) && (position == starts->PositionFromPartition(run-1))) { run--; } return run; } // If there is no run boundary at position, insert one continuing style. int RunStyles::SplitRun(int position) { int run = RunFromPosition(position); int posRun = starts->PositionFromPartition(run); if (posRun < position) { int runStyle = ValueAt(position); run++; starts->InsertPartition(run, position); styles->InsertValue(run, 1, runStyle); } return run; } void RunStyles::RemoveRun(int run) { starts->RemovePartition(run); styles->DeleteRange(run, 1); } void RunStyles::RemoveRunIfEmpty(int run) { if ((run < starts->Partitions()) && (starts->Partitions() > 1)) { if (starts->PositionFromPartition(run) == starts->PositionFromPartition(run+1)) { RemoveRun(run); } } } void RunStyles::RemoveRunIfSameAsPrevious(int run) { if ((run > 0) && (run < starts->Partitions())) { if (styles->ValueAt(run-1) == styles->ValueAt(run)) { RemoveRun(run); } } } RunStyles::RunStyles() { starts = new Partitioning(8); styles = new SplitVector<int>(); styles->InsertValue(0, 2, 0); } RunStyles::~RunStyles() { delete starts; starts = NULL; delete styles; styles = NULL; } int RunStyles::Length() const { return starts->PositionFromPartition(starts->Partitions()); } int RunStyles::ValueAt(int position) const { return styles->ValueAt(starts->PartitionFromPosition(position)); } int RunStyles::FindNextChange(int position, int end) { int run = starts->PartitionFromPosition(position); if (run < starts->Partitions()) { int runChange = starts->PositionFromPartition(run); if (runChange > position) return runChange; int nextChange = starts->PositionFromPartition(run + 1); if (nextChange > position) { return nextChange; } else if (position < end) { return end; } else { return end + 1; } } else { return end + 1; } } int RunStyles::StartRun(int position) { return starts->PositionFromPartition(starts->PartitionFromPosition(position)); } int RunStyles::EndRun(int position) { return starts->PositionFromPartition(starts->PartitionFromPosition(position) + 1); } bool RunStyles::FillRange(int &position, int value, int &fillLength) { int end = position + fillLength; int runEnd = RunFromPosition(end); if (styles->ValueAt(runEnd) == value) { // End already has value so trim range. end = starts->PositionFromPartition(runEnd); if (position >= end) { // Whole range is already same as value so no action return false; } fillLength = end - position; } else { runEnd = SplitRun(end); } int runStart = RunFromPosition(position); if (styles->ValueAt(runStart) == value) { // Start is in expected value so trim range. runStart++; position = starts->PositionFromPartition(runStart); fillLength = end - position; } else { if (starts->PositionFromPartition(runStart) < position) { runStart = SplitRun(position); runEnd++; } } if (runStart < runEnd) { styles->SetValueAt(runStart, value); // Remove each old run over the range for (int run=runStart+1; run<runEnd; run++) { RemoveRun(runStart+1); } runEnd = RunFromPosition(end); RemoveRunIfSameAsPrevious(runEnd); RemoveRunIfSameAsPrevious(runStart); runEnd = RunFromPosition(end); RemoveRunIfEmpty(runEnd); return true; } else { return false; } } void RunStyles::SetValueAt(int position, int value) { int len = 1; FillRange(position, value, len); } void RunStyles::InsertSpace(int position, int insertLength) { int runStart = RunFromPosition(position); if (starts->PositionFromPartition(runStart) == position) { int runStyle = ValueAt(position); // Inserting at start of run so make previous longer if (runStart == 0) { // Inserting at start of document so ensure 0 if (runStyle) { styles->SetValueAt(0, 0); starts->InsertPartition(1, 0); styles->InsertValue(1, 1, runStyle); starts->InsertText(0, insertLength); } else { starts->InsertText(runStart, insertLength); } } else { if (runStyle) { starts->InsertText(runStart-1, insertLength); } else { // Insert at end of run so do not extend style starts->InsertText(runStart, insertLength); } } } else { starts->InsertText(runStart, insertLength); } } void RunStyles::DeleteAll() { delete starts; starts = NULL; delete styles; styles = NULL; starts = new Partitioning(8); styles = new SplitVector<int>(); styles->InsertValue(0, 2, 0); } void RunStyles::DeleteRange(int position, int deleteLength) { int end = position + deleteLength; int runStart = RunFromPosition(position); int runEnd = RunFromPosition(end); if (runStart == runEnd) { // Deleting from inside one run starts->InsertText(runStart, -deleteLength); RemoveRunIfEmpty(runStart); } else { runStart = SplitRun(position); runEnd = SplitRun(end); starts->InsertText(runStart, -deleteLength); // Remove each old run over the range for (int run=runStart; run<runEnd; run++) { RemoveRun(runStart); } RemoveRunIfEmpty(runStart); RemoveRunIfSameAsPrevious(runStart); } } int RunStyles::Runs() const { return starts->Partitions(); } bool RunStyles::AllSame() const { for (int run = 1; run < starts->Partitions(); run++) { if (styles->ValueAt(run) != styles->ValueAt(run - 1)) return false; } return true; } bool RunStyles::AllSameAs(int value) const { return AllSame() && (styles->ValueAt(0) == value); } int RunStyles::Find(int value, int start) const { if (start < Length()) { int run = start ? RunFromPosition(start) : 0; if (styles->ValueAt(run) == value) return start; run++; while (run < starts->Partitions()) { if (styles->ValueAt(run) == value) return starts->PositionFromPartition(run); run++; } } return -1; } |
Added src/RunStyles.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
/** @file RunStyles.h ** Data structure used to store sparse styles. **/ // Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. /// Styling buffer using one element for each run rather than using /// a filled buffer. #ifndef RUNSTYLES_H #define RUNSTYLES_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif class RunStyles { private: Partitioning *starts; SplitVector<int> *styles; int RunFromPosition(int position) const; int SplitRun(int position); void RemoveRun(int run); void RemoveRunIfEmpty(int run); void RemoveRunIfSameAsPrevious(int run); // Private so RunStyles objects can not be copied RunStyles(const RunStyles &); public: RunStyles(); ~RunStyles(); int Length() const; int ValueAt(int position) const; int FindNextChange(int position, int end); int StartRun(int position); int EndRun(int position); // Returns true if some values may have changed bool FillRange(int &position, int value, int &fillLength); void SetValueAt(int position, int value); void InsertSpace(int position, int insertLength); void DeleteAll(); void DeleteRange(int position, int deleteLength); int Runs() const; bool AllSame() const; bool AllSameAs(int value) const; int Find(int value, int start) const; }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/SVector.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
// Scintilla source code edit control /** @file SVector.h ** A simple expandable vector. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@hare.net.au> // The License.txt file describes the conditions under which this software may be distributed. #ifndef SVECTOR_H #define SVECTOR_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif /** * A simple expandable integer vector. * Storage not allocated for elements until an element is used. * This makes it very lightweight unless used so is a good match for optional features. */ class SVector { enum { allocSize = 4000 }; int *v; ///< The vector unsigned int size; ///< Number of elements allocated unsigned int len; ///< Number of elements used in vector /** Internally allocate more elements than the user wants * to avoid thrashing the memory allocator. */ void SizeTo(int newSize) { if (newSize < allocSize) newSize += allocSize; else newSize = (newSize * 3) / 2; int *newv = new int[newSize]; size = newSize; unsigned int i=0; for (; i<len; i++) { newv[i] = v[i]; } for (; i<size; i++) { newv[i] = 0; } delete []v; v = newv; } public: SVector() { v = 0; len = 0; size = 0; } ~SVector() { Free(); } /// Constructor from another vector. SVector(const SVector &other) { v = 0; len = 0; size = 0; if (other.Length() > 0) { SizeTo(other.Length()); for (int i=0; i<other.Length(); i++) v[i] = other.v[i]; len = other.Length(); } } /// Copy constructor. SVector &operator=(const SVector &other) { if (this != &other) { delete []v; v = 0; len = 0; size = 0; if (other.Length() > 0) { SizeTo(other.Length()); for (int i=0; i<other.Length(); i++) v[i] = other.v[i]; len = other.Length(); } } return *this; } /** @brief Accessor. * Allows to access values from the list, and grows it if accessing * outside the current bounds. The returned value in this case is 0. */ int &operator[](unsigned int i) { if (i >= len) { if (i >= size) { SizeTo(i); } len = i+1; } return v[i]; } /// Reset vector. void Free() { delete []v; v = 0; size = 0; len = 0; } /** @brief Grow vector size. * Doesn't allow a vector to be shrinked. */ void SetLength(unsigned int newLength) { if (newLength > len) { if (newLength >= size) { SizeTo(newLength); } } len = newLength; } /// Get the current length (number of used elements) of the vector. int Length() const { return len; } }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/SciTE.properties.
> > > > > > |
1 2 3 4 5 6 |
# SciTE.properties is the per directory local options file and can be used to override # settings made in SciTEGlobal.properties command.build.directory.*.cxx=..\win32 command.build.directory.*.h=..\win32 command.build.*.cxx=nmake -f scintilla.mak QUIET=1 command.build.*.h=nmake -f scintilla.mak QUIET=1 |
Added src/ScintillaBase.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 |
// Scintilla source code edit control /** @file ScintillaBase.cxx ** An enhanced subclass of Editor with calltips, autocomplete and context menu. **/ // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <ctype.h> #include <assert.h> #include <string> #include <vector> #include <map> #include "Platform.h" #include "ILexer.h" #include "Scintilla.h" #include "PropSetSimple.h" #ifdef SCI_LEXER #include "SciLexer.h" #include "LexerModule.h" #include "Catalogue.h" #endif #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" #include "ContractionState.h" #include "CellBuffer.h" #include "CallTip.h" #include "KeyMap.h" #include "Indicator.h" #include "XPM.h" #include "LineMarker.h" #include "Style.h" #include "ViewStyle.h" #include "AutoComplete.h" #include "CharClassify.h" #include "Decoration.h" #include "Document.h" #include "Selection.h" #include "PositionCache.h" #include "Editor.h" #include "ScintillaBase.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif ScintillaBase::ScintillaBase() { displayPopupMenu = true; listType = 0; maxListWidth = 0; } ScintillaBase::~ScintillaBase() { } void ScintillaBase::Finalise() { Editor::Finalise(); popup.Destroy(); } void ScintillaBase::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) { bool isFillUp = ac.Active() && ac.IsFillUpChar(*s); if (!isFillUp) { Editor::AddCharUTF(s, len, treatAsDBCS); } if (ac.Active()) { AutoCompleteCharacterAdded(s[0]); // For fill ups add the character after the autocompletion has // triggered so containers see the key so can display a calltip. if (isFillUp) { Editor::AddCharUTF(s, len, treatAsDBCS); } } } void ScintillaBase::Command(int cmdId) { switch (cmdId) { case idAutoComplete: // Nothing to do break; case idCallTip: // Nothing to do break; case idcmdUndo: WndProc(SCI_UNDO, 0, 0); break; case idcmdRedo: WndProc(SCI_REDO, 0, 0); break; case idcmdCut: WndProc(SCI_CUT, 0, 0); break; case idcmdCopy: WndProc(SCI_COPY, 0, 0); break; case idcmdPaste: WndProc(SCI_PASTE, 0, 0); break; case idcmdDelete: WndProc(SCI_CLEAR, 0, 0); break; case idcmdSelectAll: WndProc(SCI_SELECTALL, 0, 0); break; } } int ScintillaBase::KeyCommand(unsigned int iMessage) { // Most key commands cancel autocompletion mode if (ac.Active()) { switch (iMessage) { // Except for these case SCI_LINEDOWN: AutoCompleteMove(1); return 0; case SCI_LINEUP: AutoCompleteMove(-1); return 0; case SCI_PAGEDOWN: AutoCompleteMove(ac.lb->GetVisibleRows()); return 0; case SCI_PAGEUP: AutoCompleteMove(-ac.lb->GetVisibleRows()); return 0; case SCI_VCHOME: AutoCompleteMove(-5000); return 0; case SCI_LINEEND: AutoCompleteMove(5000); return 0; case SCI_DELETEBACK: DelCharBack(true); AutoCompleteCharacterDeleted(); EnsureCaretVisible(); return 0; case SCI_DELETEBACKNOTLINE: DelCharBack(false); AutoCompleteCharacterDeleted(); EnsureCaretVisible(); return 0; case SCI_TAB: AutoCompleteCompleted(); return 0; case SCI_NEWLINE: AutoCompleteCompleted(); return 0; default: AutoCompleteCancel(); } } if (ct.inCallTipMode) { if ( (iMessage != SCI_CHARLEFT) && (iMessage != SCI_CHARLEFTEXTEND) && (iMessage != SCI_CHARRIGHT) && (iMessage != SCI_CHARRIGHTEXTEND) && (iMessage != SCI_EDITTOGGLEOVERTYPE) && (iMessage != SCI_DELETEBACK) && (iMessage != SCI_DELETEBACKNOTLINE) ) { ct.CallTipCancel(); } if ((iMessage == SCI_DELETEBACK) || (iMessage == SCI_DELETEBACKNOTLINE)) { if (sel.MainCaret() <= ct.posStartCallTip) { ct.CallTipCancel(); } } } return Editor::KeyCommand(iMessage); } void ScintillaBase::AutoCompleteDoubleClick(void *p) { ScintillaBase *sci = reinterpret_cast<ScintillaBase *>(p); sci->AutoCompleteCompleted(); } void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) { //Platform::DebugPrintf("AutoComplete %s\n", list); ct.CallTipCancel(); if (ac.chooseSingle && (listType == 0)) { if (list && !strchr(list, ac.GetSeparator())) { const char *typeSep = strchr(list, ac.GetTypesep()); int lenInsert = typeSep ? static_cast<int>(typeSep-list) : static_cast<int>(strlen(list)); UndoGroup ug(pdoc); if (ac.ignoreCase) { SetEmptySelection(sel.MainCaret() - lenEntered); pdoc->DeleteChars(sel.MainCaret(), lenEntered); SetEmptySelection(sel.MainCaret()); pdoc->InsertString(sel.MainCaret(), list, lenInsert); SetEmptySelection(sel.MainCaret() + lenInsert); } else { SetEmptySelection(sel.MainCaret()); pdoc->InsertString(sel.MainCaret(), list + lenEntered, lenInsert - lenEntered); SetEmptySelection(sel.MainCaret() + lenInsert - lenEntered); } ac.Cancel(); return; } } ac.Start(wMain, idAutoComplete, sel.MainCaret(), PointMainCaret(), lenEntered, vs.lineHeight, IsUnicodeMode(), technology); PRectangle rcClient = GetClientRectangle(); Point pt = LocationFromPosition(sel.MainCaret() - lenEntered); PRectangle rcPopupBounds = wMain.GetMonitorRect(pt); if (rcPopupBounds.Height() == 0) rcPopupBounds = rcClient; int heightLB = ac.heightLBDefault; int widthLB = ac.widthLBDefault; if (pt.x >= rcClient.right - widthLB) { HorizontalScrollTo(xOffset + pt.x - rcClient.right + widthLB); Redraw(); pt = PointMainCaret(); } PRectangle rcac; rcac.left = pt.x - ac.lb->CaretFromEdge(); if (pt.y >= rcPopupBounds.bottom - heightLB && // Wont fit below. pt.y >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2) { // and there is more room above. rcac.top = pt.y - heightLB; if (rcac.top < rcPopupBounds.top) { heightLB -= (rcPopupBounds.top - rcac.top); rcac.top = rcPopupBounds.top; } } else { rcac.top = pt.y + vs.lineHeight; } rcac.right = rcac.left + widthLB; rcac.bottom = Platform::Minimum(rcac.top + heightLB, rcPopupBounds.bottom); ac.lb->SetPositionRelative(rcac, wMain); ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font); unsigned int aveCharWidth = vs.styles[STYLE_DEFAULT].aveCharWidth; ac.lb->SetAverageCharWidth(aveCharWidth); ac.lb->SetDoubleClickAction(AutoCompleteDoubleClick, this); ac.SetList(list); // Fiddle the position of the list so it is right next to the target and wide enough for all its strings PRectangle rcList = ac.lb->GetDesiredRect(); int heightAlloced = rcList.bottom - rcList.top; widthLB = Platform::Maximum(widthLB, rcList.right - rcList.left); if (maxListWidth != 0) widthLB = Platform::Minimum(widthLB, aveCharWidth*maxListWidth); // Make an allowance for large strings in list rcList.left = pt.x - ac.lb->CaretFromEdge(); rcList.right = rcList.left + widthLB; if (((pt.y + vs.lineHeight) >= (rcPopupBounds.bottom - heightAlloced)) && // Wont fit below. ((pt.y + vs.lineHeight / 2) >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2)) { // and there is more room above. rcList.top = pt.y - heightAlloced; } else { rcList.top = pt.y + vs.lineHeight; } rcList.bottom = rcList.top + heightAlloced; ac.lb->SetPositionRelative(rcList, wMain); ac.Show(true); if (lenEntered != 0) { AutoCompleteMoveToCurrentWord(); } } void ScintillaBase::AutoCompleteCancel() { if (ac.Active()) { SCNotification scn = {0}; scn.nmhdr.code = SCN_AUTOCCANCELLED; scn.wParam = 0; scn.listType = 0; NotifyParent(scn); } ac.Cancel(); } void ScintillaBase::AutoCompleteMove(int delta) { ac.Move(delta); } void ScintillaBase::AutoCompleteMoveToCurrentWord() { std::string wordCurrent = RangeText(ac.posStart - ac.startLen, sel.MainCaret()); ac.Select(wordCurrent.c_str()); } void ScintillaBase::AutoCompleteCharacterAdded(char ch) { if (ac.IsFillUpChar(ch)) { AutoCompleteCompleted(); } else if (ac.IsStopChar(ch)) { AutoCompleteCancel(); } else { AutoCompleteMoveToCurrentWord(); } } void ScintillaBase::AutoCompleteCharacterDeleted() { if (sel.MainCaret() < ac.posStart - ac.startLen) { AutoCompleteCancel(); } else if (ac.cancelAtStartPos && (sel.MainCaret() <= ac.posStart)) { AutoCompleteCancel(); } else { AutoCompleteMoveToCurrentWord(); } SCNotification scn = {0}; scn.nmhdr.code = SCN_AUTOCCHARDELETED; scn.wParam = 0; scn.listType = 0; NotifyParent(scn); } void ScintillaBase::AutoCompleteCompleted() { int item = ac.GetSelection(); if (item == -1) { AutoCompleteCancel(); return; } const std::string selected = ac.GetValue(item); ac.Show(false); SCNotification scn = {0}; scn.nmhdr.code = listType > 0 ? SCN_USERLISTSELECTION : SCN_AUTOCSELECTION; scn.message = 0; scn.wParam = listType; scn.listType = listType; Position firstPos = ac.posStart - ac.startLen; scn.position = firstPos; scn.lParam = firstPos; scn.text = selected.c_str(); NotifyParent(scn); if (!ac.Active()) return; ac.Cancel(); if (listType > 0) return; Position endPos = sel.MainCaret(); if (ac.dropRestOfWord) endPos = pdoc->ExtendWordSelect(endPos, 1, true); if (endPos < firstPos) return; UndoGroup ug(pdoc); if (endPos != firstPos) { pdoc->DeleteChars(firstPos, endPos - firstPos); } SetEmptySelection(ac.posStart); if (item != -1) { pdoc->InsertCString(firstPos, selected.c_str()); SetEmptySelection(firstPos + static_cast<int>(selected.length())); } SetLastXChosen(); } int ScintillaBase::AutoCompleteGetCurrent() { if (!ac.Active()) return -1; return ac.GetSelection(); } int ScintillaBase::AutoCompleteGetCurrentText(char *buffer) { if (ac.Active()) { int item = ac.GetSelection(); if (item != -1) { const std::string selected = ac.GetValue(item); if (buffer != NULL) strcpy(buffer, selected.c_str()); return static_cast<int>(selected.length()); } } if (buffer != NULL) *buffer = '\0'; return 0; } void ScintillaBase::CallTipShow(Point pt, const char *defn) { ac.Cancel(); // If container knows about STYLE_CALLTIP then use it in place of the // STYLE_DEFAULT for the face name, size and character set. Also use it // for the foreground and background colour. int ctStyle = ct.UseStyleCallTip() ? STYLE_CALLTIP : STYLE_DEFAULT; if (ct.UseStyleCallTip()) { ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back); } PRectangle rc = ct.CallTipStart(sel.MainCaret(), pt, vs.lineHeight, defn, vs.styles[ctStyle].fontName, vs.styles[ctStyle].sizeZoomed, CodePage(), vs.styles[ctStyle].characterSet, vs.technology, wMain); // If the call-tip window would be out of the client // space PRectangle rcClient = GetClientRectangle(); int offset = vs.lineHeight + rc.Height(); // adjust so it displays below the text. if (rc.top < rcClient.top) { rc.top += offset; rc.bottom += offset; } // adjust so it displays above the text. if (rc.bottom > rcClient.bottom) { rc.top -= offset; rc.bottom -= offset; } // Now display the window. CreateCallTipWindow(rc); ct.wCallTip.SetPositionRelative(rc, wMain); ct.wCallTip.Show(); } void ScintillaBase::CallTipClick() { SCNotification scn = {0}; scn.nmhdr.code = SCN_CALLTIPCLICK; scn.position = ct.clickPlace; NotifyParent(scn); } void ScintillaBase::ContextMenu(Point pt) { if (displayPopupMenu) { bool writable = !WndProc(SCI_GETREADONLY, 0, 0); popup.CreatePopUp(); AddToPopUp("Undo", idcmdUndo, writable && pdoc->CanUndo()); AddToPopUp("Redo", idcmdRedo, writable && pdoc->CanRedo()); AddToPopUp(""); AddToPopUp("Cut", idcmdCut, writable && !sel.Empty()); AddToPopUp("Copy", idcmdCopy, !sel.Empty()); AddToPopUp("Paste", idcmdPaste, writable && WndProc(SCI_CANPASTE, 0, 0)); AddToPopUp("Delete", idcmdDelete, writable && !sel.Empty()); AddToPopUp(""); AddToPopUp("Select All", idcmdSelectAll); popup.Show(pt, wMain); } } void ScintillaBase::CancelModes() { AutoCompleteCancel(); ct.CallTipCancel(); Editor::CancelModes(); } void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) { CancelModes(); Editor::ButtonDown(pt, curTime, shift, ctrl, alt); } #ifdef SCI_LEXER #ifdef SCI_NAMESPACE namespace Scintilla { #endif class LexState : public LexInterface { const LexerModule *lexCurrent; void SetLexerModule(const LexerModule *lex); PropSetSimple props; int interfaceVersion; public: int lexLanguage; LexState(Document *pdoc_); virtual ~LexState(); void SetLexer(uptr_t wParam); void SetLexerLanguage(const char *languageName); const char *DescribeWordListSets(); void SetWordList(int n, const char *wl); int GetStyleBitsNeeded() const; const char *GetName() const; void *PrivateCall(int operation, void *pointer); const char *PropertyNames(); int PropertyType(const char *name); const char *DescribeProperty(const char *name); void PropSet(const char *key, const char *val); const char *PropGet(const char *key) const; int PropGetInt(const char *key, int defaultValue=0) const; int PropGetExpanded(const char *key, char *result) const; int LineEndTypesSupported(); int AllocateSubStyles(int styleBase, int numberStyles); int SubStylesStart(int styleBase); int SubStylesLength(int styleBase); void FreeSubStyles(); void SetIdentifiers(int style, const char *identifiers); int DistanceToSecondaryStyles(); const char *GetSubStyleBases(); }; #ifdef SCI_NAMESPACE } #endif LexState::LexState(Document *pdoc_) : LexInterface(pdoc_) { lexCurrent = 0; performingStyle = false; interfaceVersion = lvOriginal; lexLanguage = SCLEX_CONTAINER; } LexState::~LexState() { if (instance) { instance->Release(); instance = 0; } } LexState *ScintillaBase::DocumentLexState() { if (!pdoc->pli) { pdoc->pli = new LexState(pdoc); } return static_cast<LexState *>(pdoc->pli); } void LexState::SetLexerModule(const LexerModule *lex) { if (lex != lexCurrent) { if (instance) { instance->Release(); instance = 0; } interfaceVersion = lvOriginal; lexCurrent = lex; if (lexCurrent) { instance = lexCurrent->Create(); interfaceVersion = instance->Version(); } pdoc->LexerChanged(); } } void LexState::SetLexer(uptr_t wParam) { lexLanguage = wParam; if (lexLanguage == SCLEX_CONTAINER) { SetLexerModule(0); } else { const LexerModule *lex = Catalogue::Find(lexLanguage); if (!lex) lex = Catalogue::Find(SCLEX_NULL); SetLexerModule(lex); } } void LexState::SetLexerLanguage(const char *languageName) { const LexerModule *lex = Catalogue::Find(languageName); if (!lex) lex = Catalogue::Find(SCLEX_NULL); if (lex) lexLanguage = lex->GetLanguage(); SetLexerModule(lex); } const char *LexState::DescribeWordListSets() { if (instance) { return instance->DescribeWordListSets(); } else { return 0; } } void LexState::SetWordList(int n, const char *wl) { if (instance) { int firstModification = instance->WordListSet(n, wl); if (firstModification >= 0) { pdoc->ModifiedAt(firstModification); } } } int LexState::GetStyleBitsNeeded() const { return lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5; } const char *LexState::GetName() const { return lexCurrent ? lexCurrent->languageName : ""; } void *LexState::PrivateCall(int operation, void *pointer) { if (pdoc && instance) { return instance->PrivateCall(operation, pointer); } else { return 0; } } const char *LexState::PropertyNames() { if (instance) { return instance->PropertyNames(); } else { return 0; } } int LexState::PropertyType(const char *name) { if (instance) { return instance->PropertyType(name); } else { return SC_TYPE_BOOLEAN; } } const char *LexState::DescribeProperty(const char *name) { if (instance) { return instance->DescribeProperty(name); } else { return 0; } } void LexState::PropSet(const char *key, const char *val) { props.Set(key, val); if (instance) { int firstModification = instance->PropertySet(key, val); if (firstModification >= 0) { pdoc->ModifiedAt(firstModification); } } } const char *LexState::PropGet(const char *key) const { return props.Get(key); } int LexState::PropGetInt(const char *key, int defaultValue) const { return props.GetInt(key, defaultValue); } int LexState::PropGetExpanded(const char *key, char *result) const { return props.GetExpanded(key, result); } int LexState::LineEndTypesSupported() { if (instance && (interfaceVersion >= lvSubStyles)) { return static_cast<ILexerWithSubStyles *>(instance)->LineEndTypesSupported(); } return 0; } int LexState::AllocateSubStyles(int styleBase, int numberStyles) { if (instance && (interfaceVersion >= lvSubStyles)) { return static_cast<ILexerWithSubStyles *>(instance)->AllocateSubStyles(styleBase, numberStyles); } return -1; } int LexState::SubStylesStart(int styleBase) { if (instance && (interfaceVersion >= lvSubStyles)) { return static_cast<ILexerWithSubStyles *>(instance)->SubStylesStart(styleBase); } return -1; } int LexState::SubStylesLength(int styleBase) { if (instance && (interfaceVersion >= lvSubStyles)) { return static_cast<ILexerWithSubStyles *>(instance)->SubStylesLength(styleBase); } return 0; } void LexState::FreeSubStyles() { if (instance && (interfaceVersion >= lvSubStyles)) { static_cast<ILexerWithSubStyles *>(instance)->FreeSubStyles(); } } void LexState::SetIdentifiers(int style, const char *identifiers) { if (instance && (interfaceVersion >= lvSubStyles)) { static_cast<ILexerWithSubStyles *>(instance)->SetIdentifiers(style, identifiers); } } int LexState::DistanceToSecondaryStyles() { if (instance && (interfaceVersion >= lvSubStyles)) { return static_cast<ILexerWithSubStyles *>(instance)->DistanceToSecondaryStyles(); } return 0; } const char *LexState::GetSubStyleBases() { if (instance && (interfaceVersion >= lvSubStyles)) { return static_cast<ILexerWithSubStyles *>(instance)->GetSubStyleBases(); } return ""; } #endif void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) { #ifdef SCI_LEXER if (DocumentLexState()->lexLanguage != SCLEX_CONTAINER) { int lineEndStyled = pdoc->LineFromPosition(pdoc->GetEndStyled()); int endStyled = pdoc->LineStart(lineEndStyled); DocumentLexState()->Colourise(endStyled, endStyleNeeded); return; } #endif Editor::NotifyStyleToNeeded(endStyleNeeded); } void ScintillaBase::NotifyLexerChanged(Document *, void *) { #ifdef SCI_LEXER int bits = DocumentLexState()->GetStyleBitsNeeded(); vs.EnsureStyle((1 << bits) - 1); #endif } sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { switch (iMessage) { case SCI_AUTOCSHOW: listType = 0; AutoCompleteStart(wParam, reinterpret_cast<const char *>(lParam)); break; case SCI_AUTOCCANCEL: ac.Cancel(); break; case SCI_AUTOCACTIVE: return ac.Active(); case SCI_AUTOCPOSSTART: return ac.posStart; case SCI_AUTOCCOMPLETE: AutoCompleteCompleted(); break; case SCI_AUTOCSETSEPARATOR: ac.SetSeparator(static_cast<char>(wParam)); break; case SCI_AUTOCGETSEPARATOR: return ac.GetSeparator(); case SCI_AUTOCSTOPS: ac.SetStopChars(reinterpret_cast<char *>(lParam)); break; case SCI_AUTOCSELECT: ac.Select(reinterpret_cast<char *>(lParam)); break; case SCI_AUTOCGETCURRENT: return AutoCompleteGetCurrent(); case SCI_AUTOCGETCURRENTTEXT: return AutoCompleteGetCurrentText(reinterpret_cast<char *>(lParam)); case SCI_AUTOCSETCANCELATSTART: ac.cancelAtStartPos = wParam != 0; break; case SCI_AUTOCGETCANCELATSTART: return ac.cancelAtStartPos; case SCI_AUTOCSETFILLUPS: ac.SetFillUpChars(reinterpret_cast<char *>(lParam)); break; case SCI_AUTOCSETCHOOSESINGLE: ac.chooseSingle = wParam != 0; break; case SCI_AUTOCGETCHOOSESINGLE: return ac.chooseSingle; case SCI_AUTOCSETIGNORECASE: ac.ignoreCase = wParam != 0; break; case SCI_AUTOCGETIGNORECASE: return ac.ignoreCase; case SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR: ac.ignoreCaseBehaviour = wParam; break; case SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR: return ac.ignoreCaseBehaviour; case SCI_USERLISTSHOW: listType = wParam; AutoCompleteStart(0, reinterpret_cast<const char *>(lParam)); break; case SCI_AUTOCSETAUTOHIDE: ac.autoHide = wParam != 0; break; case SCI_AUTOCGETAUTOHIDE: return ac.autoHide; case SCI_AUTOCSETDROPRESTOFWORD: ac.dropRestOfWord = wParam != 0; break; case SCI_AUTOCGETDROPRESTOFWORD: return ac.dropRestOfWord; case SCI_AUTOCSETMAXHEIGHT: ac.lb->SetVisibleRows(wParam); break; case SCI_AUTOCGETMAXHEIGHT: return ac.lb->GetVisibleRows(); case SCI_AUTOCSETMAXWIDTH: maxListWidth = wParam; break; case SCI_AUTOCGETMAXWIDTH: return maxListWidth; case SCI_REGISTERIMAGE: ac.lb->RegisterImage(wParam, reinterpret_cast<const char *>(lParam)); break; case SCI_REGISTERRGBAIMAGE: ac.lb->RegisterRGBAImage(wParam, sizeRGBAImage.x, sizeRGBAImage.y, reinterpret_cast<unsigned char *>(lParam)); break; case SCI_CLEARREGISTEREDIMAGES: ac.lb->ClearRegisteredImages(); break; case SCI_AUTOCSETTYPESEPARATOR: ac.SetTypesep(static_cast<char>(wParam)); break; case SCI_AUTOCGETTYPESEPARATOR: return ac.GetTypesep(); case SCI_CALLTIPSHOW: CallTipShow(LocationFromPosition(wParam), reinterpret_cast<const char *>(lParam)); break; case SCI_CALLTIPCANCEL: ct.CallTipCancel(); break; case SCI_CALLTIPACTIVE: return ct.inCallTipMode; case SCI_CALLTIPPOSSTART: return ct.posStartCallTip; case SCI_CALLTIPSETHLT: ct.SetHighlight(wParam, lParam); break; case SCI_CALLTIPSETBACK: ct.colourBG = ColourDesired(wParam); vs.styles[STYLE_CALLTIP].back = ct.colourBG; InvalidateStyleRedraw(); break; case SCI_CALLTIPSETFORE: ct.colourUnSel = ColourDesired(wParam); vs.styles[STYLE_CALLTIP].fore = ct.colourUnSel; InvalidateStyleRedraw(); break; case SCI_CALLTIPSETFOREHLT: ct.colourSel = ColourDesired(wParam); InvalidateStyleRedraw(); break; case SCI_CALLTIPUSESTYLE: ct.SetTabSize((int)wParam); InvalidateStyleRedraw(); break; case SCI_CALLTIPSETPOSITION: ct.SetPosition(wParam != 0); InvalidateStyleRedraw(); break; case SCI_USEPOPUP: displayPopupMenu = wParam != 0; break; #ifdef SCI_LEXER case SCI_SETLEXER: DocumentLexState()->SetLexer(wParam); break; case SCI_GETLEXER: return DocumentLexState()->lexLanguage; case SCI_COLOURISE: if (DocumentLexState()->lexLanguage == SCLEX_CONTAINER) { pdoc->ModifiedAt(wParam); NotifyStyleToNeeded((lParam == -1) ? pdoc->Length() : lParam); } else { DocumentLexState()->Colourise(wParam, lParam); } Redraw(); break; case SCI_SETPROPERTY: DocumentLexState()->PropSet(reinterpret_cast<const char *>(wParam), reinterpret_cast<const char *>(lParam)); break; case SCI_GETPROPERTY: return StringResult(lParam, DocumentLexState()->PropGet(reinterpret_cast<const char *>(wParam))); case SCI_GETPROPERTYEXPANDED: return DocumentLexState()->PropGetExpanded(reinterpret_cast<const char *>(wParam), reinterpret_cast<char *>(lParam)); case SCI_GETPROPERTYINT: return DocumentLexState()->PropGetInt(reinterpret_cast<const char *>(wParam), lParam); case SCI_SETKEYWORDS: DocumentLexState()->SetWordList(wParam, reinterpret_cast<const char *>(lParam)); break; case SCI_SETLEXERLANGUAGE: DocumentLexState()->SetLexerLanguage(reinterpret_cast<const char *>(lParam)); break; case SCI_GETLEXERLANGUAGE: return StringResult(lParam, DocumentLexState()->GetName()); case SCI_PRIVATELEXERCALL: return reinterpret_cast<sptr_t>( DocumentLexState()->PrivateCall(wParam, reinterpret_cast<void *>(lParam))); case SCI_GETSTYLEBITSNEEDED: return DocumentLexState()->GetStyleBitsNeeded(); case SCI_PROPERTYNAMES: return StringResult(lParam, DocumentLexState()->PropertyNames()); case SCI_PROPERTYTYPE: return DocumentLexState()->PropertyType(reinterpret_cast<const char *>(wParam)); case SCI_DESCRIBEPROPERTY: return StringResult(lParam, DocumentLexState()->DescribeProperty(reinterpret_cast<const char *>(wParam))); case SCI_DESCRIBEKEYWORDSETS: return StringResult(lParam, DocumentLexState()->DescribeWordListSets()); case SCI_GETLINEENDTYPESSUPPORTED: return DocumentLexState()->LineEndTypesSupported(); case SCI_ALLOCATESUBSTYLES: return DocumentLexState()->AllocateSubStyles(wParam, lParam); case SCI_GETSUBSTYLESSTART: return DocumentLexState()->SubStylesStart(wParam); case SCI_GETSUBSTYLESLENGTH: return DocumentLexState()->SubStylesLength(wParam); case SCI_FREESUBSTYLES: DocumentLexState()->FreeSubStyles(); break; case SCI_SETIDENTIFIERS: DocumentLexState()->SetIdentifiers(wParam, reinterpret_cast<const char *>(lParam)); break; case SCI_DISTANCETOSECONDARYSTYLES: return DocumentLexState()->DistanceToSecondaryStyles(); case SCI_GETSUBSTYLEBASES: return StringResult(lParam, DocumentLexState()->GetSubStyleBases()); #endif default: return Editor::WndProc(iMessage, wParam, lParam); } return 0l; } |
Added src/ScintillaBase.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
// Scintilla source code edit control /** @file ScintillaBase.h ** Defines an enhanced subclass of Editor with calltips, autocomplete and context menu. **/ // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef SCINTILLABASE_H #define SCINTILLABASE_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif #ifdef SCI_LEXER class LexState; #endif /** */ class ScintillaBase : public Editor { // Private so ScintillaBase objects can not be copied ScintillaBase(const ScintillaBase &); ScintillaBase &operator=(const ScintillaBase &); protected: /** Enumeration of commands and child windows. */ enum { idCallTip=1, idAutoComplete=2, idcmdUndo=10, idcmdRedo=11, idcmdCut=12, idcmdCopy=13, idcmdPaste=14, idcmdDelete=15, idcmdSelectAll=16 }; bool displayPopupMenu; Menu popup; AutoComplete ac; CallTip ct; int listType; ///< 0 is an autocomplete list int maxListWidth; /// Maximum width of list, in average character widths #ifdef SCI_LEXER LexState *DocumentLexState(); void SetLexer(uptr_t wParam); void SetLexerLanguage(const char *languageName); void Colourise(int start, int end); #endif ScintillaBase(); virtual ~ScintillaBase(); virtual void Initialise() = 0; virtual void Finalise() = 0; virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false); void Command(int cmdId); virtual void CancelModes(); virtual int KeyCommand(unsigned int iMessage); void AutoCompleteStart(int lenEntered, const char *list); void AutoCompleteCancel(); void AutoCompleteMove(int delta); int AutoCompleteGetCurrent(); int AutoCompleteGetCurrentText(char *buffer); void AutoCompleteCharacterAdded(char ch); void AutoCompleteCharacterDeleted(); void AutoCompleteCompleted(); void AutoCompleteMoveToCurrentWord(); static void AutoCompleteDoubleClick(void *p); void CallTipClick(); void CallTipShow(Point pt, const char *defn); virtual void CreateCallTipWindow(PRectangle rc) = 0; virtual void AddToPopUp(const char *label, int cmd=0, bool enabled=true) = 0; void ContextMenu(Point pt); virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt); void NotifyStyleToNeeded(int endStyleNeeded); void NotifyLexerChanged(Document *doc, void *userData); public: // Public so scintilla_send_message can use it virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/Selection.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
// Scintilla source code edit control /** @file Selection.cxx ** Classes maintaining the selection. **/ // Copyright 2009 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <vector> #include "Platform.h" #include "Scintilla.h" #include "Selection.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int length) { if (position == startChange) { virtualSpace = 0; } if (insertion) { if (position > startChange) { position += length; } } else { if (position > startChange) { int endDeletion = startChange + length; if (position > endDeletion) { position -= length; } else { position = startChange; virtualSpace = 0; } } } } bool SelectionPosition::operator <(const SelectionPosition &other) const { if (position == other.position) return virtualSpace < other.virtualSpace; else return position < other.position; } bool SelectionPosition::operator >(const SelectionPosition &other) const { if (position == other.position) return virtualSpace > other.virtualSpace; else return position > other.position; } bool SelectionPosition::operator <=(const SelectionPosition &other) const { if (position == other.position && virtualSpace == other.virtualSpace) return true; else return other > *this; } bool SelectionPosition::operator >=(const SelectionPosition &other) const { if (position == other.position && virtualSpace == other.virtualSpace) return true; else return *this > other; } int SelectionRange::Length() const { if (anchor > caret) { return anchor.Position() - caret.Position(); } else { return caret.Position() - anchor.Position(); } } bool SelectionRange::Contains(int pos) const { if (anchor > caret) return (pos >= caret.Position()) && (pos <= anchor.Position()); else return (pos >= anchor.Position()) && (pos <= caret.Position()); } bool SelectionRange::Contains(SelectionPosition sp) const { if (anchor > caret) return (sp >= caret) && (sp <= anchor); else return (sp >= anchor) && (sp <= caret); } bool SelectionRange::ContainsCharacter(int posCharacter) const { if (anchor > caret) return (posCharacter >= caret.Position()) && (posCharacter < anchor.Position()); else return (posCharacter >= anchor.Position()) && (posCharacter < caret.Position()); } SelectionSegment SelectionRange::Intersect(SelectionSegment check) const { SelectionSegment inOrder(caret, anchor); if ((inOrder.start <= check.end) || (inOrder.end >= check.start)) { SelectionSegment portion = check; if (portion.start < inOrder.start) portion.start = inOrder.start; if (portion.end > inOrder.end) portion.end = inOrder.end; if (portion.start > portion.end) return SelectionSegment(); else return portion; } else { return SelectionSegment(); } } bool SelectionRange::Trim(SelectionRange range) { SelectionPosition startRange = range.Start(); SelectionPosition endRange = range.End(); SelectionPosition start = Start(); SelectionPosition end = End(); PLATFORM_ASSERT(start <= end); PLATFORM_ASSERT(startRange <= endRange); if ((startRange <= end) && (endRange >= start)) { if ((start > startRange) && (end < endRange)) { // Completely covered by range -> empty at start end = start; } else if ((start < startRange) && (end > endRange)) { // Completely covers range -> empty at start end = start; } else if (start <= startRange) { // Trim end end = startRange; } else { // PLATFORM_ASSERT(end >= endRange); // Trim start start = endRange; } if (anchor > caret) { caret = start; anchor = end; } else { anchor = start; caret = end; } return Empty(); } else { return false; } } // If range is all virtual collapse to start of virtual space void SelectionRange::MinimizeVirtualSpace() { if (caret.Position() == anchor.Position()) { int virtualSpace = caret.VirtualSpace(); if (virtualSpace > anchor.VirtualSpace()) virtualSpace = anchor.VirtualSpace(); caret.SetVirtualSpace(virtualSpace); anchor.SetVirtualSpace(virtualSpace); } } Selection::Selection() : mainRange(0), moveExtends(false), tentativeMain(false), selType(selStream) { AddSelection(SelectionPosition(0)); } Selection::~Selection() { } bool Selection::IsRectangular() const { return (selType == selRectangle) || (selType == selThin); } int Selection::MainCaret() const { return ranges[mainRange].caret.Position(); } int Selection::MainAnchor() const { return ranges[mainRange].anchor.Position(); } SelectionRange &Selection::Rectangular() { return rangeRectangular; } SelectionSegment Selection::Limits() const { if (ranges.empty()) { return SelectionSegment(); } else { SelectionSegment sr(ranges[0].anchor, ranges[0].caret); for (size_t i=1; i<ranges.size(); i++) { sr.Extend(ranges[i].anchor); sr.Extend(ranges[i].caret); } return sr; } } SelectionSegment Selection::LimitsForRectangularElseMain() const { if (IsRectangular()) { return Limits(); } else { return SelectionSegment(ranges[mainRange].caret, ranges[mainRange].anchor); } } size_t Selection::Count() const { return ranges.size(); } size_t Selection::Main() const { return mainRange; } void Selection::SetMain(size_t r) { PLATFORM_ASSERT(r < ranges.size()); mainRange = r; } SelectionRange &Selection::Range(size_t r) { return ranges[r]; } SelectionRange &Selection::RangeMain() { return ranges[mainRange]; } bool Selection::MoveExtends() const { return moveExtends; } void Selection::SetMoveExtends(bool moveExtends_) { moveExtends = moveExtends_; } bool Selection::Empty() const { for (size_t i=0; i<ranges.size(); i++) { if (!ranges[i].Empty()) return false; } return true; } SelectionPosition Selection::Last() const { SelectionPosition lastPosition; for (size_t i=0; i<ranges.size(); i++) { if (lastPosition < ranges[i].caret) lastPosition = ranges[i].caret; if (lastPosition < ranges[i].anchor) lastPosition = ranges[i].anchor; } return lastPosition; } int Selection::Length() const { int len = 0; for (size_t i=0; i<ranges.size(); i++) { len += ranges[i].Length(); } return len; } void Selection::MovePositions(bool insertion, int startChange, int length) { for (size_t i=0; i<ranges.size(); i++) { ranges[i].caret.MoveForInsertDelete(insertion, startChange, length); ranges[i].anchor.MoveForInsertDelete(insertion, startChange, length); } } void Selection::TrimSelection(SelectionRange range) { for (size_t i=0; i<ranges.size();) { if ((i != mainRange) && (ranges[i].Trim(range))) { // Trimmed to empty so remove for (size_t j=i; j<ranges.size()-1; j++) { ranges[j] = ranges[j+1]; if (j == mainRange-1) mainRange--; } ranges.pop_back(); } else { i++; } } } void Selection::SetSelection(SelectionRange range) { ranges.clear(); ranges.push_back(range); mainRange = ranges.size() - 1; } void Selection::AddSelection(SelectionRange range) { TrimSelection(range); ranges.push_back(range); mainRange = ranges.size() - 1; } void Selection::AddSelectionWithoutTrim(SelectionRange range) { ranges.push_back(range); mainRange = ranges.size() - 1; } void Selection::TentativeSelection(SelectionRange range) { if (!tentativeMain) { rangesSaved = ranges; } ranges = rangesSaved; AddSelection(range); TrimSelection(ranges[mainRange]); tentativeMain = true; } void Selection::CommitTentative() { rangesSaved.clear(); tentativeMain = false; } int Selection::CharacterInSelection(int posCharacter) const { for (size_t i=0; i<ranges.size(); i++) { if (ranges[i].ContainsCharacter(posCharacter)) return i == mainRange ? 1 : 2; } return 0; } int Selection::InSelectionForEOL(int pos) const { for (size_t i=0; i<ranges.size(); i++) { if (!ranges[i].Empty() && (pos > ranges[i].Start().Position()) && (pos <= ranges[i].End().Position())) return i == mainRange ? 1 : 2; } return 0; } int Selection::VirtualSpaceFor(int pos) const { int virtualSpace = 0; for (size_t i=0; i<ranges.size(); i++) { if ((ranges[i].caret.Position() == pos) && (virtualSpace < ranges[i].caret.VirtualSpace())) virtualSpace = ranges[i].caret.VirtualSpace(); if ((ranges[i].anchor.Position() == pos) && (virtualSpace < ranges[i].anchor.VirtualSpace())) virtualSpace = ranges[i].anchor.VirtualSpace(); } return virtualSpace; } void Selection::Clear() { ranges.clear(); ranges.push_back(SelectionRange()); mainRange = ranges.size() - 1; selType = selStream; moveExtends = false; ranges[mainRange].Reset(); rangeRectangular.Reset(); } void Selection::RemoveDuplicates() { for (size_t i=0; i<ranges.size()-1; i++) { if (ranges[i].Empty()) { size_t j=i+1; while (j<ranges.size()) { if (ranges[i] == ranges[j]) { ranges.erase(ranges.begin() + j); if (mainRange >= j) mainRange--; } else { j++; } } } } } void Selection::RotateMain() { mainRange = (mainRange + 1) % ranges.size(); } |
Added src/Selection.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
// Scintilla source code edit control /** @file Selection.h ** Classes maintaining the selection. **/ // Copyright 2009 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef SELECTION_H #define SELECTION_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif class SelectionPosition { int position; int virtualSpace; public: explicit SelectionPosition(int position_=INVALID_POSITION, int virtualSpace_=0) : position(position_), virtualSpace(virtualSpace_) { PLATFORM_ASSERT(virtualSpace < 800000); if (virtualSpace < 0) virtualSpace = 0; } void Reset() { position = 0; virtualSpace = 0; } void MoveForInsertDelete(bool insertion, int startChange, int length); bool operator ==(const SelectionPosition &other) const { return position == other.position && virtualSpace == other.virtualSpace; } bool operator <(const SelectionPosition &other) const; bool operator >(const SelectionPosition &other) const; bool operator <=(const SelectionPosition &other) const; bool operator >=(const SelectionPosition &other) const; int Position() const { return position; } void SetPosition(int position_) { position = position_; virtualSpace = 0; } int VirtualSpace() const { return virtualSpace; } void SetVirtualSpace(int virtualSpace_) { PLATFORM_ASSERT(virtualSpace_ < 800000); if (virtualSpace_ >= 0) virtualSpace = virtualSpace_; } void Add(int increment) { position = position + increment; } bool IsValid() const { return position >= 0; } }; // Ordered range to make drawing simpler struct SelectionSegment { SelectionPosition start; SelectionPosition end; SelectionSegment() : start(), end() { } SelectionSegment(SelectionPosition a, SelectionPosition b) { if (a < b) { start = a; end = b; } else { start = b; end = a; } } bool Empty() const { return start == end; } void Extend(SelectionPosition p) { if (start > p) start = p; if (end < p) end = p; } }; struct SelectionRange { SelectionPosition caret; SelectionPosition anchor; SelectionRange() : caret(), anchor() { } SelectionRange(SelectionPosition single) : caret(single), anchor(single) { } SelectionRange(int single) : caret(single), anchor(single) { } SelectionRange(SelectionPosition caret_, SelectionPosition anchor_) : caret(caret_), anchor(anchor_) { } SelectionRange(int caret_, int anchor_) : caret(caret_), anchor(anchor_) { } bool Empty() const { return anchor == caret; } int Length() const; // int Width() const; // Like Length but takes virtual space into account bool operator ==(const SelectionRange &other) const { return caret == other.caret && anchor == other.anchor; } bool operator <(const SelectionRange &other) const { return caret < other.caret || ((caret == other.caret) && (anchor < other.anchor)); } void Reset() { anchor.Reset(); caret.Reset(); } void ClearVirtualSpace() { anchor.SetVirtualSpace(0); caret.SetVirtualSpace(0); } bool Contains(int pos) const; bool Contains(SelectionPosition sp) const; bool ContainsCharacter(int posCharacter) const; SelectionSegment Intersect(SelectionSegment check) const; SelectionPosition Start() const { return (anchor < caret) ? anchor : caret; } SelectionPosition End() const { return (anchor < caret) ? caret : anchor; } bool Trim(SelectionRange range); // If range is all virtual collapse to start of virtual space void MinimizeVirtualSpace(); }; class Selection { std::vector<SelectionRange> ranges; std::vector<SelectionRange> rangesSaved; SelectionRange rangeRectangular; size_t mainRange; bool moveExtends; bool tentativeMain; public: enum selTypes { noSel, selStream, selRectangle, selLines, selThin }; selTypes selType; Selection(); ~Selection(); bool IsRectangular() const; int MainCaret() const; int MainAnchor() const; SelectionRange &Rectangular(); SelectionSegment Limits() const; // This is for when you want to move the caret in response to a // user direction command - for rectangular selections, use the range // that covers all selected text otherwise return the main selection. SelectionSegment LimitsForRectangularElseMain() const; size_t Count() const; size_t Main() const; void SetMain(size_t r); SelectionRange &Range(size_t r); SelectionRange &RangeMain(); bool MoveExtends() const; void SetMoveExtends(bool moveExtends_); bool Empty() const; SelectionPosition Last() const; int Length() const; void MovePositions(bool insertion, int startChange, int length); void TrimSelection(SelectionRange range); void SetSelection(SelectionRange range); void AddSelection(SelectionRange range); void AddSelectionWithoutTrim(SelectionRange range); void TentativeSelection(SelectionRange range); void CommitTentative(); int CharacterInSelection(int posCharacter) const; int InSelectionForEOL(int pos) const; int VirtualSpaceFor(int pos) const; void Clear(); void RemoveDuplicates(); void RotateMain(); bool Tentative() const { return tentativeMain; } std::vector<SelectionRange> RangesCopy() const { return ranges; } }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/SplitVector.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
// Scintilla source code edit control /** @file SplitVector.h ** Main data structure for holding arrays that handle insertions ** and deletions efficiently. **/ // Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef SPLITVECTOR_H #define SPLITVECTOR_H template <typename T> class SplitVector { protected: T *body; int size; int lengthBody; int part1Length; int gapLength; /// invariant: gapLength == size - lengthBody int growSize; /// Move the gap to a particular position so that insertion and /// deletion at that point will not require much copying and /// hence be fast. void GapTo(int position) { if (position != part1Length) { if (position < part1Length) { memmove( body + position + gapLength, body + position, sizeof(T) * (part1Length - position)); } else { // position > part1Length memmove( body + part1Length, body + part1Length + gapLength, sizeof(T) * (position - part1Length)); } part1Length = position; } } /// Check that there is room in the buffer for an insertion, /// reallocating if more space needed. void RoomFor(int insertionLength) { if (gapLength <= insertionLength) { while (growSize < size / 6) growSize *= 2; ReAllocate(size + insertionLength + growSize); } } void Init() { body = NULL; growSize = 8; size = 0; lengthBody = 0; part1Length = 0; gapLength = 0; } public: /// Construct a split buffer. SplitVector() { Init(); } ~SplitVector() { delete []body; body = 0; } int GetGrowSize() const { return growSize; } void SetGrowSize(int growSize_) { growSize = growSize_; } /// Reallocate the storage for the buffer to be newSize and /// copy exisiting contents to the new buffer. /// Must not be used to decrease the size of the buffer. void ReAllocate(int newSize) { if (newSize > size) { // Move the gap to the end GapTo(lengthBody); T *newBody = new T[newSize]; if ((size != 0) && (body != 0)) { memmove(newBody, body, sizeof(T) * lengthBody); delete []body; } body = newBody; gapLength += newSize - size; size = newSize; } } /// Retrieve the character at a particular position. /// Retrieving positions outside the range of the buffer returns 0. /// The assertions here are disabled since calling code can be /// simpler if out of range access works and returns 0. T ValueAt(int position) const { if (position < part1Length) { //PLATFORM_ASSERT(position >= 0); if (position < 0) { return 0; } else { return body[position]; } } else { //PLATFORM_ASSERT(position < lengthBody); if (position >= lengthBody) { return 0; } else { return body[gapLength + position]; } } } void SetValueAt(int position, T v) { if (position < part1Length) { PLATFORM_ASSERT(position >= 0); if (position < 0) { ; } else { body[position] = v; } } else { PLATFORM_ASSERT(position < lengthBody); if (position >= lengthBody) { ; } else { body[gapLength + position] = v; } } } T &operator[](int position) const { PLATFORM_ASSERT(position >= 0 && position < lengthBody); if (position < part1Length) { return body[position]; } else { return body[gapLength + position]; } } /// Retrieve the length of the buffer. int Length() const { return lengthBody; } /// Insert a single value into the buffer. /// Inserting at positions outside the current range fails. void Insert(int position, T v) { PLATFORM_ASSERT((position >= 0) && (position <= lengthBody)); if ((position < 0) || (position > lengthBody)) { return; } RoomFor(1); GapTo(position); body[part1Length] = v; lengthBody++; part1Length++; gapLength--; } /// Insert a number of elements into the buffer setting their value. /// Inserting at positions outside the current range fails. void InsertValue(int position, int insertLength, T v) { PLATFORM_ASSERT((position >= 0) && (position <= lengthBody)); if (insertLength > 0) { if ((position < 0) || (position > lengthBody)) { return; } RoomFor(insertLength); GapTo(position); for (int i = 0; i < insertLength; i++) body[part1Length + i] = v; lengthBody += insertLength; part1Length += insertLength; gapLength -= insertLength; } } /// Ensure at least length elements allocated, /// appending zero valued elements if needed. void EnsureLength(int wantedLength) { if (Length() < wantedLength) { InsertValue(Length(), wantedLength - Length(), 0); } } /// Insert text into the buffer from an array. void InsertFromArray(int positionToInsert, const T s[], int positionFrom, int insertLength) { PLATFORM_ASSERT((positionToInsert >= 0) && (positionToInsert <= lengthBody)); if (insertLength > 0) { if ((positionToInsert < 0) || (positionToInsert > lengthBody)) { return; } RoomFor(insertLength); GapTo(positionToInsert); memmove(body + part1Length, s + positionFrom, sizeof(T) * insertLength); lengthBody += insertLength; part1Length += insertLength; gapLength -= insertLength; } } /// Delete one element from the buffer. void Delete(int position) { PLATFORM_ASSERT((position >= 0) && (position < lengthBody)); if ((position < 0) || (position >= lengthBody)) { return; } DeleteRange(position, 1); } /// Delete a range from the buffer. /// Deleting positions outside the current range fails. void DeleteRange(int position, int deleteLength) { PLATFORM_ASSERT((position >= 0) && (position + deleteLength <= lengthBody)); if ((position < 0) || ((position + deleteLength) > lengthBody)) { return; } if ((position == 0) && (deleteLength == lengthBody)) { // Full deallocation returns storage and is faster delete []body; Init(); } else if (deleteLength > 0) { GapTo(position); lengthBody -= deleteLength; gapLength += deleteLength; } } /// Delete all the buffer contents. void DeleteAll() { DeleteRange(0, lengthBody); } // Retrieve a range of elements into an array void GetRange(T *buffer, int position, int retrieveLength) const { // Split into up to 2 ranges, before and after the split then use memcpy on each. int range1Length = 0; if (position < part1Length) { int part1AfterPosition = part1Length - position; range1Length = retrieveLength; if (range1Length > part1AfterPosition) range1Length = part1AfterPosition; } memcpy(buffer, body + position, range1Length * sizeof(T)); buffer += range1Length; position = position + range1Length + gapLength; int range2Length = retrieveLength - range1Length; memcpy(buffer, body + position, range2Length * sizeof(T)); } T *BufferPointer() { RoomFor(1); GapTo(lengthBody); body[lengthBody] = 0; return body; } T *RangePointer(int position, int rangeLength) { if (position < part1Length) { if ((position + rangeLength) > part1Length) { // Range overlaps gap, so move gap to start of range. GapTo(position); return body + position + gapLength; } else { return body + position ; } } else { return body + position + gapLength; } } int GapPosition() const { return part1Length; } }; #endif |
Added src/Style.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
// Scintilla source code edit control /** @file Style.cxx ** Defines the font and colour style for a class of text. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <string.h> #include "Platform.h" #include "Scintilla.h" #include "Style.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif FontAlias::FontAlias() { } FontAlias::~FontAlias() { SetID(0); // ~Font will not release the actual font resource sine it is now 0 } void FontAlias::MakeAlias(Font &fontOrigin) { SetID(fontOrigin.GetID()); } void FontAlias::ClearFont() { SetID(0); } bool FontSpecification::EqualTo(const FontSpecification &other) const { return weight == other.weight && italic == other.italic && size == other.size && characterSet == other.characterSet && fontName == other.fontName; } FontMeasurements::FontMeasurements() { Clear(); } void FontMeasurements::Clear() { ascent = 1; descent = 1; aveCharWidth = 1; spaceWidth = 1; sizeZoomed = 2; } Style::Style() : FontSpecification() { Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), Platform::DefaultFontSize() * SC_FONT_SIZE_MULTIPLIER, 0, SC_CHARSET_DEFAULT, SC_WEIGHT_NORMAL, false, false, false, caseMixed, true, true, false); } Style::Style(const Style &source) : FontSpecification(), FontMeasurements() { Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), 0, 0, 0, SC_WEIGHT_NORMAL, false, false, false, caseMixed, true, true, false); fore = source.fore; back = source.back; characterSet = source.characterSet; weight = source.weight; italic = source.italic; size = source.size; eolFilled = source.eolFilled; underline = source.underline; caseForce = source.caseForce; visible = source.visible; changeable = source.changeable; hotspot = source.hotspot; } Style::~Style() { } Style &Style::operator=(const Style &source) { if (this == &source) return * this; Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), 0, 0, SC_CHARSET_DEFAULT, SC_WEIGHT_NORMAL, false, false, false, caseMixed, true, true, false); fore = source.fore; back = source.back; characterSet = source.characterSet; weight = source.weight; italic = source.italic; size = source.size; eolFilled = source.eolFilled; underline = source.underline; caseForce = source.caseForce; visible = source.visible; changeable = source.changeable; return *this; } void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_, const char *fontName_, int characterSet_, int weight_, bool italic_, bool eolFilled_, bool underline_, ecaseForced caseForce_, bool visible_, bool changeable_, bool hotspot_) { fore = fore_; back = back_; characterSet = characterSet_; weight = weight_; italic = italic_; size = size_; fontName = fontName_; eolFilled = eolFilled_; underline = underline_; caseForce = caseForce_; visible = visible_; changeable = changeable_; hotspot = hotspot_; font.ClearFont(); FontMeasurements::Clear(); } void Style::ClearTo(const Style &source) { Clear( source.fore, source.back, source.size, source.fontName, source.characterSet, source.weight, source.italic, source.eolFilled, source.underline, source.caseForce, source.visible, source.changeable, source.hotspot); } void Style::Copy(Font &font_, const FontMeasurements &fm_) { font.MakeAlias(font_); #if PLAT_WX font.SetAscent(fm_.ascent); #endif (FontMeasurements &)(*this) = fm_; } |
Added src/Style.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
// Scintilla source code edit control /** @file Style.h ** Defines the font and colour style for a class of text. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef STYLE_H #define STYLE_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif struct FontSpecification { const char *fontName; int weight; bool italic; int size; int characterSet; int extraFontFlag; FontSpecification() : fontName(0), weight(SC_WEIGHT_NORMAL), italic(false), size(10 * SC_FONT_SIZE_MULTIPLIER), characterSet(0), extraFontFlag(0) { } bool EqualTo(const FontSpecification &other) const; }; // Just like Font but only has a copy of the FontID so should not delete it class FontAlias : public Font { // Private so FontAlias objects can not be copied FontAlias(const FontAlias &); FontAlias &operator=(const FontAlias &); public: FontAlias(); virtual ~FontAlias(); void MakeAlias(Font &fontOrigin); void ClearFont(); }; struct FontMeasurements { unsigned int ascent; unsigned int descent; XYPOSITION aveCharWidth; XYPOSITION spaceWidth; int sizeZoomed; FontMeasurements(); void Clear(); }; /** */ class Style : public FontSpecification, public FontMeasurements { public: ColourDesired fore; ColourDesired back; bool eolFilled; bool underline; enum ecaseForced {caseMixed, caseUpper, caseLower}; ecaseForced caseForce; bool visible; bool changeable; bool hotspot; FontAlias font; Style(); Style(const Style &source); ~Style(); Style &operator=(const Style &source); void Clear(ColourDesired fore_, ColourDesired back_, int size_, const char *fontName_, int characterSet_, int weight_, bool italic_, bool eolFilled_, bool underline_, ecaseForced caseForce_, bool visible_, bool changeable_, bool hotspot_); void ClearTo(const Style &source); void Copy(Font &font_, const FontMeasurements &fm_); bool IsProtected() const { return !(changeable && visible);} }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/UniConversion.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
// Scintilla source code edit control /** @file UniConversion.cxx ** Functions to handle UTF-8 and UTF-16 strings. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include "UniConversion.h" enum { SURROGATE_LEAD_FIRST = 0xD800 }; enum { SURROGATE_TRAIL_FIRST = 0xDC00 }; enum { SURROGATE_TRAIL_LAST = 0xDFFF }; unsigned int UTF8Length(const wchar_t *uptr, unsigned int tlen) { unsigned int len = 0; for (unsigned int i = 0; i < tlen && uptr[i];) { unsigned int uch = uptr[i]; if (uch < 0x80) { len++; } else if (uch < 0x800) { len += 2; } else if ((uch >= SURROGATE_LEAD_FIRST) && (uch <= SURROGATE_TRAIL_LAST)) { len += 4; i++; } else { len += 3; } i++; } return len; } void UTF8FromUTF16(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned int len) { int k = 0; for (unsigned int i = 0; i < tlen && uptr[i];) { unsigned int uch = uptr[i]; if (uch < 0x80) { putf[k++] = static_cast<char>(uch); } else if (uch < 0x800) { putf[k++] = static_cast<char>(0xC0 | (uch >> 6)); putf[k++] = static_cast<char>(0x80 | (uch & 0x3f)); } else if ((uch >= SURROGATE_LEAD_FIRST) && (uch <= SURROGATE_TRAIL_LAST)) { // Half a surrogate pair i++; unsigned int xch = 0x10000 + ((uch & 0x3ff) << 10) + (uptr[i] & 0x3ff); putf[k++] = static_cast<char>(0xF0 | (xch >> 18)); putf[k++] = static_cast<char>(0x80 | ((xch >> 12) & 0x3f)); putf[k++] = static_cast<char>(0x80 | ((xch >> 6) & 0x3f)); putf[k++] = static_cast<char>(0x80 | (xch & 0x3f)); } else { putf[k++] = static_cast<char>(0xE0 | (uch >> 12)); putf[k++] = static_cast<char>(0x80 | ((uch >> 6) & 0x3f)); putf[k++] = static_cast<char>(0x80 | (uch & 0x3f)); } i++; } putf[len] = '\0'; } unsigned int UTF8CharLength(unsigned char ch) { if (ch < 0x80) { return 1; } else if (ch < 0x80 + 0x40 + 0x20) { return 2; } else if (ch < 0x80 + 0x40 + 0x20 + 0x10) { return 3; } else { return 4; } } unsigned int UTF16Length(const char *s, unsigned int len) { unsigned int ulen = 0; unsigned int charLen; for (unsigned int i=0; i<len;) { unsigned char ch = static_cast<unsigned char>(s[i]); if (ch < 0x80) { charLen = 1; } else if (ch < 0x80 + 0x40 + 0x20) { charLen = 2; } else if (ch < 0x80 + 0x40 + 0x20 + 0x10) { charLen = 3; } else { charLen = 4; ulen++; } i += charLen; ulen++; } return ulen; } unsigned int UTF16FromUTF8(const char *s, unsigned int len, wchar_t *tbuf, unsigned int tlen) { unsigned int ui=0; const unsigned char *us = reinterpret_cast<const unsigned char *>(s); unsigned int i=0; while ((i<len) && (ui<tlen)) { unsigned char ch = us[i++]; if (ch < 0x80) { tbuf[ui] = ch; } else if (ch < 0x80 + 0x40 + 0x20) { tbuf[ui] = static_cast<wchar_t>((ch & 0x1F) << 6); ch = us[i++]; tbuf[ui] = static_cast<wchar_t>(tbuf[ui] + (ch & 0x7F)); } else if (ch < 0x80 + 0x40 + 0x20 + 0x10) { tbuf[ui] = static_cast<wchar_t>((ch & 0xF) << 12); ch = us[i++]; tbuf[ui] = static_cast<wchar_t>(tbuf[ui] + ((ch & 0x7F) << 6)); ch = us[i++]; tbuf[ui] = static_cast<wchar_t>(tbuf[ui] + (ch & 0x7F)); } else { // Outside the BMP so need two surrogates int val = (ch & 0x7) << 18; ch = us[i++]; val += (ch & 0x3F) << 12; ch = us[i++]; val += (ch & 0x3F) << 6; ch = us[i++]; val += (ch & 0x3F); tbuf[ui] = static_cast<wchar_t>(((val - 0x10000) >> 10) + SURROGATE_LEAD_FIRST); ui++; tbuf[ui] = static_cast<wchar_t>((val & 0x3ff) + SURROGATE_TRAIL_FIRST); } ui++; } return ui; } int UTF8BytesOfLead[256]; static bool initialisedBytesOfLead = false; static int BytesFromLead(int leadByte) { if (leadByte < 0xC2) { // Single byte or invalid return 1; } else if (leadByte < 0xE0) { return 2; } else if (leadByte < 0xF0) { return 3; } else if (leadByte < 0xF5) { return 4; } else { // Characters longer than 4 bytes not possible in current UTF-8 return 1; } } void UTF8BytesOfLeadInitialise() { if (!initialisedBytesOfLead) { for (int i=0;i<256;i++) { UTF8BytesOfLead[i] = BytesFromLead(i); } initialisedBytesOfLead = true; } } // Return both the width of the first character in the string and a status // saying whether it is valid or invalid. // Most invalid sequences return a width of 1 so are treated as isolated bytes but // the non-characters *FFFE, *FFFF and FDD0 .. FDEF return 3 or 4 as they can be // reasonably treated as code points in some circumstances. They will, however, // not have associated glyphs. int UTF8Classify(const unsigned char *us, int len) { // For the rules: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 if (*us < 0x80) { // Single bytes easy return 1; } else if (*us > 0xf4) { // Characters longer than 4 bytes not possible in current UTF-8 return UTF8MaskInvalid | 1; } else if (*us >= 0xf0) { // 4 bytes if (len < 4) return UTF8MaskInvalid | 1; if (UTF8IsTrailByte(us[1]) && UTF8IsTrailByte(us[2]) && UTF8IsTrailByte(us[3])) { if (((us[1] & 0xf) == 0xf) && (us[2] == 0xbf) && ((us[3] == 0xbe) || (us[3] == 0xbf))) { // *FFFE or *FFFF non-character return UTF8MaskInvalid | 4; } if (*us == 0xf4) { // Check if encoding a value beyond the last Unicode character 10FFFF if (us[1] > 0x8f) { return UTF8MaskInvalid | 1; } else if (us[1] == 0x8f) { if (us[2] > 0xbf) { return UTF8MaskInvalid | 1; } else if (us[2] == 0xbf) { if (us[3] > 0xbf) { return UTF8MaskInvalid | 1; } } } } else if ((*us == 0xf0) && ((us[1] & 0xf0) == 0x80)) { // Overlong return UTF8MaskInvalid | 1; } return 4; } else { return UTF8MaskInvalid | 1; } } else if (*us >= 0xe0) { // 3 bytes if (len < 3) return UTF8MaskInvalid | 1; if (UTF8IsTrailByte(us[1]) && UTF8IsTrailByte(us[2])) { if ((*us == 0xe0) && ((us[1] & 0xe0) == 0x80)) { // Overlong return UTF8MaskInvalid | 1; } if ((*us == 0xed) && ((us[1] & 0xe0) == 0xa0)) { // Surrogate return UTF8MaskInvalid | 1; } if ((*us == 0xef) && (us[1] == 0xbf) && (us[2] == 0xbe)) { // U+FFFE non-character - 3 bytes long return UTF8MaskInvalid | 3; } if ((*us == 0xef) && (us[1] == 0xbf) && (us[2] == 0xbf)) { // U+FFFF non-character - 3 bytes long return UTF8MaskInvalid | 3; } if ((*us == 0xef) && (us[1] == 0xb7) && (((us[2] & 0xf0) == 0x90) || ((us[2] & 0xf0) == 0xa0))) { // U+FDD0 .. U+FDEF return UTF8MaskInvalid | 3; } return 3; } else { return UTF8MaskInvalid | 1; } } else if (*us >= 0xc2) { // 2 bytes if (len < 2) return UTF8MaskInvalid | 1; if (UTF8IsTrailByte(us[1])) { return 2; } else { return UTF8MaskInvalid | 1; } } else { // 0xc0 .. 0xc1 is overlong encoding // 0x80 .. 0xbf is trail byte return UTF8MaskInvalid | 1; } } |
Added src/UniConversion.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
// Scintilla source code edit control /** @file UniConversion.h ** Functions to handle UTF-8 and UTF-16 strings. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. const int UTF8MaxBytes = 4; unsigned int UTF8Length(const wchar_t *uptr, unsigned int tlen); void UTF8FromUTF16(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned int len); unsigned int UTF8CharLength(unsigned char ch); unsigned int UTF16Length(const char *s, unsigned int len); unsigned int UTF16FromUTF8(const char *s, unsigned int len, wchar_t *tbuf, unsigned int tlen); extern int UTF8BytesOfLead[256]; void UTF8BytesOfLeadInitialise(); inline bool UTF8IsTrailByte(int ch) { return (ch >= 0x80) && (ch < 0xc0); } inline bool UTF8IsAscii(int ch) { return ch < 0x80; } enum { UTF8MaskWidth=0x7, UTF8MaskInvalid=0x8 }; int UTF8Classify(const unsigned char *us, int len); // Line separator is U+2028 \xe2\x80\xa8 // Paragraph separator is U+2029 \xe2\x80\xa9 const int UTF8SeparatorLength = 3; inline bool UTF8IsSeparator(const unsigned char *us) { return (us[0] == 0xe2) && (us[1] == 0x80) && ((us[2] == 0xa8) || (us[2] == 0xa9)); } // NEL is U+0085 \xc2\x85 const int UTF8NELLength = 2; inline bool UTF8IsNEL(const unsigned char *us) { return (us[0] == 0xc2) && (us[1] == 0x85); } |
Added src/ViewStyle.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 |
// Scintilla source code edit control /** @file ViewStyle.cxx ** Store information on how the document is to be viewed. **/ // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <string.h> #include <assert.h> #include <vector> #include <map> #include "Platform.h" #include "Scintilla.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" #include "Indicator.h" #include "XPM.h" #include "LineMarker.h" #include "Style.h" #include "ViewStyle.h" #ifdef SCI_NAMESPACE using namespace Scintilla; #endif MarginStyle::MarginStyle() : style(SC_MARGIN_SYMBOL), width(0), mask(0), sensitive(false), cursor(SC_CURSORREVERSEARROW) { } // A list of the fontnames - avoids wasting space in each style FontNames::FontNames() { size = 8; names = new char *[size]; max = 0; } FontNames::~FontNames() { Clear(); delete []names; names = 0; } void FontNames::Clear() { for (int i=0; i<max; i++) { delete []names[i]; } max = 0; } const char *FontNames::Save(const char *name) { if (!name) return 0; for (int i=0; i<max; i++) { if (strcmp(names[i], name) == 0) { return names[i]; } } if (max >= size) { // Grow array int sizeNew = size * 2; char **namesNew = new char *[sizeNew]; for (int j=0; j<max; j++) { namesNew[j] = names[j]; } delete []names; names = namesNew; size = sizeNew; } names[max] = new char[strlen(name) + 1]; strcpy(names[max], name); max++; return names[max-1]; } FontRealised::FontRealised(const FontSpecification &fs) { frNext = NULL; (FontSpecification &)(*this) = fs; } FontRealised::~FontRealised() { font.Release(); delete frNext; frNext = 0; } void FontRealised::Realise(Surface &surface, int zoomLevel, int technology) { PLATFORM_ASSERT(fontName); sizeZoomed = size + zoomLevel * SC_FONT_SIZE_MULTIPLIER; if (sizeZoomed <= 2 * SC_FONT_SIZE_MULTIPLIER) // Hangs if sizeZoomed <= 1 sizeZoomed = 2 * SC_FONT_SIZE_MULTIPLIER; float deviceHeight = surface.DeviceHeightFont(sizeZoomed); FontParameters fp(fontName, deviceHeight / SC_FONT_SIZE_MULTIPLIER, weight, italic, extraFontFlag, technology, characterSet); font.Create(fp); ascent = surface.Ascent(font); descent = surface.Descent(font); aveCharWidth = surface.AverageCharWidth(font); spaceWidth = surface.WidthChar(font, ' '); if (frNext) { frNext->Realise(surface, zoomLevel, technology); } } FontRealised *FontRealised::Find(const FontSpecification &fs) { if (!fs.fontName) return this; FontRealised *fr = this; while (fr) { if (fr->EqualTo(fs)) return fr; fr = fr->frNext; } return 0; } void FontRealised::FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent) { FontRealised *fr = this; while (fr) { if (maxAscent < fr->ascent) maxAscent = fr->ascent; if (maxDescent < fr->descent) maxDescent = fr->descent; fr = fr->frNext; } } ViewStyle::ViewStyle() { Init(); } ViewStyle::ViewStyle(const ViewStyle &source) { frFirst = NULL; Init(source.stylesSize); for (unsigned int sty=0; sty<source.stylesSize; sty++) { styles[sty] = source.styles[sty]; // Can't just copy fontname as its lifetime is relative to its owning ViewStyle styles[sty].fontName = fontNames.Save(source.styles[sty].fontName); } nextExtendedStyle = source.nextExtendedStyle; for (int mrk=0; mrk<=MARKER_MAX; mrk++) { markers[mrk] = source.markers[mrk]; } CalcLargestMarkerHeight(); for (int ind=0; ind<=INDIC_MAX; ind++) { indicators[ind] = source.indicators[ind]; } selforeset = source.selforeset; selforeground = source.selforeground; selAdditionalForeground = source.selAdditionalForeground; selbackset = source.selbackset; selbackground = source.selbackground; selAdditionalBackground = source.selAdditionalBackground; selbackground2 = source.selbackground2; selAlpha = source.selAlpha; selAdditionalAlpha = source.selAdditionalAlpha; selEOLFilled = source.selEOLFilled; foldmarginColourSet = source.foldmarginColourSet; foldmarginColour = source.foldmarginColour; foldmarginHighlightColourSet = source.foldmarginHighlightColourSet; foldmarginHighlightColour = source.foldmarginHighlightColour; hotspotForegroundSet = source.hotspotForegroundSet; hotspotForeground = source.hotspotForeground; hotspotBackgroundSet = source.hotspotBackgroundSet; hotspotBackground = source.hotspotBackground; hotspotUnderline = source.hotspotUnderline; hotspotSingleLine = source.hotspotSingleLine; whitespaceForegroundSet = source.whitespaceForegroundSet; whitespaceForeground = source.whitespaceForeground; whitespaceBackgroundSet = source.whitespaceBackgroundSet; whitespaceBackground = source.whitespaceBackground; selbar = source.selbar; selbarlight = source.selbarlight; caretcolour = source.caretcolour; additionalCaretColour = source.additionalCaretColour; showCaretLineBackground = source.showCaretLineBackground; alwaysShowCaretLineBackground = source.alwaysShowCaretLineBackground; caretLineBackground = source.caretLineBackground; caretLineAlpha = source.caretLineAlpha; edgecolour = source.edgecolour; edgeState = source.edgeState; caretStyle = source.caretStyle; caretWidth = source.caretWidth; someStylesProtected = false; someStylesForceCase = false; leftMarginWidth = source.leftMarginWidth; rightMarginWidth = source.rightMarginWidth; for (int margin=0; margin <= SC_MAX_MARGIN; margin++) { ms[margin] = source.ms[margin]; } maskInLine = source.maskInLine; fixedColumnWidth = source.fixedColumnWidth; marginInside = source.marginInside; textStart = source.textStart; zoomLevel = source.zoomLevel; viewWhitespace = source.viewWhitespace; whitespaceSize = source.whitespaceSize; viewIndentationGuides = source.viewIndentationGuides; viewEOL = source.viewEOL; extraFontFlag = source.extraFontFlag; extraAscent = source.extraAscent; extraDescent = source.extraDescent; marginStyleOffset = source.marginStyleOffset; annotationVisible = source.annotationVisible; annotationStyleOffset = source.annotationStyleOffset; braceHighlightIndicatorSet = source.braceHighlightIndicatorSet; braceHighlightIndicator = source.braceHighlightIndicator; braceBadLightIndicatorSet = source.braceBadLightIndicatorSet; braceBadLightIndicator = source.braceBadLightIndicator; } ViewStyle::~ViewStyle() { delete []styles; styles = NULL; delete frFirst; frFirst = NULL; } void ViewStyle::Init(size_t stylesSize_) { frFirst = NULL; stylesSize = 0; styles = NULL; AllocStyles(stylesSize_); nextExtendedStyle = 256; fontNames.Clear(); ResetDefaultStyle(); // There are no image markers by default, so no need for calling CalcLargestMarkerHeight() largestMarkerHeight = 0; indicators[0].style = INDIC_SQUIGGLE; indicators[0].under = false; indicators[0].fore = ColourDesired(0, 0x7f, 0); indicators[1].style = INDIC_TT; indicators[1].under = false; indicators[1].fore = ColourDesired(0, 0, 0xff); indicators[2].style = INDIC_PLAIN; indicators[2].under = false; indicators[2].fore = ColourDesired(0xff, 0, 0); technology = SC_TECHNOLOGY_DEFAULT; lineHeight = 1; maxAscent = 1; maxDescent = 1; aveCharWidth = 8; spaceWidth = 8; selforeset = false; selforeground = ColourDesired(0xff, 0, 0); selAdditionalForeground = ColourDesired(0xff, 0, 0); selbackset = true; selbackground = ColourDesired(0xc0, 0xc0, 0xc0); selAdditionalBackground = ColourDesired(0xd7, 0xd7, 0xd7); selbackground2 = ColourDesired(0xb0, 0xb0, 0xb0); selAlpha = SC_ALPHA_NOALPHA; selAdditionalAlpha = SC_ALPHA_NOALPHA; selEOLFilled = false; foldmarginColourSet = false; foldmarginColour = ColourDesired(0xff, 0, 0); foldmarginHighlightColourSet = false; foldmarginHighlightColour = ColourDesired(0xc0, 0xc0, 0xc0); whitespaceForegroundSet = false; whitespaceForeground = ColourDesired(0, 0, 0); whitespaceBackgroundSet = false; whitespaceBackground = ColourDesired(0xff, 0xff, 0xff); selbar = Platform::Chrome(); selbarlight = Platform::ChromeHighlight(); styles[STYLE_LINENUMBER].fore = ColourDesired(0, 0, 0); styles[STYLE_LINENUMBER].back = Platform::Chrome(); caretcolour = ColourDesired(0, 0, 0); additionalCaretColour = ColourDesired(0x7f, 0x7f, 0x7f); showCaretLineBackground = false; alwaysShowCaretLineBackground = false; caretLineBackground = ColourDesired(0xff, 0xff, 0); caretLineAlpha = SC_ALPHA_NOALPHA; edgecolour = ColourDesired(0xc0, 0xc0, 0xc0); edgeState = EDGE_NONE; caretStyle = CARETSTYLE_LINE; caretWidth = 1; someStylesProtected = false; someStylesForceCase = false; hotspotForegroundSet = false; hotspotForeground = ColourDesired(0, 0, 0xff); hotspotBackgroundSet = false; hotspotBackground = ColourDesired(0xff, 0xff, 0xff); hotspotUnderline = true; hotspotSingleLine = true; leftMarginWidth = 1; rightMarginWidth = 1; ms[0].style = SC_MARGIN_NUMBER; ms[0].width = 0; ms[0].mask = 0; ms[1].style = SC_MARGIN_SYMBOL; ms[1].width = 16; ms[1].mask = ~SC_MASK_FOLDERS; ms[2].style = SC_MARGIN_SYMBOL; ms[2].width = 0; ms[2].mask = 0; marginInside = true; fixedColumnWidth = marginInside ? leftMarginWidth : 0; maskInLine = 0xffffffff; for (int margin=0; margin <= SC_MAX_MARGIN; margin++) { fixedColumnWidth += ms[margin].width; if (ms[margin].width > 0) maskInLine &= ~ms[margin].mask; } textStart = marginInside ? fixedColumnWidth : leftMarginWidth; zoomLevel = 0; viewWhitespace = wsInvisible; whitespaceSize = 1; viewIndentationGuides = ivNone; viewEOL = false; extraFontFlag = 0; extraAscent = 0; extraDescent = 0; marginStyleOffset = 0; annotationVisible = ANNOTATION_HIDDEN; annotationStyleOffset = 0; braceHighlightIndicatorSet = false; braceHighlightIndicator = 0; braceBadLightIndicatorSet = false; braceBadLightIndicator = 0; } void ViewStyle::CreateFont(const FontSpecification &fs) { if (fs.fontName) { for (FontRealised *cur=frFirst; cur; cur=cur->frNext) { if (cur->EqualTo(fs)) return; if (!cur->frNext) { cur->frNext = new FontRealised(fs); return; } } frFirst = new FontRealised(fs); } } void ViewStyle::Refresh(Surface &surface) { delete frFirst; frFirst = NULL; selbar = Platform::Chrome(); selbarlight = Platform::ChromeHighlight(); for (unsigned int i=0; i<stylesSize; i++) { styles[i].extraFontFlag = extraFontFlag; } CreateFont(styles[STYLE_DEFAULT]); for (unsigned int j=0; j<stylesSize; j++) { CreateFont(styles[j]); } assert(frFirst); frFirst->Realise(surface, zoomLevel, technology); for (unsigned int k=0; k<stylesSize; k++) { FontRealised *fr = frFirst->Find(styles[k]); styles[k].Copy(fr->font, *fr); } maxAscent = 1; maxDescent = 1; frFirst->FindMaxAscentDescent(maxAscent, maxDescent); maxAscent += extraAscent; maxDescent += extraDescent; lineHeight = maxAscent + maxDescent; someStylesProtected = false; someStylesForceCase = false; for (unsigned int l=0; l<stylesSize; l++) { if (styles[l].IsProtected()) { someStylesProtected = true; } if (styles[l].caseForce != Style::caseMixed) { someStylesForceCase = true; } } aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth; spaceWidth = styles[STYLE_DEFAULT].spaceWidth; fixedColumnWidth = marginInside ? leftMarginWidth : 0; maskInLine = 0xffffffff; for (int margin=0; margin <= SC_MAX_MARGIN; margin++) { fixedColumnWidth += ms[margin].width; if (ms[margin].width > 0) maskInLine &= ~ms[margin].mask; } textStart = marginInside ? fixedColumnWidth : leftMarginWidth; } void ViewStyle::AllocStyles(size_t sizeNew) { Style *stylesNew = new Style[sizeNew]; size_t i=0; for (; i<stylesSize; i++) { stylesNew[i] = styles[i]; stylesNew[i].fontName = styles[i].fontName; } if (stylesSize > STYLE_DEFAULT) { for (; i<sizeNew; i++) { if (i != STYLE_DEFAULT) { stylesNew[i].ClearTo(styles[STYLE_DEFAULT]); } } } delete []styles; styles = stylesNew; stylesSize = sizeNew; } void ViewStyle::ReleaseAllExtendedStyles() { nextExtendedStyle = 256; } int ViewStyle::AllocateExtendedStyles(int numberStyles) { int startRange = static_cast<int>(nextExtendedStyle); nextExtendedStyle += numberStyles; return startRange; } void ViewStyle::EnsureStyle(size_t index) { if (index >= stylesSize) { size_t sizeNew = stylesSize * 2; while (sizeNew <= index) sizeNew *= 2; AllocStyles(sizeNew); } } void ViewStyle::ResetDefaultStyle() { styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0), ColourDesired(0xff,0xff,0xff), Platform::DefaultFontSize() * SC_FONT_SIZE_MULTIPLIER, fontNames.Save(Platform::DefaultFont()), SC_CHARSET_DEFAULT, SC_WEIGHT_NORMAL, false, false, false, Style::caseMixed, true, true, false); } void ViewStyle::ClearStyles() { // Reset all styles to be like the default style for (unsigned int i=0; i<stylesSize; i++) { if (i != STYLE_DEFAULT) { styles[i].ClearTo(styles[STYLE_DEFAULT]); } } styles[STYLE_LINENUMBER].back = Platform::Chrome(); // Set call tip fore/back to match the values previously set for call tips styles[STYLE_CALLTIP].back = ColourDesired(0xff, 0xff, 0xff); styles[STYLE_CALLTIP].fore = ColourDesired(0x80, 0x80, 0x80); } void ViewStyle::SetStyleFontName(int styleIndex, const char *name) { styles[styleIndex].fontName = fontNames.Save(name); } bool ViewStyle::ProtectionActive() const { return someStylesProtected; } bool ViewStyle::ValidStyle(size_t styleIndex) const { return styleIndex < stylesSize; } void ViewStyle::CalcLargestMarkerHeight() { largestMarkerHeight = 0; for (int m = 0; m <= MARKER_MAX; ++m) { switch (markers[m].markType) { case SC_MARK_PIXMAP: if (markers[m].pxpm->GetHeight() > largestMarkerHeight) largestMarkerHeight = markers[m].pxpm->GetHeight(); break; case SC_MARK_RGBAIMAGE: if (markers[m].image->GetHeight() > largestMarkerHeight) largestMarkerHeight = markers[m].image->GetHeight(); break; } } } |
Added src/ViewStyle.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
// Scintilla source code edit control /** @file ViewStyle.h ** Store information on how the document is to be viewed. **/ // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef VIEWSTYLE_H #define VIEWSTYLE_H #ifdef SCI_NAMESPACE namespace Scintilla { #endif /** */ class MarginStyle { public: int style; int width; int mask; bool sensitive; int cursor; MarginStyle(); }; /** */ class FontNames { private: char **names; int size; int max; // Private so FontNames objects can not be copied FontNames(const FontNames &); public: FontNames(); ~FontNames(); void Clear(); const char *Save(const char *name); }; class FontRealised : public FontSpecification, public FontMeasurements { // Private so FontRealised objects can not be copied FontRealised(const FontRealised &); FontRealised &operator=(const FontRealised &); public: Font font; FontRealised *frNext; FontRealised(const FontSpecification &fs); virtual ~FontRealised(); void Realise(Surface &surface, int zoomLevel, int technology); FontRealised *Find(const FontSpecification &fs); void FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent); }; enum IndentView {ivNone, ivReal, ivLookForward, ivLookBoth}; enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2}; /** */ class ViewStyle { public: FontNames fontNames; FontRealised *frFirst; size_t stylesSize; Style *styles; size_t nextExtendedStyle; LineMarker markers[MARKER_MAX + 1]; int largestMarkerHeight; Indicator indicators[INDIC_MAX + 1]; int technology; int lineHeight; unsigned int maxAscent; unsigned int maxDescent; XYPOSITION aveCharWidth; XYPOSITION spaceWidth; bool selforeset; ColourDesired selforeground; ColourDesired selAdditionalForeground; bool selbackset; ColourDesired selbackground; ColourDesired selAdditionalBackground; ColourDesired selbackground2; int selAlpha; int selAdditionalAlpha; bool selEOLFilled; bool whitespaceForegroundSet; ColourDesired whitespaceForeground; bool whitespaceBackgroundSet; ColourDesired whitespaceBackground; ColourDesired selbar; ColourDesired selbarlight; bool foldmarginColourSet; ColourDesired foldmarginColour; bool foldmarginHighlightColourSet; ColourDesired foldmarginHighlightColour; bool hotspotForegroundSet; ColourDesired hotspotForeground; bool hotspotBackgroundSet; ColourDesired hotspotBackground; bool hotspotUnderline; bool hotspotSingleLine; /// Margins are ordered: Line Numbers, Selection Margin, Spacing Margin int leftMarginWidth; ///< Spacing margin on left of text int rightMarginWidth; ///< Spacing margin on right of text int maskInLine; ///< Mask for markers to be put into text because there is nowhere for them to go in margin MarginStyle ms[SC_MAX_MARGIN+1]; int fixedColumnWidth; ///< Total width of margins bool marginInside; ///< true: margin included in text view, false: separate views int textStart; ///< Starting x position of text within the view int zoomLevel; WhiteSpaceVisibility viewWhitespace; int whitespaceSize; IndentView viewIndentationGuides; bool viewEOL; ColourDesired caretcolour; ColourDesired additionalCaretColour; bool showCaretLineBackground; bool alwaysShowCaretLineBackground; ColourDesired caretLineBackground; int caretLineAlpha; ColourDesired edgecolour; int edgeState; int caretStyle; int caretWidth; bool someStylesProtected; bool someStylesForceCase; int extraFontFlag; int extraAscent; int extraDescent; int marginStyleOffset; int annotationVisible; int annotationStyleOffset; bool braceHighlightIndicatorSet; int braceHighlightIndicator; bool braceBadLightIndicatorSet; int braceBadLightIndicator; ViewStyle(); ViewStyle(const ViewStyle &source); ~ViewStyle(); void Init(size_t stylesSize_=64); void CreateFont(const FontSpecification &fs); void Refresh(Surface &surface); void AllocStyles(size_t sizeNew); void ReleaseAllExtendedStyles(); int AllocateExtendedStyles(int numberStyles); void EnsureStyle(size_t index); void ResetDefaultStyle(); void ClearStyles(); void SetStyleFontName(int styleIndex, const char *name); bool ProtectionActive() const; bool ValidStyle(size_t styleIndex) const; void CalcLargestMarkerHeight(); }; #ifdef SCI_NAMESPACE } #endif #endif |
Added src/XPM.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 |
// Scintilla source code edit control /** @file XPM.cxx ** Define a class that holds data in the X Pixmap (XPM) format. **/ // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <string.h> #include <stdlib.h> #include <vector> #include <map> #include "Platform.h" #include "XPM.h" #ifdef _WIN32 # define strcasecmp stricmp #endif #ifdef SCI_NAMESPACE using namespace Scintilla; #endif static const char *NextField(const char *s) { // In case there are leading spaces in the string while (*s && *s == ' ') { s++; } while (*s && *s != ' ') { s++; } while (*s && *s == ' ') { s++; } return s; } // Data lines in XPM can be terminated either with NUL or " static size_t MeasureLength(const char *s) { size_t i = 0; while (s[i] && (s[i] != '\"')) i++; return i; } ColourDesired XPM::ColourDesiredFromCode(const std::string & ch) const { ColourCodeMap::const_iterator it = colourCodeTable.find(ch); ColourDesired *cd = it->second; return (cd ? *cd: ColourDesired(0xff, 0xff, 0xff)); } ColourDesired XPM::ColourFromCode(const std::string &ch) const { ColourCodeMap::const_iterator it = colourCodeTable.find(ch); ColourDesired *cd = it->second; return (cd ? *cd: ColourDesired(0xff, 0xff, 0xff)); } void XPM::FillRun(Surface *surface, const std::string &code, int startX, int y, int x) { if ((code.compare(*codeTransparent) != 0) && (startX != x)) { PRectangle rc(startX, y, x, y+1); surface->FillRectangle(rc, ColourFromCode(code)); } } XPM::XPM(const char *textForm) : data(0), codeTransparent(NULL), codes(0), colours(0), lines(0) { Init(textForm); } XPM::XPM(const char *const *linesForm) : data(0), codeTransparent(NULL), codes(0), colours(0), lines(0) { Init(linesForm); } XPM::~XPM() { Clear(); } void XPM::Init(const char *textForm) { Clear(); // Test done is two parts to avoid possibility of overstepping the memory // if memcmp implemented strangely. Must be 4 bytes at least at destination. if ((0 == memcmp(textForm, "/* X", 4)) && (0 == memcmp(textForm, "/* XPM */", 9))) { // Build the lines form out of the text form const char **linesForm = LinesFormFromTextForm(textForm); if (linesForm != 0) { Init(linesForm); delete []linesForm; } } else { // It is really in line form Init(reinterpret_cast<const char * const *>(textForm)); } } void XPM::Init(const char *const *linesForm) { Clear(); height = 1; width = 1; nColours = 1; data = NULL; codeTransparent = new std::string; codes = NULL; colours = NULL; lines = NULL; if (!linesForm) return; const char *line0 = linesForm[0]; width = atoi(line0); line0 = NextField(line0); height = atoi(line0); line0 = NextField(line0); nColours = atoi(line0); line0 = NextField(line0); ncpp = atoi(line0); if (ncpp < 1 || 4 < ncpp) { // Only 1-4 char per pixel is supported return; } codes = new std::string[nColours]; colours = new ColourDesired[nColours]; int strings = 1+height+nColours; lines = new char *[strings]; size_t allocation = 0; for (int i=0; i<strings; i++) { allocation += MeasureLength(linesForm[i]) + 1; } data = new char[allocation]; char *nextBit = data; for (int j=0; j<strings; j++) { lines[j] = nextBit; size_t len = MeasureLength(linesForm[j]); memcpy(nextBit, linesForm[j], len); nextBit += len; *nextBit++ = '\0'; } for (int c=0; c<nColours; c++) { const char *colourDef = lines[c+1]; std::string *ch = new std::string(colourDef, 0, ncpp); codes[c] = *ch; colourDef += ncpp; while (*colourDef == ' ' && *colourDef != '\0') colourDef++; while (*colourDef != '\0') { switch (*colourDef) { case 'c': colourDef += 2; if (*colourDef == '#') { colours[c].Set(colourDef); } else if (strcasecmp(colourDef,"none")==0) { colours[c] = ColourDesired(0xff, 0xff, 0xff); codeTransparent = &codes[c]; } else { // Symbolic name for color - not supported // use white for now colours[c] = ColourDesired(0xff, 0xff, 0xff); } break; case 's': // Skip symbolic name case 'm': // Skip monochrome spec case 'g': // Skip grayscale spec while (*colourDef != ' ' && *colourDef != '\0') colourDef++; while (*colourDef == ' ' && *colourDef != '\0') colourDef++; break; default: // Unexpected key! return; } while (*colourDef != ' ' && *colourDef != '\0') colourDef++; while (*colourDef == ' ' && *colourDef != '\0') colourDef++; } colourCodeTable[codes[c]] = &(colours[c]); } } void XPM::Clear() { delete []data; data = 0; delete []codes; codes = 0; delete []colours; colours = 0; delete []lines; lines = 0; } void XPM::Draw(Surface *surface, PRectangle &rc) { if (!data || !codes || !colours || !lines) { return; } // Centre the pixmap int startY = rc.top + (rc.Height() - height) / 2; int startX = rc.left + (rc.Width() - width) / 2; for (int y=0; y<height; y++) { char prevCode[5] = {'\0','\0','\0','\0','\0'}; int xStartRun = 0; for (int x=0; x<width; x++) { char code[5]; strncpy(code, &lines[y+nColours+1][(x*ncpp)], ncpp); code[ncpp] = '\0'; if (strcmp(code, prevCode) != 0) { FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + x); xStartRun = x; strcpy(prevCode, code); } } FillRun(surface, prevCode, startX + xStartRun, startY + y, startX + width); } } void XPM::PixelAt(int x, int y, ColourDesired &colour, bool &transparent) const { if (!data || !codes || !colours || !lines || (x<0) || (x >= width) || (y<0) || (y >= height)) { colour = 0; transparent = true; return; } std::string const code(&lines[y+nColours+1][x],0,ncpp); transparent = (code.compare(*codeTransparent) == 0); if (transparent) { colour = 0; } else { colour = ColourDesiredFromCode(code).AsLong(); } } const char **XPM::LinesFormFromTextForm(const char *textForm) { // Build the lines form out of the text form const char **linesForm = 0; int countQuotes = 0; int strings=1; int j=0; for (; countQuotes < (2*strings) && textForm[j] != '\0'; j++) { if (textForm[j] == '\"') { if (countQuotes == 0) { // First field: width, height, number of colors, chars per pixel const char *line0 = textForm + j + 1; // Skip width line0 = NextField(line0); // Add 1 line for each pixel of height strings += atoi(line0); line0 = NextField(line0); // Add 1 line for each colour strings += atoi(line0); linesForm = new const char *[strings]; if (linesForm == 0) { break; // Memory error! } } if (countQuotes / 2 >= strings) { break; // Bad height or number of colors! } if ((countQuotes & 1) == 0) { linesForm[countQuotes / 2] = textForm + j + 1; } countQuotes++; } } if (textForm[j] == '\0' || countQuotes / 2 > strings) { // Malformed XPM! Height + number of colors too high or too low delete []linesForm; linesForm = 0; } return linesForm; } // In future, may want to minimize search time by sorting and using a binary search. XPMSet::XPMSet() : set(0), len(0), maximum(0), height(-1), width(-1) { } XPMSet::~XPMSet() { Clear(); } void XPMSet::Clear() { for (int i = 0; i < len; i++) { delete set[i]; } delete []set; set = 0; len = 0; maximum = 0; height = -1; width = -1; } void XPMSet::Add(int ident, const char *textForm) { // Invalidate cached dimensions height = -1; width = -1; // Replace if this id already present for (int i = 0; i < len; i++) { if (set[i]->GetId() == ident) { set[i]->Init(textForm); return; } } // Not present, so add to end XPM *pxpm = new XPM(textForm); if (pxpm) { pxpm->SetId(ident); if (len == maximum) { maximum += 64; XPM **setNew = new XPM *[maximum]; for (int i = 0; i < len; i++) { setNew[i] = set[i]; } delete []set; set = setNew; } set[len] = pxpm; len++; } } XPM *XPMSet::Get(int ident) { for (int i = 0; i < len; i++) { if (set[i]->GetId() == ident) { return set[i]; } } return 0; } int XPMSet::GetHeight() { if (height < 0) { for (int i = 0; i < len; i++) { if (height < set[i]->GetHeight()) { height = set[i]->GetHeight(); } } } return (height > 0) ? height : 0; } int XPMSet::GetWidth() { if (width < 0) { for (int i = 0; i < len; i++) { if (width < set[i]->GetWidth()) { width = set[i]->GetWidth(); } } } return (width > 0) ? width : 0; } RGBAImage::RGBAImage(int width_, int height_, float scale_, const unsigned char *pixels_) : height(height_), width(width_), scale(scale_) { if (pixels_) { pixelBytes.assign(pixels_, pixels_ + CountBytes()); } else { pixelBytes.resize(CountBytes()); } } RGBAImage::RGBAImage(const XPM &xpm) { height = xpm.GetHeight(); width = xpm.GetWidth(); scale = 1; pixelBytes.resize(CountBytes()); for (int y=0; y<height; y++) { for (int x=0; x<width; x++) { ColourDesired colour; bool transparent = false; xpm.PixelAt(x, y, colour, transparent); SetPixel(x, y, colour, transparent ? 0 : 255); } } } RGBAImage::~RGBAImage() { } int RGBAImage::CountBytes() const { return width * height * 4; } const unsigned char *RGBAImage::Pixels() const { return &pixelBytes[0]; } void RGBAImage::SetPixel(int x, int y, ColourDesired colour, int alpha) { unsigned char *pixel = &pixelBytes[0] + (y*width+x) * 4; // RGBA pixel[0] = static_cast<unsigned char>(colour.GetRed()); pixel[1] = static_cast<unsigned char>(colour.GetGreen()); pixel[2] = static_cast<unsigned char>(colour.GetBlue()); pixel[3] = static_cast<unsigned char>(alpha); } RGBAImageSet::RGBAImageSet() : height(-1), width(-1){ } RGBAImageSet::~RGBAImageSet() { Clear(); } /// Remove all images. void RGBAImageSet::Clear() { for (ImageMap::iterator it=images.begin(); it != images.end(); ++it) { delete it->second; it->second = 0; } images.clear(); height = -1; width = -1; } /// Add an image. void RGBAImageSet::Add(int ident, RGBAImage *image) { ImageMap::iterator it=images.find(ident); if (it == images.end()) { images[ident] = image; } else { delete it->second; it->second = image; } height = -1; width = -1; } /// Get image by id. RGBAImage *RGBAImageSet::Get(int ident) { ImageMap::iterator it = images.find(ident); if (it != images.end()) { return it->second; } return NULL; } /// Give the largest height of the set. int RGBAImageSet::GetHeight() const { if (height < 0) { for (ImageMap::const_iterator it=images.begin(); it != images.end(); ++it) { if (height < it->second->GetHeight()) { height = it->second->GetHeight(); } } } return (height > 0) ? height : 0; } /// Give the largest width of the set. int RGBAImageSet::GetWidth() const { if (width < 0) { for (ImageMap::const_iterator it=images.begin(); it != images.end(); ++it) { if (width < it->second->GetWidth()) { width = it->second->GetWidth(); } } } return (width > 0) ? width : 0; } |
Added src/XPM.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
// Scintilla source code edit control /** @file XPM.h ** Define a class that holds data in the X Pixmap (XPM) format. **/ // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #ifndef XPM_H #define XPM_H #include <string> #ifdef SCI_NAMESPACE namespace Scintilla { #endif /** * Hold a pixmap in XPM format. */ class XPM { int pid; // Assigned by container int height; int width; int nColours; int ncpp; char *data; std::string *codeTransparent; std::string *codes; ColourDesired *colours; ColourDesired ColourDesiredFromCode(const std::string &ch) const; ColourDesired ColourFromCode(const std::string &ch) const; void FillRun(Surface *surface, const std::string &code, int startX, int y, int x); char **lines; typedef std::map<std::string, ColourDesired*> ColourCodeMap; ColourCodeMap colourCodeTable; public: XPM(const char *textForm); XPM(const char *const *linesForm); ~XPM(); void Init(const char *textForm); void Init(const char *const *linesForm); void Clear(); /// Decompose image into runs and use FillRectangle for each run void Draw(Surface *surface, PRectangle &rc); char **InLinesForm() { return lines; } void SetId(int pid_) { pid = pid_; } int GetId() const { return pid; } int GetHeight() const { return height; } int GetWidth() const { return width; } void PixelAt(int x, int y, ColourDesired &colour, bool &transparent) const; static const char **LinesFormFromTextForm(const char *textForm); }; /** * A collection of pixmaps indexed by integer id. */ class XPMSet { XPM **set; ///< The stored XPMs. int len; ///< Current number of XPMs. int maximum; ///< Current maximum number of XPMs, increased by steps if reached. int height; ///< Memorize largest height of the set. int width; ///< Memorize largest width of the set. public: XPMSet(); ~XPMSet(); /// Remove all XPMs. void Clear(); /// Add a XPM. void Add(int ident, const char *textForm); /// Get XPM by id. XPM *Get(int ident); /// Give the largest height of the set. int GetHeight(); /// Give the largest width of the set. int GetWidth(); }; /** * An translucent image stoed as a sequence of RGBA bytes. */ class RGBAImage { // Private so RGBAImage objects can not be copied RGBAImage(const RGBAImage &); RGBAImage &operator=(const RGBAImage &); int height; int width; float scale; std::vector<unsigned char> pixelBytes; public: RGBAImage(int width_, int height_, float scale_, const unsigned char *pixels_); RGBAImage(const XPM &xpm); virtual ~RGBAImage(); int GetHeight() const { return height; } int GetWidth() const { return width; } float GetScale() const { return scale; } float GetScaledHeight() const { return height / scale; } float GetScaledWidth() const { return width / scale; } int CountBytes() const; const unsigned char *Pixels() const; void SetPixel(int x, int y, ColourDesired colour, int alpha=0xff); }; /** * A collection of RGBAImage pixmaps indexed by integer id. */ class RGBAImageSet { typedef std::map<int, RGBAImage*> ImageMap; ImageMap images; mutable int height; ///< Memorize largest height of the set. mutable int width; ///< Memorize largest width of the set. public: RGBAImageSet(); ~RGBAImageSet(); /// Remove all images. void Clear(); /// Add an image. void Add(int ident, RGBAImage *image); /// Get image by id. RGBAImage *Get(int ident); /// Give the largest height of the set. int GetHeight() const; /// Give the largest width of the set. int GetWidth() const; }; #ifdef SCI_NAMESPACE } #endif #endif |
Added test/MessageNumbers.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# List many windows message numbers msgs = { "WM_ACTIVATE":6, "WM_ACTIVATEAPP":28, "WM_CAPTURECHANGED":533, "WM_CHAR":258, "WM_CLOSE":16, "WM_CREATE":1, "WM_COMMAND":273, "WM_DESTROY":2, "WM_ENTERSIZEMOVE":561, "WM_ERASEBKGND":20, "WM_EXITSIZEMOVE":562, "WM_GETMINMAXINFO":36, "WM_GETTEXT":13, "WM_IME_SETCONTEXT":0x0281, "WM_IME_NOTIFY":0x0282, "WM_KEYDOWN":256, "WM_KEYUP":257, "WM_KILLFOCUS":8, "WM_LBUTTONDOWN":513, "WM_LBUTTONUP":514, "WM_MBUTTONDOWN":519, "WM_MBUTTONUP":520, "WM_MBUTTONDBLCLK":521, "WM_MOUSEACTIVATE":33, "WM_MOUSEMOVE":512, "WM_MOVE":3, "WM_MOVING":534, "WM_NCACTIVATE":134, "WM_NCCALCSIZE":131, "WM_NCCREATE":129, "WM_NCDESTROY":130, "WM_NCHITTEST":132, "WM_NCLBUTTONDBLCLK":163, "WM_NCLBUTTONDOWN":161, "WM_NCLBUTTONUP":162, "WM_NCMOUSEMOVE":160, "WM_NCPAINT":133, "WM_PAINT":15, "WM_PARENTNOTIFY":528, "WM_SETCURSOR":32, "WM_SETFOCUS":7, "WM_SETFONT":48, "WM_SETTEXT":12, "WM_SHOWWINDOW":24, "WM_SIZE":5, "WM_SIZING":532, "WM_SYNCPAINT":136, "WM_SYSCOMMAND":274, "WM_SYSKEYDOWN":260, "WM_TIMER":275, "WM_USER":1024, "WM_USER+1":1025, "WM_WINDOWPOSCHANGED":71, "WM_WINDOWPOSCHANGING":70, } sgsm={} for k,v in msgs.items(): sgsm[v] = k |
Added test/README.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
The test directory contains some unit and performance tests for Scintilla. The tests can only be run on Windows using Python 2.7 or 3.x. Running on another platform would require writing a file similar to XiteWin.py for that platform. Python 2.7+ is required because the bytes string type and literals are available. A test application is in xite.py and this can be run to experiment: pythonw xite.py To run the basic tests: pythonw simpleTests.py There are some lexing tests with simple input files in several languages in the examples subdirectory and their expected lexed states in *.styled where the start of each style is marked with {styleNumber}, for example: {15}<%@{16}language=javas{15}%>{0} To run the lexing tests: pythonw lexTests.py To check for performance regressions: pythonw performanceTests.py While each test run will be different and the timer has only limited granularity, some results from a 2 GHz Athlon with a DEBUG build are: 0.187 testAddLine . 0.203 testAddLineMiddle . 0.171 testHuge . 0.203 testHugeInserts . 0.312 testHugeReplace . |
Added test/XiteMenu.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# -*- coding: utf-8 -*- from __future__ import unicode_literals """ Define the menu structure used by the Pentacle applications """ MenuStructure = [ ["&File", [ ["&New", "<control>N"], ["&Open...", "<control>O"], ["&Save", "<control>S"], ["Save &As...", "<control><shift>S"], ["Test", ""], ["Exercised", ""], ["Uncalled", ""], ["-", ""], ["&Exit", ""]]], [ "&Edit", [ ["&Undo", "<control>Z"], ["&Redo", "<control>Y"], ["-", ""], ["Cu&t", "<control>X"], ["&Copy", "<control>C"], ["&Paste", "<control>V"], ["&Delete", "Del"], ["Select &All", "<control>A"], ]], ] |
Added test/XiteWin.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 |
# -*- coding: utf-8 -*- from __future__ import with_statement from __future__ import unicode_literals import os, sys, unittest import ctypes from ctypes import wintypes from ctypes import c_int, c_ulong, c_char_p, c_wchar_p, c_ushort user32=ctypes.windll.user32 gdi32=ctypes.windll.gdi32 kernel32=ctypes.windll.kernel32 from MessageNumbers import msgs, sgsm import XiteMenu scintillaDirectory = ".." scintillaIncludeDirectory = os.path.join(scintillaDirectory, "include") sys.path.append(scintillaIncludeDirectory) import Face scintillaBinDirectory = os.path.join(scintillaDirectory, "bin") os.environ['PATH'] = os.environ['PATH'] + ";" + scintillaBinDirectory #print(os.environ['PATH']) WFUNC = ctypes.WINFUNCTYPE(c_int, c_int, c_int, c_int, c_int) WS_CHILD = 0x40000000 WS_CLIPCHILDREN = 0x2000000 WS_OVERLAPPEDWINDOW = 0xcf0000 WS_VISIBLE = 0x10000000 WS_HSCROLL = 0x100000 WS_VSCROLL = 0x200000 WA_INACTIVE = 0 MF_POPUP = 16 MF_SEPARATOR = 0x800 IDYES = 6 OFN_HIDEREADONLY = 4 MB_OK = 0 MB_YESNOCANCEL = 3 MF_CHECKED = 8 MF_UNCHECKED = 0 SW_SHOW = 5 PM_REMOVE = 1 VK_SHIFT = 16 VK_CONTROL = 17 VK_MENU = 18 class OPENFILENAME(ctypes.Structure): _fields_ = (("lStructSize", c_int), ("hwndOwner", c_int), ("hInstance", c_int), ("lpstrFilter", c_wchar_p), ("lpstrCustomFilter", c_char_p), ("nMaxCustFilter", c_int), ("nFilterIndex", c_int), ("lpstrFile", c_wchar_p), ("nMaxFile", c_int), ("lpstrFileTitle", c_wchar_p), ("nMaxFileTitle", c_int), ("lpstrInitialDir", c_wchar_p), ("lpstrTitle", c_wchar_p), ("flags", c_int), ("nFileOffset", c_ushort), ("nFileExtension", c_ushort), ("lpstrDefExt", c_char_p), ("lCustData", c_int), ("lpfnHook", c_char_p), ("lpTemplateName", c_char_p), ("pvReserved", c_char_p), ("dwReserved", c_int), ("flagsEx", c_int)) def __init__(self, win, title): ctypes.Structure.__init__(self) self.lStructSize = ctypes.sizeof(OPENFILENAME) self.nMaxFile = 1024 self.hwndOwner = win self.lpstrTitle = title self.Flags = OFN_HIDEREADONLY trace = False #~ trace = True def WindowSize(w): rc = ctypes.wintypes.RECT() user32.GetClientRect(w, ctypes.byref(rc)) return rc.right - rc.left, rc.bottom - rc.top def IsKeyDown(key): return (user32.GetKeyState(key) & 0x8000) != 0 def KeyTranslate(w): tr = { 9: "Tab", 0xD:"Enter", 0x1B: "Esc" } if w in tr: return tr[w] elif ord("A") <= w <= ord("Z"): return chr(w) elif 0x70 <= w <= 0x7b: return "F" + str(w-0x70+1) else: return "Unknown_" + hex(w) class WNDCLASS(ctypes.Structure): _fields_= (\ ('style', c_int), ('lpfnWndProc', WFUNC), ('cls_extra', c_int), ('wnd_extra', c_int), ('hInst', c_int), ('hIcon', c_int), ('hCursor', c_int), ('hbrBackground', c_int), ('menu_name', c_wchar_p), ('lpzClassName', c_wchar_p), ) class XTEXTRANGE(ctypes.Structure): _fields_= (\ ('cpMin', c_int), ('cpMax', c_int), ('lpstrText', c_char_p), ) class TEXTRANGE(ctypes.Structure): _fields_= (\ ('cpMin', c_int), ('cpMax', c_int), ('lpstrText', ctypes.POINTER(ctypes.c_char)), ) class FINDTEXT(ctypes.Structure): _fields_= (\ ('cpMin', c_int), ('cpMax', c_int), ('lpstrText', c_char_p), ('cpMinText', c_int), ('cpMaxText', c_int), ) hinst = ctypes.windll.kernel32.GetModuleHandleW(0) def RegisterClass(name, func, background = 0): # register a window class for toplevel windows. wc = WNDCLASS() wc.style = 0 wc.lpfnWndProc = func wc.cls_extra = 0 wc.wnd_extra = 0 wc.hInst = hinst wc.hIcon = 0 wc.hCursor = 0 wc.hbrBackground = background wc.menu_name = 0 wc.lpzClassName = name user32.RegisterClassW(ctypes.byref(wc)) class SciCall: def __init__(self, fn, ptr, msg): self._fn = fn self._ptr = ptr self._msg = msg def __call__(self, w=0, l=0): return self._fn(self._ptr, self._msg, w, l) class Scintilla: def __init__(self, face, hwndParent, hinstance): self.__dict__["face"] = face self.__dict__["used"] = set() self.__dict__["all"] = set() # The k member is for accessing constants as a dictionary self.__dict__["k"] = {} for f in face.features: self.all.add(f) if face.features[f]["FeatureType"] == "val": self.k[f] = int(self.face.features[f]["Value"], 0) elif face.features[f]["FeatureType"] == "evt": self.k["SCN_"+f] = int(self.face.features[f]["Value"], 0) # Get the function first as that also loads the DLL self.__dict__["_scifn"] = ctypes.windll.SciLexer.Scintilla_DirectFunction self.__dict__["_hwnd"] = user32.CreateWindowExW(0, "Scintilla", "Source", WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_CLIPCHILDREN, 0, 0, 100, 100, hwndParent, 0, hinstance, 0) self.__dict__["_sciptr"] = user32.SendMessageW(self._hwnd, int(self.face.features["GetDirectPointer"]["Value"], 0), 0,0) user32.ShowWindow(self._hwnd, SW_SHOW) def __getattr__(self, name): if name in self.face.features: self.used.add(name) feature = self.face.features[name] value = int(feature["Value"], 0) #~ print("Feature", name, feature) if feature["FeatureType"] == "val": self.__dict__[name] = value return value else: return SciCall(self._scifn, self._sciptr, value) elif ("Get" + name) in self.face.features: self.used.add("Get" + name) feature = self.face.features["Get" + name] value = int(feature["Value"], 0) if feature["FeatureType"] == "get" and \ not name.startswith("Get") and \ not feature["Param1Type"] and \ not feature["Param2Type"] and \ feature["ReturnType"] in ["bool", "int", "position"]: #~ print("property", feature) return self._scifn(self._sciptr, value, 0, 0) elif name.startswith("SCN_") and name in self.k: self.used.add(name) feature = self.face.features[name[4:]] value = int(feature["Value"], 0) #~ print("Feature", name, feature) if feature["FeatureType"] == "val": return value raise AttributeError(name) def __setattr__(self, name, val): if ("Set" + name) in self.face.features: self.used.add("Set" + name) feature = self.face.features["Set" + name] value = int(feature["Value"], 0) #~ print("setproperty", feature) if feature["FeatureType"] == "set" and not name.startswith("Set"): if feature["Param1Type"] in ["bool", "int", "position"]: return self._scifn(self._sciptr, value, val, 0) elif feature["Param2Type"] in ["string"]: return self._scifn(self._sciptr, value, 0, val) raise AttributeError(name) raise AttributeError(name) def getvalue(self, name): if name in self.face.features: feature = self.face.features[name] if feature["FeatureType"] != "evt": try: return int(feature["Value"], 0) except ValueError: return -1 return -1 def ByteRange(self, start, end): tr = TEXTRANGE() tr.cpMin = start tr.cpMax = end length = end - start tr.lpstrText = ctypes.create_string_buffer(length + 1) self.GetTextRange(0, ctypes.byref(tr)) text = tr.lpstrText[:length] text += b"\0" * (length - len(text)) return text def StyledTextRange(self, start, end): tr = TEXTRANGE() tr.cpMin = start tr.cpMax = end length = 2 * (end - start) tr.lpstrText = ctypes.create_string_buffer(length + 2) self.GetStyledText(0, ctypes.byref(tr)) styledText = tr.lpstrText[:length] styledText += b"\0" * (length - len(styledText)) return styledText def FindBytes(self, start, end, s, flags): ft = FINDTEXT() ft.cpMin = start ft.cpMax = end ft.lpstrText = s ft.cpMinText = 0 ft.cpMaxText = 0 pos = self.FindText(flags, ctypes.byref(ft)) #~ print(start, end, ft.cpMinText, ft.cpMaxText) return pos def Contents(self): return self.ByteRange(0, self.Length) def SizeTo(self, width, height): user32.SetWindowPos(self._hwnd, 0, 0, 0, width, height, 0) def FocusOn(self): user32.SetFocus(self._hwnd) class XiteWin(): def __init__(self, test=""): self.face = Face.Face() self.face.ReadFromFile(os.path.join(scintillaIncludeDirectory, "Scintilla.iface")) self.titleDirty = True self.fullPath = "" self.test = test self.appName = "xite" self.cmds = {} self.windowName = "XiteWindow" self.wfunc = WFUNC(self.WndProc) RegisterClass(self.windowName, self.wfunc) user32.CreateWindowExW(0, self.windowName, self.appName, \ WS_VISIBLE | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, \ 0, 0, 500, 700, 0, 0, hinst, 0) args = sys.argv[1:] self.SetMenus() if args: self.GrabFile(args[0]) self.ed.FocusOn() self.ed.GotoPos(self.ed.Length) if self.test: print(self.test) for k in self.cmds: if self.cmds[k] == "Test": user32.PostMessageW(self.win, msgs["WM_COMMAND"], k, 0) def OnSize(self): width, height = WindowSize(self.win) self.ed.SizeTo(width, height) user32.InvalidateRect(self.win, 0, 0) def OnCreate(self, hwnd): self.win = hwnd self.ed = Scintilla(self.face, hwnd, hinst) self.ed.FocusOn() def Invalidate(self): user32.InvalidateRect(self.win, 0, 0) def WndProc(self, h, m, w, l): ms = sgsm.get(m, "XXX") if trace: print("%s %s %s %s" % (hex(h)[2:],ms,w,l)) if ms == "WM_CLOSE": user32.PostQuitMessage(0) elif ms == "WM_CREATE": self.OnCreate(h) return 0 elif ms == "WM_SIZE": # Work out size if w != 1: self.OnSize() return 0 elif ms == "WM_COMMAND": cmdCode = w & 0xffff if cmdCode in self.cmds: self.Command(self.cmds[cmdCode]) return 0 elif ms == "WM_ACTIVATE": if w != WA_INACTIVE: self.ed.FocusOn() return 0 else: return user32.DefWindowProcW(h, m, w, l) return 0 def Command(self, name): name = name.replace(" ", "") method = "Cmd" + name cmd = None try: cmd = getattr(self, method) except AttributeError: return if cmd: cmd() def KeyDown(self, w, prefix = ""): keyName = prefix if IsKeyDown(VK_CONTROL): keyName += "<control>" if IsKeyDown(VK_SHIFT): keyName += "<shift>" keyName += KeyTranslate(w) if trace: print("Key:", keyName) if keyName in self.keys: method = "Cmd" + self.keys[keyName] getattr(self, method)() return True #~ print("UKey:", keyName) return False def Accelerator(self, msg): ms = sgsm.get(msg.message, "XXX") if ms == "WM_KEYDOWN": return self.KeyDown(msg.wParam) elif ms == "WM_SYSKEYDOWN": return self.KeyDown(msg.wParam, "<alt>") return False def AppLoop(self): msg = ctypes.wintypes.MSG() lpmsg = ctypes.byref(msg) while user32.GetMessageW(lpmsg, 0, 0, 0): if trace and msg.message != msgs["WM_TIMER"]: print('mm', hex(msg.hWnd)[2:],sgsm.get(msg.message, "XXX")) if not self.Accelerator(msg): user32.TranslateMessage(lpmsg) user32.DispatchMessageW(lpmsg) def DoEvents(self): msg = ctypes.wintypes.MSG() lpmsg = ctypes.byref(msg) cont = True while cont: cont = user32.PeekMessageW(lpmsg, 0, 0, 0, PM_REMOVE) if cont: if not self.Accelerator(msg): user32.TranslateMessage(lpmsg) user32.DispatchMessageW(lpmsg) def SetTitle(self, changePath): if changePath or self.titleDirty != self.ed.Modify: self.titleDirty = self.ed.Modify self.title = self.fullPath if self.titleDirty: self.title += " * " else: self.title += " - " self.title += self.appName if self.win: user32.SetWindowTextW(self.win, self.title) def Open(self): ofx = OPENFILENAME(self.win, "Open File") opath = "\0" * 1024 ofx.lpstrFile = opath filters = ["Python (.py;.pyw)|*.py;*.pyw|All|*.*"] filterText = "\0".join([f.replace("|", "\0") for f in filters])+"\0\0" ofx.lpstrFilter = filterText if ctypes.windll.comdlg32.GetOpenFileNameW(ctypes.byref(ofx)): absPath = opath.replace("\0", "") self.GrabFile(absPath) self.ed.FocusOn() self.ed.LexerLanguage = "python" self.ed.Lexer = self.ed.SCLEX_PYTHON self.ed.SetKeyWords(0, b"class def else for from if import print return while") for style in [k for k in self.ed.k if k.startswith("SCE_P_")]: self.ed.StyleSetFont(self.ed.k[style], b"Verdana") if "COMMENT" in style: self.ed.StyleSetFore(self.ed.k[style], 127 * 256) self.ed.StyleSetFont(self.ed.k[style], b"Comic Sans MS") elif "OPERATOR" in style: self.ed.StyleSetBold(self.ed.k[style], 1) self.ed.StyleSetFore(self.ed.k[style], 127 * 256 * 256) elif "WORD" in style: self.ed.StyleSetItalic(self.ed.k[style], 255) self.ed.StyleSetFore(self.ed.k[style], 255 * 256 * 256) elif "TRIPLE" in style: self.ed.StyleSetFore(self.ed.k[style], 0xA0A0) elif "STRING" in style or "CHARACTER" in style: self.ed.StyleSetFore(self.ed.k[style], 0xA000A0) else: self.ed.StyleSetFore(self.ed.k[style], 0) def SaveAs(self): ofx = OPENFILENAME(self.win, "Save File") opath = "\0" * 1024 ofx.lpstrFile = opath if ctypes.windll.comdlg32.GetSaveFileNameW(ctypes.byref(ofx)): self.fullPath = opath.replace("\0", "") self.Save() self.SetTitle(1) self.ed.FocusOn() def SetMenus(self): ui = XiteMenu.MenuStructure self.cmds = {} self.keys = {} cmdId = 0 self.menuBar = user32.CreateMenu() for name, contents in ui: cmdId += 1 menu = user32.CreateMenu() for item in contents: text, key = item cmdText = text.replace("&", "") cmdText = cmdText.replace("...", "") cmdText = cmdText.replace(" ", "") cmdId += 1 if key: keyText = key.replace("<control>", "Ctrl+") keyText = keyText.replace("<shift>", "Shift+") text += "\t" + keyText if text == "-": user32.AppendMenuW(menu, MF_SEPARATOR, cmdId, text) else: user32.AppendMenuW(menu, 0, cmdId, text) self.cmds[cmdId] = cmdText self.keys[key] = cmdText #~ print(cmdId, item) user32.AppendMenuW(self.menuBar, MF_POPUP, menu, name) user32.SetMenu(self.win, self.menuBar) self.CheckMenuItem("Wrap", True) user32.ShowWindow(self.win, SW_SHOW) def CheckMenuItem(self, name, val): #~ print(name, val) if self.cmds: for k,v in self.cmds.items(): if v == name: #~ print(name, k) user32.CheckMenuItem(user32.GetMenu(self.win), \ k, [MF_UNCHECKED, MF_CHECKED][val]) def Exit(self): sys.exit(0) def DisplayMessage(self, msg, ask): return IDYES == user32.MessageBoxW(self.win, \ msg, self.appName, [MB_OK, MB_YESNOCANCEL][ask]) def NewDocument(self): self.ed.ClearAll() self.ed.EmptyUndoBuffer() self.ed.SetSavePoint() def SaveIfUnsure(self): if self.ed.Modify: msg = "Save changes to \"" + self.fullPath + "\"?" print(msg) decision = self.DisplayMessage(msg, True) if decision: self.CmdSave() return decision return True def New(self): if self.SaveIfUnsure(): self.fullPath = "" self.overrideMode = None self.NewDocument() self.SetTitle(1) self.Invalidate() def CheckMenus(self): pass def MoveSelection(self, caret, anchor=-1): if anchor == -1: anchor = caret self.ed.SetSelectionStart(caret) self.ed.SetSelectionEnd(anchor) self.ed.ScrollCaret() self.Invalidate() def GrabFile(self, name): self.fullPath = name self.overrideMode = None self.NewDocument() fsr = open(name, "rb") data = fsr.read() fsr.close() self.ed.AddText(len(data), data) self.ed.EmptyUndoBuffer() self.MoveSelection(0) self.SetTitle(1) def Save(self): fos = open(self.fullPath, "wb") blockSize = 1024 length = self.ed.Length i = 0 while i < length: grabSize = length - i if grabSize > blockSize: grabSize = blockSize #~ print(i, grabSize, length) data = self.ed.ByteRange(i, i + grabSize) fos.write(data) i += grabSize fos.close() self.ed.SetSavePoint() self.SetTitle(0) # Command handlers are called by menu actions def CmdNew(self): self.New() def CmdOpen(self): self.Open() def CmdSave(self): if (self.fullPath == None) or (len(self.fullPath) == 0): self.SaveAs() else: self.Save() def CmdSaveAs(self): self.SaveAs() def CmdTest(self): runner = unittest.TextTestRunner() if self.test: tests = unittest.defaultTestLoader.loadTestsFromName(self.test) else: tests = unittest.defaultTestLoader.loadTestsFromName("simpleTests") results = runner.run(tests) #~ print(results) if self.test: user32.PostQuitMessage(0) def CmdExercised(self): print() unused = sorted(self.ed.all.difference(self.ed.used)) print("Unused", len(unused)) print() print("\n".join(unused)) print() print("Used", len(self.ed.used)) print() print("\n".join(sorted(self.ed.used))) def Uncalled(self): print("") unused = sorted(self.ed.all.difference(self.ed.used)) uu = {} for u in unused: v = self.ed.getvalue(u) if v > 2000: uu[v] = u #~ for x in sorted(uu.keys())[150:]: return uu def CmdExit(self): self.Exit() def CmdUndo(self): self.ed.Undo() def CmdRedo(self): self.ed.Redo() def CmdCut(self): self.ed.Cut() def CmdCopy(self): self.ed.Copy() def CmdPaste(self): self.ed.Paste() def CmdDelete(self): self.ed.Clear() xiteFrame = None def main(test): global xiteFrame xiteFrame = XiteWin(test) xiteFrame.AppLoop() #~ xiteFrame.CmdExercised() return xiteFrame.Uncalled() |
Added test/examples/x.asp.
> > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 |
<%@language=javas%> <% #include function x() { } %> <%@language=vbscript%> <% sub x 'comment %> <head> <body></body> |
Added test/examples/x.asp.styled.
> > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 |
{15}<%@{16}language=javas{15}%>{0} {15}<%{56} #{61}include{56} {62}function{56} {61}x{65}(){56} {65}{{56} {65}}{56} {15}%>{0} {15}<%@{16}language=vbscript{15}%>{0} {15}<%{81} {84}sub{81} {86}x{81} {82}'comment {81} {15}%>{0} {1}<head>{0} {1}<body></body>{0} |
Added test/examples/x.cxx.
> > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// A demonstration program #include <stdio.h> #if 0 /* */ #define DUMMY() \ if (1); #endif #define M\ \ int main() { double x[] = {3.14159,6.02e23,1.6e-19,1.0+1}; int y[] = {75,0113,0x4b}; printf("hello world %d %g\n", y[0], x[0]); } |
Added test/examples/x.cxx.styled.
> > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{2}// A demonstration program {9}#include <stdio.h> #if 0 {23}/* */{9} {73}#define DUMMY() \ if (1); {9}#endif {0} {9}#define M\ {0}\ {5}int{0} {11}main{10}(){0} {10}{{0} {11}double{0} {11}x{10}[]{0} {10}={0} {10}{{4}3.14159{10},{4}6.02e23{10},{4}1.6e-19{10},{4}1.0{10}+{4}1{10}};{0} {5}int{0} {11}y{10}[]{0} {10}={0} {10}{{4}75{10},{4}0113{10},{4}0x4b{10}};{0} {11}printf{10}({6}"hello world %d %g\n"{10},{0} {11}y{10}[{4}0{10}],{0} {11}x{10}[{4}0{10}]);{0} {10}}{0} |
Added test/examples/x.d.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
$ // /++ +/ doccomments are not yet supported /* */ /** */ /// drdr /+ /+ +/ +/ //keyword test keyword1 keyword2 keyword4 keyword5 keyword6 keyword7 //unicode identifier test вапёasdÓΘΣαԷԸՑהכ拉麺とひシマイ단결을 //strings test 's ' w's'w "multiline string"w e"zz"e r"asd\"e r"multiline string"c r`asd\`e `multiline string`d x"023 abc"e x"023 abc"w //numbers test a[3..4]=3 2.stringof 2.0.stringof 2. 2.2e+2 2.2e-2 .2e+2 .2 2e+2 0x2e+2 0x2ep+10 ,.2.stringof, end |
Added test/examples/x.d.styled.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
{14}${0} {2}// /++ +/ doccomments are not yet supported {1}/* */{0} {3}/** */{0} {15}/// drdr {4}/+ /+ +/ +/{0} {2}//keyword test {6}keyword1{0} {7}keyword2{0} {9}keyword4{0} {20}keyword5{0} {21}keyword6{0} {22}keyword7{0} {2}//unicode identifier test {14}вапёasdÓΘΣαԷԸՑהכ拉麺とひシマイ단결을{0} {2}//strings test {11}'s ' {14}w{12}'s'{14}w{0} {10}"multiline string"w{0} {14}e{10}"zz"{14}e{0} {19}r"asd\"{14}e{0} {19}r"multiline string"c{0} {14}r{18}`asd\`{14}e{0} {18}`multiline string`d{0} {19}x"023 abc"{14}e{0} {19}x"023 abc"w{0} {2}//numbers test {14}a{13}[{5}3{13}..{5}4{13}]={5}3{0} {5}2.stringof{0} {5}2.0{13}.{14}stringof{0} {5}2.{0} {5}2.2e+2{0} {5}2.2e-2{0} {5}.2e+2{0} {5}.2{0} {5}2e+2{0} {5}0x2e{13}+{5}2{0} {5}0x2ep+10{0} {13},{5}.2{13}.{14}stringof{13},{0} {14}end{0} |
Added test/examples/x.html.
> > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 |
<html xmlns="http://www.w3.org/1999/xhtml"> <script type="text/javascript"> var b = /abc/i.test('abc'); 'x\ </t>' </script> <head> <meta name="Date.Modified" content="20010515" /> <title>SinkWorld - Portability</title> <unknown>SinkWorld - Portability</unknown> <link rel="stylesheet" type="text/css" href="SW.css"> </head> |
Added test/examples/x.html.styled.
> > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 |
{1}<html{8} {3}xmlns{8}={6}"http://www.w3.org/1999/xhtml"{1}>{0} {1}<script{8} {3}type{8}={6}"text/javascript"{1}>{40} {46}var{41} {46}b{41} {50}={41} {52}/abc/i{46}.test{50}({49}'abc'{50});{41} {49}'x\ </t>'{41} {1}</script>{0} {1}<head>{0} {1}<meta{8} {3}name{8}={6}"Date.Modified"{8} {3}content{8}={6}"20010515"{8} {11}/>{0} {1}<title>{0}SinkWorld - Portability{1}</title>{0} {2}<unknown>{0}SinkWorld - Portability{2}</unknown>{0} {1}<link{8} {3}rel{8}={6}"stylesheet"{8} {3}type{8}={6}"text/css"{8} {3}href{8}={6}"SW.css"{1}>{0} {1}</head>{0} |
Added test/examples/x.php.
> > > > > > |
1 2 3 4 5 6 |
<head> <!-- About to script --> <?php echo "<!-- -->\n"; /* ?> */ ?> <strong>for</strong><b>if</b> |
Added test/examples/x.php.styled.
> > > > > > |
1 2 3 4 5 6 |
{1}<head>{0} {9}<!-- About to script -->{0} {18}<?php{118} echo {119}"<!-- -->\n"{127};{118} {124}/* ?> */{118} {18}?>{0} {1}<strong>{0}for{1}</strong><b>{0}if{1}</b>{0} |
Added test/examples/x.py.
> > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 |
# Convert all punctuation characters except '_', '*', and '.' into spaces. def depunctuate(s): '''A docstring''' """Docstring 2""" d = "" for ch in s: if ch in 'abcde': d = d + ch else: d = d + " " return d |
Added test/examples/x.py.styled.
> > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 |
{1}# Convert all punctuation characters except '_', '*', and '.' into spaces.{0} {5}def{0} {9}depunctuate{10}({11}s{10}):{0} {6}'''A docstring'''{0} {7}"""Docstring 2"""{0} {11}d{0} {10}={0} {3}""{0} {5}for{0} {11}ch{0} {5}in{0} {11}s{10}:{0} {5}if{0} {11}ch{0} {5}in{0} {4}'abcde'{10}:{0} {11}d{0} {10}={0} {11}d{0} {10}+{0} {11}ch{0} {5}else{10}:{0} {11}d{0} {10}={0} {11}d{0} {10}+{0} {3}" "{0} {5}return{0} {11}d{0} |
Added test/examples/x.vb.
> > > > > > > > > |
1 2 3 4 5 6 7 8 9 |
' String" Dim a As String = "hello, world" Dim b As String = "hello world" Dim c As String = "Joe said ""Hello"" to me" Dim d As String = "\\\\server\\share\\file.txt" ' Character ""C "c"C "cc"C ' Date d = #5/31/1993# or # 01/01/0001 12:00:00AM # |
Added test/examples/x.vb.styled.
> > > > > > > > > |
1 2 3 4 5 6 7 8 9 |
{1}' String" {3}Dim{0} {7}a{0} {3}As{0} {3}String{0} {6}={0} {4}"hello, world"{0} {3}Dim{0} {7}b{0} {3}As{0} {3}String{0} {6}={0} {4}"hello world"{0} {3}Dim{0} {7}c{0} {3}As{0} {3}String{0} {6}={0} {4}"Joe said ""Hello"" to me"{0} {3}Dim{0} {7}d{0} {3}As{0} {3}String{0} {6}={0} {4}"\\\\server\\share\\file.txt"{0} {1}' Character {4}""C{0} {4}"c"C{0} {4}"cc"C{0} {1}' Date {7}d{0} {6}={0} {8}#5/31/1993#{0} {3}or{0} {8}# 01/01/0001 12:00:00AM #{0} |
Added test/lexTests.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# -*- coding: utf-8 -*- from __future__ import with_statement import io import os import unittest import XiteWin keywordsHTML = [ b"b body content head href html link meta " b"name rel script strong title type xmlns", b"function", b"sub" ] class TestLexers(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() def AsStyled(self): text = self.ed.Contents() data = io.BytesIO() prevStyle = -1 for o in range(self.ed.Length): styleNow = self.ed.GetStyleAt(o) if styleNow != prevStyle: styleBuf = "{%0d}" % styleNow data.write(styleBuf.encode('utf-8')) prevStyle = styleNow data.write(text[o:o+1]) return data.getvalue() def LexExample(self, name, lexerName, keywords=None): if keywords is None: keywords = [] self.ed.LexerLanguage = lexerName bits = self.ed.StyleBitsNeeded mask = 2 << bits - 1 self.ed.StyleBits = bits for i in range(len(keywords)): self.ed.SetKeyWords(i, keywords[i]) nameExample = os.path.join("examples", name) namePrevious = nameExample +".styled" nameNew = nameExample +".new" with open(nameExample, "rb") as f: prog = f.read() BOM = b"\xEF\xBB\xBF" if prog.startswith(BOM): prog = prog[len(BOM):] lenDocument = len(prog) self.ed.AddText(lenDocument, prog) self.ed.Colourise(0, lenDocument) self.assertEquals(self.ed.EndStyled, lenDocument) with open(namePrevious, "rb") as f: prevStyled = f.read() progStyled = self.AsStyled() if progStyled != prevStyled: with open(nameNew, "wb") as f: f.write(progStyled) print(progStyled) print(prevStyled) self.assertEquals(progStyled, prevStyled) # The whole file doesn't parse like it did before so don't try line by line # as that is likely to fail many times. return # Try partial lexes from the start of every line which should all be identical. for line in range(self.ed.LineCount): lineStart = self.ed.PositionFromLine(line) self.ed.StartStyling(lineStart, mask) self.assertEquals(self.ed.EndStyled, lineStart) self.ed.Colourise(lineStart, lenDocument) progStyled = self.AsStyled() if progStyled != prevStyled: with open(nameNew, "wb") as f: f.write(progStyled) self.assertEquals(progStyled, prevStyled) # Give up after one failure return def testCXX(self): self.LexExample("x.cxx", b"cpp", [b"int"]) def testPython(self): self.LexExample("x.py", b"python", [b"class def else for if import in print return while"]) def testHTML(self): self.LexExample("x.html", b"hypertext", keywordsHTML) def testASP(self): self.LexExample("x.asp", b"hypertext", keywordsHTML) def testPHP(self): self.LexExample("x.php", b"hypertext", keywordsHTML) def testVB(self): self.LexExample("x.vb", b"vb", [b"as dim or string"]) def testD(self): self.LexExample("x.d", b"d", [b"keyword1", b"keyword2", b"", b"keyword4", b"keyword5", b"keyword6", b"keyword7"]) if __name__ == '__main__': XiteWin.main("lexTests") |
Added test/performanceTests.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# -*- coding: utf-8 -*- from __future__ import with_statement from __future__ import unicode_literals import os, string, time, unittest import XiteWin class TestPerformance(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() def testAddLine(self): data = (string.ascii_letters + string.digits + "\n").encode('utf-8') start = time.time() for i in range(1000): self.ed.AddText(len(data), data) self.assertEquals(self.ed.LineCount, i + 2) end = time.time() duration = end - start print("%6.3f testAddLine" % duration) self.xite.DoEvents() self.assert_(self.ed.Length > 0) def testAddLineMiddle(self): data = (string.ascii_letters + string.digits + "\n").encode('utf-8') start = time.time() for i in range(1000): self.ed.AddText(len(data), data) self.assertEquals(self.ed.LineCount, i + 2) end = time.time() duration = end - start print("%6.3f testAddLineMiddle" % duration) self.xite.DoEvents() self.assert_(self.ed.Length > 0) def testHuge(self): data = (string.ascii_letters + string.digits + "\n").encode('utf-8') data = data * 100000 start = time.time() self.ed.AddText(len(data), data) end = time.time() duration = end - start print("%6.3f testHuge" % duration) self.xite.DoEvents() self.assert_(self.ed.Length > 0) def testHugeInserts(self): data = (string.ascii_letters + string.digits + "\n").encode('utf-8') data = data * 100000 insert = (string.digits + "\n").encode('utf-8') self.ed.AddText(len(data), data) start = time.time() for i in range(1000): self.ed.InsertText(0, insert) end = time.time() duration = end - start print("%6.3f testHugeInserts" % duration) self.xite.DoEvents() self.assert_(self.ed.Length > 0) def testHugeReplace(self): oneLine = (string.ascii_letters + string.digits + "\n").encode('utf-8') data = oneLine * 100000 insert = (string.digits + "\n").encode('utf-8') self.ed.AddText(len(data), data) start = time.time() for i in range(1000): self.ed.TargetStart = i * len(insert) self.ed.TargetEnd = self.ed.TargetStart + len(oneLine) self.ed.ReplaceTarget(len(insert), insert) end = time.time() duration = end - start print("%6.3f testHugeReplace" % duration) self.xite.DoEvents() self.assert_(self.ed.Length > 0) if __name__ == '__main__': XiteWin.main("performanceTests") |
Added test/simpleTests.py.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 |
# -*- coding: utf-8 -*- from __future__ import with_statement from __future__ import unicode_literals import codecs, ctypes, os, sys, unittest import XiteWin class TestSimple(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() def testLength(self): self.assertEquals(self.ed.Length, 0) def testAddText(self): self.ed.AddText(1, "x") self.assertEquals(self.ed.Length, 1) self.assertEquals(self.ed.GetCharAt(0), ord("x")) self.assertEquals(self.ed.GetStyleAt(0), 0) self.ed.ClearAll() self.assertEquals(self.ed.Length, 0) def testDeleteRange(self): self.ed.AddText(5, b"abcde") self.assertEquals(self.ed.Length, 5) self.ed.DeleteRange(1, 2) self.assertEquals(self.ed.Length, 3) self.assertEquals(self.ed.Contents(), b"ade") def testAddStyledText(self): self.assertEquals(self.ed.EndStyled, 0) self.ed.AddStyledText(2, b"x\002") self.assertEquals(self.ed.Length, 1) self.assertEquals(self.ed.GetCharAt(0), ord("x")) self.assertEquals(self.ed.GetStyleAt(0), 2) self.assertEquals(self.ed.StyledTextRange(0, 1), b"x\002") self.ed.ClearDocumentStyle() self.assertEquals(self.ed.Length, 1) self.assertEquals(self.ed.GetCharAt(0), ord("x")) self.assertEquals(self.ed.GetStyleAt(0), 0) self.assertEquals(self.ed.StyledTextRange(0, 1), b"x\0") def testStyling(self): self.assertEquals(self.ed.EndStyled, 0) self.ed.AddStyledText(4, b"x\002y\003") self.assertEquals(self.ed.StyledTextRange(0, 2), b"x\002y\003") self.ed.StartStyling(0,0xf) self.ed.SetStyling(1, 5) self.assertEquals(self.ed.StyledTextRange(0, 2), b"x\005y\003") # Set the mask so 0 bit changed but not 2 bit self.ed.StartStyling(0,0x1) self.ed.SetStyling(1, 0) self.assertEquals(self.ed.StyledTextRange(0, 2), b"x\004y\003") self.ed.StartStyling(0,0xff) self.ed.SetStylingEx(2, b"\100\101") self.assertEquals(self.ed.StyledTextRange(0, 2), b"x\100y\101") def testPosition(self): self.assertEquals(self.ed.CurrentPos, 0) self.assertEquals(self.ed.Anchor, 0) self.ed.AddText(1, "x") # Caret has automatically moved self.assertEquals(self.ed.CurrentPos, 1) self.assertEquals(self.ed.Anchor, 1) self.ed.SelectAll() self.assertEquals(self.ed.CurrentPos, 0) self.assertEquals(self.ed.Anchor, 1) self.ed.Anchor = 0 self.assertEquals(self.ed.Anchor, 0) # Check line positions self.assertEquals(self.ed.PositionFromLine(0), 0) self.assertEquals(self.ed.GetLineEndPosition(0), 1) self.assertEquals(self.ed.PositionFromLine(1), 1) self.ed.CurrentPos = 1 self.assertEquals(self.ed.Anchor, 0) self.assertEquals(self.ed.CurrentPos, 1) def testSelection(self): self.assertEquals(self.ed.CurrentPos, 0) self.assertEquals(self.ed.Anchor, 0) self.assertEquals(self.ed.SelectionStart, 0) self.assertEquals(self.ed.SelectionEnd, 0) self.ed.AddText(1, "x") self.ed.SelectionStart = 0 self.assertEquals(self.ed.CurrentPos, 1) self.assertEquals(self.ed.Anchor, 0) self.assertEquals(self.ed.SelectionStart, 0) self.assertEquals(self.ed.SelectionEnd, 1) self.ed.SelectionStart = 1 self.assertEquals(self.ed.CurrentPos, 1) self.assertEquals(self.ed.Anchor, 1) self.assertEquals(self.ed.SelectionStart, 1) self.assertEquals(self.ed.SelectionEnd, 1) self.ed.SelectionEnd = 0 self.assertEquals(self.ed.CurrentPos, 0) self.assertEquals(self.ed.Anchor, 0) def testSetSelection(self): self.ed.AddText(4, b"abcd") self.ed.SetSel(1, 3) self.assertEquals(self.ed.SelectionStart, 1) self.assertEquals(self.ed.SelectionEnd, 3) result = b"\0" * 5 length = self.ed.GetSelText(0, result) self.assertEquals(length, 3) self.assertEquals(result[:length], b"bc\0") self.ed.ReplaceSel(0, b"1234") self.assertEquals(self.ed.Length, 6) self.assertEquals(self.ed.Contents(), b"a1234d") def testReadOnly(self): self.ed.AddText(1, b"x") self.assertEquals(self.ed.ReadOnly, 0) self.assertEquals(self.ed.Contents(), b"x") self.ed.ReadOnly = 1 self.assertEquals(self.ed.ReadOnly, 1) self.ed.AddText(1, b"x") self.assertEquals(self.ed.Contents(), b"x") self.ed.ReadOnly = 0 self.ed.AddText(1, b"x") self.assertEquals(self.ed.Contents(), b"xx") self.ed.Null() self.assertEquals(self.ed.Contents(), b"xx") def testAddLine(self): data = b"x" * 70 + b"\n" for i in range(5): self.ed.AddText(len(data), data) self.xite.DoEvents() self.assertEquals(self.ed.LineCount, i + 2) self.assert_(self.ed.Length > 0) def testInsertText(self): data = b"xy" self.ed.InsertText(0, data) self.assertEquals(self.ed.Length, 2) self.assertEquals(data, self.ed.ByteRange(0,2)) self.ed.InsertText(1, data) # Should now be "xxyy" self.assertEquals(self.ed.Length, 4) self.assertEquals(b"xxyy", self.ed.ByteRange(0,4)) def testInsertNul(self): data = b"\0" self.ed.AddText(1, data) self.assertEquals(self.ed.Length, 1) self.assertEquals(data, self.ed.ByteRange(0,1)) def testUndoRedo(self): data = b"xy" self.assertEquals(self.ed.Modify, 0) self.assertEquals(self.ed.UndoCollection, 1) self.assertEquals(self.ed.CanRedo(), 0) self.assertEquals(self.ed.CanUndo(), 0) self.ed.InsertText(0, data) self.assertEquals(self.ed.Length, 2) self.assertEquals(self.ed.Modify, 1) self.assertEquals(self.ed.CanRedo(), 0) self.assertEquals(self.ed.CanUndo(), 1) self.ed.Undo() self.assertEquals(self.ed.Length, 0) self.assertEquals(self.ed.Modify, 0) self.assertEquals(self.ed.CanRedo(), 1) self.assertEquals(self.ed.CanUndo(), 0) self.ed.Redo() self.assertEquals(self.ed.Length, 2) self.assertEquals(self.ed.Modify, 1) self.assertEquals(data, self.ed.Contents()) self.assertEquals(self.ed.CanRedo(), 0) self.assertEquals(self.ed.CanUndo(), 1) def testUndoSavePoint(self): data = b"xy" self.assertEquals(self.ed.Modify, 0) self.ed.InsertText(0, data) self.assertEquals(self.ed.Modify, 1) self.ed.SetSavePoint() self.assertEquals(self.ed.Modify, 0) self.ed.InsertText(0, data) self.assertEquals(self.ed.Modify, 1) def testUndoCollection(self): data = b"xy" self.assertEquals(self.ed.UndoCollection, 1) self.ed.UndoCollection = 0 self.assertEquals(self.ed.UndoCollection, 0) self.ed.InsertText(0, data) self.assertEquals(self.ed.CanRedo(), 0) self.assertEquals(self.ed.CanUndo(), 0) self.ed.UndoCollection = 1 def testGetColumn(self): self.ed.AddText(1, b"x") self.assertEquals(self.ed.GetColumn(0), 0) self.assertEquals(self.ed.GetColumn(1), 1) # Next line caused infinite loop in 1.71 self.assertEquals(self.ed.GetColumn(2), 1) self.assertEquals(self.ed.GetColumn(3), 1) def testTabWidth(self): self.assertEquals(self.ed.TabWidth, 8) self.ed.AddText(3, b"x\tb") self.assertEquals(self.ed.GetColumn(0), 0) self.assertEquals(self.ed.GetColumn(1), 1) self.assertEquals(self.ed.GetColumn(2), 8) for col in range(10): if col == 0: self.assertEquals(self.ed.FindColumn(0, col), 0) elif col == 1: self.assertEquals(self.ed.FindColumn(0, col), 1) elif col == 8: self.assertEquals(self.ed.FindColumn(0, col), 2) elif col == 9: self.assertEquals(self.ed.FindColumn(0, col), 3) else: self.assertEquals(self.ed.FindColumn(0, col), 1) self.ed.TabWidth = 4 self.assertEquals(self.ed.TabWidth, 4) self.assertEquals(self.ed.GetColumn(0), 0) self.assertEquals(self.ed.GetColumn(1), 1) self.assertEquals(self.ed.GetColumn(2), 4) def testIndent(self): self.assertEquals(self.ed.Indent, 0) self.assertEquals(self.ed.UseTabs, 1) self.ed.Indent = 8 self.ed.UseTabs = 0 self.assertEquals(self.ed.Indent, 8) self.assertEquals(self.ed.UseTabs, 0) self.ed.AddText(3, b"x\tb") self.assertEquals(self.ed.GetLineIndentation(0), 0) self.ed.InsertText(0, b" ") self.assertEquals(self.ed.GetLineIndentation(0), 1) self.assertEquals(self.ed.GetLineIndentPosition(0), 1) self.assertEquals(self.ed.Contents(), b" x\tb") self.ed.SetLineIndentation(0,2) self.assertEquals(self.ed.Contents(), b" x\tb") self.assertEquals(self.ed.GetLineIndentPosition(0), 2) self.ed.UseTabs = 1 self.ed.SetLineIndentation(0,8) self.assertEquals(self.ed.Contents(), b"\tx\tb") self.assertEquals(self.ed.GetLineIndentPosition(0), 1) def testGetCurLine(self): self.ed.AddText(1, b"x") data = b"\0" * 100 caret = self.ed.GetCurLine(len(data), data) data = data.rstrip(b"\0") self.assertEquals(caret, 1) self.assertEquals(data, b"x") def testGetLine(self): self.ed.AddText(1, b"x") data = b"\0" * 100 length = self.ed.GetLine(0, data) self.assertEquals(length, 1) data = data[:length] self.assertEquals(data, b"x") def testLineEnds(self): self.ed.AddText(3, b"x\ny") self.assertEquals(self.ed.GetLineEndPosition(0), 1) self.assertEquals(self.ed.GetLineEndPosition(1), 3) self.assertEquals(self.ed.LineLength(0), 2) self.assertEquals(self.ed.LineLength(1), 1) self.assertEquals(self.ed.EOLMode, self.ed.SC_EOL_CRLF) lineEnds = [b"\r\n", b"\r", b"\n"] for lineEndType in [self.ed.SC_EOL_CR, self.ed.SC_EOL_LF, self.ed.SC_EOL_CRLF]: self.ed.EOLMode = lineEndType self.assertEquals(self.ed.EOLMode, lineEndType) self.ed.ConvertEOLs(lineEndType) self.assertEquals(self.ed.Contents(), b"x" + lineEnds[lineEndType] + b"y") self.assertEquals(self.ed.LineLength(0), 1 + len(lineEnds[lineEndType])) # Several tests for unicode line ends U+2028 and U+2029 def testUnicodeLineEnds(self): # Add two lines separated with U+2028 and ensure it is seen as two lines # Then remove U+2028 and should be just 1 lines self.ed.Lexer = self.ed.SCLEX_CPP self.ed.SetCodePage(65001) self.ed.SetLineEndTypesAllowed(1) self.ed.AddText(5, b"x\xe2\x80\xa8y") self.assertEquals(self.ed.LineCount, 2) self.assertEquals(self.ed.GetLineEndPosition(0), 1) self.assertEquals(self.ed.GetLineEndPosition(1), 5) self.assertEquals(self.ed.LineLength(0), 4) self.assertEquals(self.ed.LineLength(1), 1) self.ed.TargetStart = 1 self.ed.TargetEnd = 4 self.ed.ReplaceTarget(0, b"") self.assertEquals(self.ed.LineCount, 1) self.assertEquals(self.ed.LineLength(0), 2) self.assertEquals(self.ed.GetLineEndPosition(0), 2) def testUnicodeLineEndsWithCodePage0(self): # Try the Unicode line ends when not in Unicode mode -> should remain 1 line self.ed.SetCodePage(0) self.ed.AddText(5, b"x\xe2\x80\xa8y") self.assertEquals(self.ed.LineCount, 1) self.ed.AddText(4, b"x\xc2\x85y") self.assertEquals(self.ed.LineCount, 1) def testUnicodeLineEndsSwitchToUnicodeAndBack(self): # Add the Unicode line ends when not in Unicode mode self.ed.SetCodePage(0) self.ed.AddText(5, b"x\xe2\x80\xa8y") self.assertEquals(self.ed.LineCount, 1) # Into UTF-8 mode - should now be interpreting as two lines self.ed.Lexer = self.ed.SCLEX_CPP self.ed.SetCodePage(65001) self.ed.SetLineEndTypesAllowed(1) self.assertEquals(self.ed.LineCount, 2) # Back to code page 0 and 1 line self.ed.SetCodePage(0) self.assertEquals(self.ed.LineCount, 1) def testUFragmentedEOLCompletion(self): # Add 2 starting bytes of UTF-8 line end then complete it self.ed.ClearAll() self.ed.AddText(4, b"x\xe2\x80y") self.assertEquals(self.ed.LineCount, 1) self.assertEquals(self.ed.GetLineEndPosition(0), 4) self.ed.SetSel(3,3) self.ed.AddText(1, b"\xa8") self.assertEquals(self.ed.Contents(), b"x\xe2\x80\xa8y") self.assertEquals(self.ed.LineCount, 2) # Add 1 starting bytes of UTF-8 line end then complete it self.ed.ClearAll() self.ed.AddText(3, b"x\xe2y") self.assertEquals(self.ed.LineCount, 1) self.assertEquals(self.ed.GetLineEndPosition(0), 3) self.ed.SetSel(2,2) self.ed.AddText(2, b"\x80\xa8") self.assertEquals(self.ed.Contents(), b"x\xe2\x80\xa8y") self.assertEquals(self.ed.LineCount, 2) def testUFragmentedEOLStart(self): # Add end of UTF-8 line end then insert start self.ed.Lexer = self.ed.SCLEX_CPP self.ed.SetCodePage(65001) self.ed.SetLineEndTypesAllowed(1) self.assertEquals(self.ed.LineCount, 1) self.ed.AddText(4, b"x\x80\xa8y") self.assertEquals(self.ed.LineCount, 1) self.ed.SetSel(1,1) self.ed.AddText(1, b"\xe2") self.assertEquals(self.ed.LineCount, 2) def testUBreakApartEOL(self): # Add two lines separated by U+2029 then remove and add back each byte ensuring # only one line after each removal of any byte in line end and 2 lines after reinsertion self.ed.Lexer = self.ed.SCLEX_CPP self.ed.SetCodePage(65001) self.ed.SetLineEndTypesAllowed(1) text = b"x\xe2\x80\xa9y"; self.ed.AddText(5, text) self.assertEquals(self.ed.LineCount, 2) for i in range(len(text)): self.ed.TargetStart = i self.ed.TargetEnd = i + 1 self.ed.ReplaceTarget(0, b"") if i in [0, 4]: # Removing text characters does not change number of lines self.assertEquals(self.ed.LineCount, 2) else: # Removing byte from line end, removes 1 line self.assertEquals(self.ed.LineCount, 1) self.ed.TargetEnd = i self.ed.ReplaceTarget(1, text[i:i+1]) self.assertEquals(self.ed.LineCount, 2) def testURemoveEOLFragment(self): # Add UTF-8 line end then delete each byte causing line end to disappear self.ed.Lexer = self.ed.SCLEX_CPP self.ed.SetCodePage(65001) self.ed.SetLineEndTypesAllowed(1) for i in range(3): self.ed.ClearAll() self.ed.AddText(5, b"x\xe2\x80\xa8y") self.assertEquals(self.ed.LineCount, 2) self.ed.TargetStart = i+1 self.ed.TargetEnd = i+2 self.ed.ReplaceTarget(0, b"") self.assertEquals(self.ed.LineCount, 1) # Several tests for unicode NEL line ends U+0085 def testNELLineEnds(self): # Add two lines separated with U+0085 and ensure it is seen as two lines # Then remove U+0085 and should be just 1 lines self.ed.Lexer = self.ed.SCLEX_CPP self.ed.SetCodePage(65001) self.ed.SetLineEndTypesAllowed(1) self.ed.AddText(4, b"x\xc2\x85y") self.assertEquals(self.ed.LineCount, 2) self.assertEquals(self.ed.GetLineEndPosition(0), 1) self.assertEquals(self.ed.GetLineEndPosition(1), 4) self.assertEquals(self.ed.LineLength(0), 3) self.assertEquals(self.ed.LineLength(1), 1) self.ed.TargetStart = 1 self.ed.TargetEnd = 3 self.ed.ReplaceTarget(0, b"") self.assertEquals(self.ed.LineCount, 1) self.assertEquals(self.ed.LineLength(0), 2) self.assertEquals(self.ed.GetLineEndPosition(0), 2) def testNELFragmentedEOLCompletion(self): # Add starting byte of UTF-8 NEL then complete it self.ed.AddText(3, b"x\xc2y") self.assertEquals(self.ed.LineCount, 1) self.assertEquals(self.ed.GetLineEndPosition(0), 3) self.ed.SetSel(2,2) self.ed.AddText(1, b"\x85") self.assertEquals(self.ed.Contents(), b"x\xc2\x85y") self.assertEquals(self.ed.LineCount, 2) def testNELFragmentedEOLStart(self): # Add end of UTF-8 NEL then insert start self.ed.Lexer = self.ed.SCLEX_CPP self.ed.SetCodePage(65001) self.ed.SetLineEndTypesAllowed(1) self.assertEquals(self.ed.LineCount, 1) self.ed.AddText(4, b"x\x85y") self.assertEquals(self.ed.LineCount, 1) self.ed.SetSel(1,1) self.ed.AddText(1, b"\xc2") self.assertEquals(self.ed.LineCount, 2) def testNELBreakApartEOL(self): # Add two lines separated by U+0085 then remove and add back each byte ensuring # only one line after each removal of any byte in line end and 2 lines after reinsertion self.ed.Lexer = self.ed.SCLEX_CPP self.ed.SetCodePage(65001) self.ed.SetLineEndTypesAllowed(1) text = b"x\xc2\x85y"; self.ed.AddText(4, text) self.assertEquals(self.ed.LineCount, 2) for i in range(len(text)): self.ed.TargetStart = i self.ed.TargetEnd = i + 1 self.ed.ReplaceTarget(0, b"") if i in [0, 3]: # Removing text characters does not change number of lines self.assertEquals(self.ed.LineCount, 2) else: # Removing byte from line end, removes 1 line self.assertEquals(self.ed.LineCount, 1) self.ed.TargetEnd = i self.ed.ReplaceTarget(1, text[i:i+1]) self.assertEquals(self.ed.LineCount, 2) def testNELRemoveEOLFragment(self): # Add UTF-8 NEL then delete each byte causing line end to disappear self.ed.SetCodePage(65001) for i in range(2): self.ed.ClearAll() self.ed.AddText(4, b"x\xc2\x85y") self.assertEquals(self.ed.LineCount, 2) self.ed.TargetStart = i+1 self.ed.TargetEnd = i+2 self.ed.ReplaceTarget(0, b"") self.assertEquals(self.ed.LineCount, 1) def testGoto(self): self.ed.AddText(5, b"a\nb\nc") self.assertEquals(self.ed.CurrentPos, 5) self.ed.GotoLine(1) self.assertEquals(self.ed.CurrentPos, 2) self.ed.GotoPos(4) self.assertEquals(self.ed.CurrentPos, 4) def testCutCopyPaste(self): self.ed.AddText(5, b"a1b2c") self.ed.SetSel(1,3) self.ed.Cut() self.assertEquals(self.ed.CanPaste(), 1) self.ed.SetSel(0, 0) self.ed.Paste() self.assertEquals(self.ed.Contents(), b"1ba2c") self.ed.SetSel(4,5) self.ed.Copy() self.ed.SetSel(1,3) self.ed.Paste() self.assertEquals(self.ed.Contents(), b"1c2c") self.ed.SetSel(2,4) self.ed.Clear() self.assertEquals(self.ed.Contents(), b"1c") def testGetSet(self): self.ed.SetText(0, b"abc") self.assertEquals(self.ed.TextLength, 3) result = b"\0" * 5 length = self.ed.GetText(4, result) result = result[:length] self.assertEquals(result, b"abc") def testAppend(self): self.ed.SetText(0, b"abc") self.assertEquals(self.ed.SelectionStart, 0) self.assertEquals(self.ed.SelectionEnd, 0) text = b"12" self.ed.AppendText(len(text), text) self.assertEquals(self.ed.SelectionStart, 0) self.assertEquals(self.ed.SelectionEnd, 0) self.assertEquals(self.ed.Contents(), b"abc12") def testTarget(self): self.ed.SetText(0, b"abcd") self.ed.TargetStart = 1 self.ed.TargetEnd = 3 self.assertEquals(self.ed.TargetStart, 1) self.assertEquals(self.ed.TargetEnd, 3) rep = b"321" self.ed.ReplaceTarget(len(rep), rep) self.assertEquals(self.ed.Contents(), b"a321d") self.ed.SearchFlags = self.ed.SCFIND_REGEXP self.assertEquals(self.ed.SearchFlags, self.ed.SCFIND_REGEXP) searchString = b"\([1-9]+\)" pos = self.ed.SearchInTarget(len(searchString), searchString) self.assertEquals(1, pos) tagString = b"abcdefghijklmnop" lenTag = self.ed.GetTag(1, tagString) tagString = tagString[:lenTag] self.assertEquals(tagString, b"321") rep = b"\\1" self.ed.TargetStart = 0 self.ed.TargetEnd = 0 self.ed.ReplaceTargetRE(len(rep), rep) self.assertEquals(self.ed.Contents(), b"321a321d") self.ed.SetSel(4,5) self.ed.TargetFromSelection() self.assertEquals(self.ed.TargetStart, 4) self.assertEquals(self.ed.TargetEnd, 5) def testTargetEscape(self): # Checks that a literal \ can be in the replacement. Bug #2959876 self.ed.SetText(0, b"abcd") self.ed.TargetStart = 1 self.ed.TargetEnd = 3 rep = b"\\\\n" self.ed.ReplaceTargetRE(len(rep), rep) self.assertEquals(self.ed.Contents(), b"a\\nd") def testPointsAndPositions(self): self.ed.AddText(1, b"x") # Start of text self.assertEquals(self.ed.PositionFromPoint(0,0), 0) # End of text self.assertEquals(self.ed.PositionFromPoint(0,100), 1) def testLinePositions(self): text = b"ab\ncd\nef" nl = b"\n" if sys.version_info[0] == 3: nl = ord(b"\n") self.ed.AddText(len(text), text) self.assertEquals(self.ed.LineFromPosition(-1), 0) line = 0 for pos in range(len(text)+1): self.assertEquals(self.ed.LineFromPosition(pos), line) if pos < len(text) and text[pos] == nl: line += 1 def testWordPositions(self): text = b"ab cd\tef" self.ed.AddText(len(text), text) self.assertEquals(self.ed.WordStartPosition(3, 0), 2) self.assertEquals(self.ed.WordStartPosition(4, 0), 3) self.assertEquals(self.ed.WordStartPosition(5, 0), 3) self.assertEquals(self.ed.WordStartPosition(6, 0), 5) self.assertEquals(self.ed.WordEndPosition(2, 0), 3) self.assertEquals(self.ed.WordEndPosition(3, 0), 5) self.assertEquals(self.ed.WordEndPosition(4, 0), 5) self.assertEquals(self.ed.WordEndPosition(5, 0), 6) self.assertEquals(self.ed.WordEndPosition(6, 0), 8) MODI = 1 UNDO = 2 REDO = 4 class TestContainerUndo(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() self.data = b"xy" def UndoState(self): return (MODI if self.ed.Modify else 0) | \ (UNDO if self.ed.CanUndo() else 0) | \ (REDO if self.ed.CanRedo() else 0) def testContainerActNoCoalesce(self): self.ed.InsertText(0, self.data) self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), MODI | UNDO) self.ed.AddUndoAction(5, 0) self.ed.Undo() self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), MODI | UNDO | REDO) self.ed.Redo() self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), MODI | UNDO) self.ed.Undo() def testContainerActCoalesce(self): self.ed.InsertText(0, self.data) self.ed.AddUndoAction(5, 1) self.ed.Undo() self.assertEquals(self.ed.Length, 0) self.assertEquals(self.UndoState(), REDO) self.ed.Redo() self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), MODI | UNDO) def testContainerMultiStage(self): self.ed.InsertText(0, self.data) self.ed.AddUndoAction(5, 1) self.ed.AddUndoAction(5, 1) self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), MODI | UNDO) self.ed.Undo() self.assertEquals(self.ed.Length, 0) self.assertEquals(self.UndoState(), REDO) self.ed.Redo() self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), MODI | UNDO) self.ed.AddUndoAction(5, 1) self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), MODI | UNDO) self.ed.Undo() self.assertEquals(self.ed.Length, 0) self.assertEquals(self.UndoState(), REDO) def testContainerMultiStageNoText(self): self.ed.AddUndoAction(5, 1) self.ed.AddUndoAction(5, 1) self.assertEquals(self.UndoState(), MODI | UNDO) self.ed.Undo() self.assertEquals(self.UndoState(), REDO) self.ed.Redo() self.assertEquals(self.UndoState(), MODI | UNDO) self.ed.AddUndoAction(5, 1) self.assertEquals(self.UndoState(), MODI | UNDO) self.ed.Undo() self.assertEquals(self.UndoState(), REDO) def testContainerActCoalesceEnd(self): self.ed.AddUndoAction(5, 1) self.assertEquals(self.ed.Length, 0) self.assertEquals(self.UndoState(), MODI | UNDO) self.ed.InsertText(0, self.data) self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), MODI | UNDO) self.ed.Undo() self.assertEquals(self.ed.Length, 0) self.assertEquals(self.UndoState(), REDO) self.ed.Redo() self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), MODI | UNDO) def testContainerBetweenInsertAndInsert(self): self.assertEquals(self.ed.Length, 0) self.ed.InsertText(0, self.data) self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), MODI | UNDO) self.ed.AddUndoAction(5, 1) self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), MODI | UNDO) self.ed.InsertText(2, self.data) self.assertEquals(self.ed.Length, 4) self.assertEquals(self.UndoState(), MODI | UNDO) # Undoes both insertions and the containerAction in the middle self.ed.Undo() self.assertEquals(self.ed.Length, 0) self.assertEquals(self.UndoState(), REDO) def testContainerNoCoalesceBetweenInsertAndInsert(self): self.assertEquals(self.ed.Length, 0) self.ed.InsertText(0, self.data) self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), MODI | UNDO) self.ed.AddUndoAction(5, 0) self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), MODI | UNDO) self.ed.InsertText(2, self.data) self.assertEquals(self.ed.Length, 4) self.assertEquals(self.UndoState(), MODI | UNDO) # Undo last insertion self.ed.Undo() self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), MODI | UNDO | REDO) # Undo container self.ed.Undo() self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), MODI | UNDO | REDO) # Undo first insertion self.ed.Undo() self.assertEquals(self.ed.Length, 0) self.assertEquals(self.UndoState(), REDO) def testContainerBetweenDeleteAndDelete(self): self.ed.InsertText(0, self.data) self.ed.EmptyUndoBuffer() self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), 0) self.ed.SetSel(2,2) self.ed.DeleteBack() self.assertEquals(self.ed.Length, 1) self.ed.AddUndoAction(5, 1) self.ed.DeleteBack() self.assertEquals(self.ed.Length, 0) # Undoes both deletions and the containerAction in the middle self.ed.Undo() self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), REDO) def testContainerBetweenInsertAndDelete(self): self.assertEquals(self.ed.Length, 0) self.ed.InsertText(0, self.data) self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), MODI | UNDO) self.ed.AddUndoAction(5, 1) self.assertEquals(self.UndoState(), MODI | UNDO) self.ed.SetSel(0,1) self.ed.Cut() self.assertEquals(self.ed.Length, 1) self.assertEquals(self.UndoState(), MODI | UNDO) self.ed.Undo() # Only undoes the deletion self.assertEquals(self.ed.Length, 2) self.assertEquals(self.UndoState(), MODI | UNDO | REDO) class TestKeyCommands(unittest.TestCase): """ These commands are normally assigned to keys and take no arguments """ def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() def selRange(self): return self.ed.CurrentPos, self.ed.Anchor def testLineMove(self): self.ed.AddText(8, b"x1\ny2\nz3") self.ed.SetSel(0,0) self.ed.ChooseCaretX() self.ed.LineDown() self.ed.LineDown() self.assertEquals(self.selRange(), (6, 6)) self.ed.LineUp() self.assertEquals(self.selRange(), (3, 3)) self.ed.LineDownExtend() self.assertEquals(self.selRange(), (6, 3)) self.ed.LineUpExtend() self.ed.LineUpExtend() self.assertEquals(self.selRange(), (0, 3)) def testCharMove(self): self.ed.AddText(8, b"x1\ny2\nz3") self.ed.SetSel(0,0) self.ed.CharRight() self.ed.CharRight() self.assertEquals(self.selRange(), (2, 2)) self.ed.CharLeft() self.assertEquals(self.selRange(), (1, 1)) self.ed.CharRightExtend() self.assertEquals(self.selRange(), (2, 1)) self.ed.CharLeftExtend() self.ed.CharLeftExtend() self.assertEquals(self.selRange(), (0, 1)) def testWordMove(self): self.ed.AddText(10, b"a big boat") self.ed.SetSel(3,3) self.ed.WordRight() self.ed.WordRight() self.assertEquals(self.selRange(), (10, 10)) self.ed.WordLeft() self.assertEquals(self.selRange(), (6, 6)) self.ed.WordRightExtend() self.assertEquals(self.selRange(), (10, 6)) self.ed.WordLeftExtend() self.ed.WordLeftExtend() self.assertEquals(self.selRange(), (2, 6)) def testHomeEndMove(self): self.ed.AddText(10, b"a big boat") self.ed.SetSel(3,3) self.ed.Home() self.assertEquals(self.selRange(), (0, 0)) self.ed.LineEnd() self.assertEquals(self.selRange(), (10, 10)) self.ed.SetSel(3,3) self.ed.HomeExtend() self.assertEquals(self.selRange(), (0, 3)) self.ed.LineEndExtend() self.assertEquals(self.selRange(), (10, 3)) def testStartEndMove(self): self.ed.AddText(10, b"a\nbig\nboat") self.ed.SetSel(3,3) self.ed.DocumentStart() self.assertEquals(self.selRange(), (0, 0)) self.ed.DocumentEnd() self.assertEquals(self.selRange(), (10, 10)) self.ed.SetSel(3,3) self.ed.DocumentStartExtend() self.assertEquals(self.selRange(), (0, 3)) self.ed.DocumentEndExtend() self.assertEquals(self.selRange(), (10, 3)) class TestMarkers(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() self.ed.AddText(5, b"x\ny\nz") def testMarker(self): handle = self.ed.MarkerAdd(1,1) self.assertEquals(self.ed.MarkerLineFromHandle(handle), 1) self.ed.MarkerDelete(1,1) self.assertEquals(self.ed.MarkerLineFromHandle(handle), -1) def testTwiceAddedDelete(self): handle = self.ed.MarkerAdd(1,1) self.assertEquals(self.ed.MarkerGet(1), 2) handle2 = self.ed.MarkerAdd(1,1) self.assertEquals(self.ed.MarkerGet(1), 2) self.ed.MarkerDelete(1,1) self.assertEquals(self.ed.MarkerGet(1), 2) self.ed.MarkerDelete(1,1) self.assertEquals(self.ed.MarkerGet(1), 0) def testMarkerDeleteAll(self): h1 = self.ed.MarkerAdd(0,1) h2 = self.ed.MarkerAdd(1,2) self.assertEquals(self.ed.MarkerLineFromHandle(h1), 0) self.assertEquals(self.ed.MarkerLineFromHandle(h2), 1) self.ed.MarkerDeleteAll(1) self.assertEquals(self.ed.MarkerLineFromHandle(h1), -1) self.assertEquals(self.ed.MarkerLineFromHandle(h2), 1) self.ed.MarkerDeleteAll(-1) self.assertEquals(self.ed.MarkerLineFromHandle(h1), -1) self.assertEquals(self.ed.MarkerLineFromHandle(h2), -1) def testMarkerDeleteHandle(self): handle = self.ed.MarkerAdd(0,1) self.assertEquals(self.ed.MarkerLineFromHandle(handle), 0) self.ed.MarkerDeleteHandle(handle) self.assertEquals(self.ed.MarkerLineFromHandle(handle), -1) def testMarkerBits(self): self.assertEquals(self.ed.MarkerGet(0), 0) self.ed.MarkerAdd(0,1) self.assertEquals(self.ed.MarkerGet(0), 2) self.ed.MarkerAdd(0,2) self.assertEquals(self.ed.MarkerGet(0), 6) def testMarkerAddSet(self): self.assertEquals(self.ed.MarkerGet(0), 0) self.ed.MarkerAddSet(0,5) self.assertEquals(self.ed.MarkerGet(0), 5) self.ed.MarkerDeleteAll(-1) def testMarkerNext(self): self.assertEquals(self.ed.MarkerNext(0, 2), -1) h1 = self.ed.MarkerAdd(0,1) h2 = self.ed.MarkerAdd(2,1) self.assertEquals(self.ed.MarkerNext(0, 2), 0) self.assertEquals(self.ed.MarkerNext(1, 2), 2) self.assertEquals(self.ed.MarkerNext(2, 2), 2) self.assertEquals(self.ed.MarkerPrevious(0, 2), 0) self.assertEquals(self.ed.MarkerPrevious(1, 2), 0) self.assertEquals(self.ed.MarkerPrevious(2, 2), 2) def testMarkerNegative(self): self.assertEquals(self.ed.MarkerNext(-1, 2), -1) def testLineState(self): self.assertEquals(self.ed.MaxLineState, 0) self.assertEquals(self.ed.GetLineState(0), 0) self.assertEquals(self.ed.GetLineState(1), 0) self.assertEquals(self.ed.GetLineState(2), 0) self.ed.SetLineState(1, 100) self.assertNotEquals(self.ed.MaxLineState, 0) self.assertEquals(self.ed.GetLineState(0), 0) self.assertEquals(self.ed.GetLineState(1), 100) self.assertEquals(self.ed.GetLineState(2), 0) def testSymbolRetrieval(self): self.ed.MarkerDefine(1,3) self.assertEquals(self.ed.MarkerSymbolDefined(1), 3) class TestIndicators(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() def testSetIndicator(self): self.assertEquals(self.ed.IndicGetStyle(0), 1) self.assertEquals(self.ed.IndicGetFore(0), 0x007f00) self.ed.IndicSetStyle(0, 2) self.ed.IndicSetFore(0, 0xff0080) self.assertEquals(self.ed.IndicGetStyle(0), 2) self.assertEquals(self.ed.IndicGetFore(0), 0xff0080) def testIndicatorFill(self): self.ed.InsertText(0, b"abc") self.ed.IndicatorCurrent = 3 self.ed.IndicatorFillRange(1,1) self.assertEquals(self.ed.IndicatorValueAt(3, 0), 0) self.assertEquals(self.ed.IndicatorValueAt(3, 1), 1) self.assertEquals(self.ed.IndicatorValueAt(3, 2), 0) self.assertEquals(self.ed.IndicatorStart(3, 0), 0) self.assertEquals(self.ed.IndicatorEnd(3, 0), 1) self.assertEquals(self.ed.IndicatorStart(3, 1), 1) self.assertEquals(self.ed.IndicatorEnd(3, 1), 2) self.assertEquals(self.ed.IndicatorStart(3, 2), 2) self.assertEquals(self.ed.IndicatorEnd(3, 2), 3) def testIndicatorAtEnd(self): self.ed.InsertText(0, b"ab") self.ed.IndicatorCurrent = 3 self.ed.IndicatorFillRange(1,1) self.assertEquals(self.ed.IndicatorValueAt(3, 0), 0) self.assertEquals(self.ed.IndicatorValueAt(3, 1), 1) self.assertEquals(self.ed.IndicatorStart(3, 0), 0) self.assertEquals(self.ed.IndicatorEnd(3, 0), 1) self.assertEquals(self.ed.IndicatorStart(3, 1), 1) self.assertEquals(self.ed.IndicatorEnd(3, 1), 2) self.ed.DeleteRange(1, 1) # Now only one character left and does not have indicator so indicator 3 is null self.assertEquals(self.ed.IndicatorValueAt(3, 0), 0) # Since null, remaining calls return 0 self.assertEquals(self.ed.IndicatorStart(3, 0), 0) self.assertEquals(self.ed.IndicatorEnd(3, 0), 0) self.assertEquals(self.ed.IndicatorStart(3, 1), 0) self.assertEquals(self.ed.IndicatorEnd(3, 1), 0) class TestScrolling(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() # 150 should be enough lines self.ed.InsertText(0, b"a" * 150 + b"\n" * 150) def testTop(self): self.ed.GotoLine(0) self.assertEquals(self.ed.FirstVisibleLine, 0) def testLineScroll(self): self.ed.GotoLine(0) self.ed.LineScroll(0, 3) self.assertEquals(self.ed.FirstVisibleLine, 3) self.ed.LineScroll(0, -2) self.assertEquals(self.ed.FirstVisibleLine, 1) self.assertEquals(self.ed.XOffset, 0) self.ed.LineScroll(10, 0) self.assertGreater(self.ed.XOffset, 0) scroll_width = float(self.ed.XOffset) / 10 self.ed.LineScroll(-2, 0) self.assertEquals(self.ed.XOffset, scroll_width * 8) def testVisibleLine(self): self.ed.FirstVisibleLine = 7 self.assertEquals(self.ed.FirstVisibleLine, 7) class TestSearch(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() self.ed.InsertText(0, b"a\tbig boat\t") def testFind(self): pos = self.ed.FindBytes(0, self.ed.Length, b"zzz", 0) self.assertEquals(pos, -1) pos = self.ed.FindBytes(0, self.ed.Length, b"big", 0) self.assertEquals(pos, 2) def testFindEmpty(self): pos = self.ed.FindBytes(0, self.ed.Length, b"", 0) self.assertEquals(pos, 0) def testCaseFind(self): self.assertEquals(self.ed.FindBytes(0, self.ed.Length, b"big", 0), 2) self.assertEquals(self.ed.FindBytes(0, self.ed.Length, b"bIg", 0), 2) self.assertEquals(self.ed.FindBytes(0, self.ed.Length, b"bIg", self.ed.SCFIND_MATCHCASE), -1) def testWordFind(self): self.assertEquals(self.ed.FindBytes(0, self.ed.Length, b"bi", 0), 2) self.assertEquals(self.ed.FindBytes(0, self.ed.Length, b"bi", self.ed.SCFIND_WHOLEWORD), -1) def testWordStartFind(self): self.assertEquals(self.ed.FindBytes(0, self.ed.Length, b"bi", 0), 2) self.assertEquals(self.ed.FindBytes(0, self.ed.Length, b"bi", self.ed.SCFIND_WORDSTART), 2) self.assertEquals(self.ed.FindBytes(0, self.ed.Length, b"ig", 0), 3) self.assertEquals(self.ed.FindBytes(0, self.ed.Length, b"ig", self.ed.SCFIND_WORDSTART), -1) def testREFind(self): flags = self.ed.SCFIND_REGEXP self.assertEquals(-1, self.ed.FindBytes(0, self.ed.Length, b"b.g", 0)) self.assertEquals(2, self.ed.FindBytes(0, self.ed.Length, b"b.g", flags)) self.assertEquals(2, self.ed.FindBytes(0, self.ed.Length, b"\<b.g\>", flags)) self.assertEquals(-1, self.ed.FindBytes(0, self.ed.Length, b"b[A-Z]g", flags | self.ed.SCFIND_MATCHCASE)) self.assertEquals(2, self.ed.FindBytes(0, self.ed.Length, b"b[a-z]g", flags)) self.assertEquals(6, self.ed.FindBytes(0, self.ed.Length, b"b[a-z]*t", flags)) self.assertEquals(0, self.ed.FindBytes(0, self.ed.Length, b"^a", flags)) self.assertEquals(10, self.ed.FindBytes(0, self.ed.Length, b"\t$", flags)) self.assertEquals(0, self.ed.FindBytes(0, self.ed.Length, b"\([a]\).*\0", flags)) def testPosixREFind(self): flags = self.ed.SCFIND_REGEXP | self.ed.SCFIND_POSIX self.assertEquals(-1, self.ed.FindBytes(0, self.ed.Length, b"b.g", 0)) self.assertEquals(2, self.ed.FindBytes(0, self.ed.Length, b"b.g", flags)) self.assertEquals(2, self.ed.FindBytes(0, self.ed.Length, b"\<b.g\>", flags)) self.assertEquals(-1, self.ed.FindBytes(0, self.ed.Length, b"b[A-Z]g", flags | self.ed.SCFIND_MATCHCASE)) self.assertEquals(2, self.ed.FindBytes(0, self.ed.Length, b"b[a-z]g", flags)) self.assertEquals(6, self.ed.FindBytes(0, self.ed.Length, b"b[a-z]*t", flags)) self.assertEquals(0, self.ed.FindBytes(0, self.ed.Length, b"^a", flags)) self.assertEquals(10, self.ed.FindBytes(0, self.ed.Length, b"\t$", flags)) self.assertEquals(0, self.ed.FindBytes(0, self.ed.Length, b"([a]).*\0", flags)) def testPhilippeREFind(self): # Requires 1.,72 flags = self.ed.SCFIND_REGEXP self.assertEquals(0, self.ed.FindBytes(0, self.ed.Length, b"\w", flags)) self.assertEquals(1, self.ed.FindBytes(0, self.ed.Length, b"\W", flags)) self.assertEquals(-1, self.ed.FindBytes(0, self.ed.Length, b"\d", flags)) self.assertEquals(0, self.ed.FindBytes(0, self.ed.Length, b"\D", flags)) self.assertEquals(1, self.ed.FindBytes(0, self.ed.Length, b"\s", flags)) self.assertEquals(0, self.ed.FindBytes(0, self.ed.Length, b"\S", flags)) self.assertEquals(2, self.ed.FindBytes(0, self.ed.Length, b"\x62", flags)) def testRENonASCII(self): self.ed.InsertText(0, b"\xAD") flags = self.ed.SCFIND_REGEXP self.assertEquals(-1, self.ed.FindBytes(0, self.ed.Length, b"\\x10", flags)) self.assertEquals(2, self.ed.FindBytes(0, self.ed.Length, b"\\x09", flags)) self.assertEquals(-1, self.ed.FindBytes(0, self.ed.Length, b"\\xAB", flags)) self.assertEquals(0, self.ed.FindBytes(0, self.ed.Length, b"\\xAD", flags)) class TestProperties(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() def testSet(self): self.ed.SetProperty(b"test", b"12") self.assertEquals(self.ed.GetPropertyInt(b"test"), 12) result = b"\0" * 10 length = self.ed.GetProperty(b"test", result) result = result[:length] self.assertEquals(result, b"12") self.ed.SetProperty(b"test.plus", b"[$(test)]") result = b"\0" * 10 length = self.ed.GetPropertyExpanded(b"test.plus", result) result = result[:length] self.assertEquals(result, b"[12]") class TestTextMargin(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() self.txt = b"abcd" self.ed.AddText(1, b"x") def testAscent(self): lineHeight = self.ed.TextHeight(0) self.ed.ExtraAscent self.assertEquals(self.ed.ExtraAscent, 0) self.assertEquals(self.ed.ExtraDescent, 0) self.ed.ExtraAscent = 1 self.assertEquals(self.ed.ExtraAscent, 1) self.ed.ExtraDescent = 2 self.assertEquals(self.ed.ExtraDescent, 2) # Allow line height to recalculate self.xite.DoEvents() lineHeightIncreased = self.ed.TextHeight(0) self.assertEquals(lineHeightIncreased, lineHeight + 2 + 1) def testTextMargin(self): self.ed.MarginSetText(0, self.txt) result = b"\0" * 10 length = self.ed.MarginGetText(0, result) result = result[:length] self.assertEquals(result, self.txt) self.ed.MarginTextClearAll() def testTextMarginStyle(self): self.ed.MarginSetText(0, self.txt) self.ed.MarginSetStyle(0, 33) self.assertEquals(self.ed.MarginGetStyle(0), 33) self.ed.MarginTextClearAll() def testTextMarginStyles(self): styles = b"\001\002\003\004" self.ed.MarginSetText(0, self.txt) self.ed.MarginSetStyles(0, styles) result = b"\0" * 10 length = self.ed.MarginGetStyles(0, result) result = result[:length] self.assertEquals(result, styles) self.ed.MarginTextClearAll() def testTextMarginStyleOffset(self): self.ed.MarginSetStyleOffset(300) self.assertEquals(self.ed.MarginGetStyleOffset(), 300) class TestAnnotation(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() self.txt = b"abcd" self.ed.AddText(1, b"x") def testTextAnnotation(self): self.assertEquals(self.ed.AnnotationGetLines(), 0) self.ed.AnnotationSetText(0, self.txt) self.assertEquals(self.ed.AnnotationGetLines(), 1) result = b"\0" * 10 length = self.ed.AnnotationGetText(0, result) self.assertEquals(length, 4) result = result[:length] self.assertEquals(result, self.txt) self.ed.AnnotationClearAll() def testTextAnnotationStyle(self): self.ed.AnnotationSetText(0, self.txt) self.ed.AnnotationSetStyle(0, 33) self.assertEquals(self.ed.AnnotationGetStyle(0), 33) self.ed.AnnotationClearAll() def testTextAnnotationStyles(self): styles = b"\001\002\003\004" self.ed.AnnotationSetText(0, self.txt) self.ed.AnnotationSetStyles(0, styles) result = b"\0" * 10 length = self.ed.AnnotationGetStyles(0, result) result = result[:length] self.assertEquals(result, styles) self.ed.AnnotationClearAll() def testExtendedStyles(self): start0 = self.ed.AllocateExtendedStyles(0) self.assertEquals(start0, 256) start1 = self.ed.AllocateExtendedStyles(10) self.assertEquals(start1, 256) start2 = self.ed.AllocateExtendedStyles(20) self.assertEquals(start2, start1 + 10) # Reset by changing lexer self.ed.ReleaseAllExtendedStyles() start0 = self.ed.AllocateExtendedStyles(0) self.assertEquals(start0, 256) def testTextAnnotationStyleOffset(self): self.ed.AnnotationSetStyleOffset(300) self.assertEquals(self.ed.AnnotationGetStyleOffset(), 300) def testTextAnnotationVisible(self): self.assertEquals(self.ed.AnnotationGetVisible(), 0) self.ed.AnnotationSetVisible(2) self.assertEquals(self.ed.AnnotationGetVisible(), 2) self.ed.AnnotationSetVisible(0) class TestMultiSelection(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() # 3 lines of 3 characters t = b"xxx\nxxx\nxxx" self.ed.AddText(len(t), t) def testSelectionCleared(self): self.ed.ClearSelections() self.assertEquals(self.ed.Selections, 1) self.assertEquals(self.ed.MainSelection, 0) self.assertEquals(self.ed.GetSelectionNCaret(0), 0) self.assertEquals(self.ed.GetSelectionNAnchor(0), 0) def test1Selection(self): self.ed.SetSelection(1, 2) self.assertEquals(self.ed.Selections, 1) self.assertEquals(self.ed.MainSelection, 0) self.assertEquals(self.ed.GetSelectionNCaret(0), 1) self.assertEquals(self.ed.GetSelectionNAnchor(0), 2) self.assertEquals(self.ed.GetSelectionNStart(0), 1) self.assertEquals(self.ed.GetSelectionNEnd(0), 2) self.ed.SwapMainAnchorCaret() self.assertEquals(self.ed.Selections, 1) self.assertEquals(self.ed.MainSelection, 0) self.assertEquals(self.ed.GetSelectionNCaret(0), 2) self.assertEquals(self.ed.GetSelectionNAnchor(0), 1) def test1SelectionReversed(self): self.ed.SetSelection(2, 1) self.assertEquals(self.ed.Selections, 1) self.assertEquals(self.ed.MainSelection, 0) self.assertEquals(self.ed.GetSelectionNCaret(0), 2) self.assertEquals(self.ed.GetSelectionNAnchor(0), 1) self.assertEquals(self.ed.GetSelectionNStart(0), 1) self.assertEquals(self.ed.GetSelectionNEnd(0), 2) def test1SelectionByStartEnd(self): self.ed.SetSelectionNStart(0, 2) self.ed.SetSelectionNEnd(0, 3) self.assertEquals(self.ed.Selections, 1) self.assertEquals(self.ed.MainSelection, 0) self.assertEquals(self.ed.GetSelectionNAnchor(0), 2) self.assertEquals(self.ed.GetSelectionNCaret(0), 3) self.assertEquals(self.ed.GetSelectionNStart(0), 2) self.assertEquals(self.ed.GetSelectionNEnd(0), 3) def test2Selections(self): self.ed.SetSelection(1, 2) self.ed.AddSelection(4, 5) self.assertEquals(self.ed.Selections, 2) self.assertEquals(self.ed.MainSelection, 1) self.assertEquals(self.ed.GetSelectionNCaret(0), 1) self.assertEquals(self.ed.GetSelectionNAnchor(0), 2) self.assertEquals(self.ed.GetSelectionNCaret(1), 4) self.assertEquals(self.ed.GetSelectionNAnchor(1), 5) self.assertEquals(self.ed.GetSelectionNStart(0), 1) self.assertEquals(self.ed.GetSelectionNEnd(0), 2) self.ed.MainSelection = 0 self.assertEquals(self.ed.MainSelection, 0) self.ed.RotateSelection() self.assertEquals(self.ed.MainSelection, 1) def testRectangularSelection(self): self.ed.RectangularSelectionAnchor = 1 self.assertEquals(self.ed.RectangularSelectionAnchor, 1) self.ed.RectangularSelectionCaret = 10 self.assertEquals(self.ed.RectangularSelectionCaret, 10) self.assertEquals(self.ed.Selections, 3) self.assertEquals(self.ed.MainSelection, 2) self.assertEquals(self.ed.GetSelectionNAnchor(0), 1) self.assertEquals(self.ed.GetSelectionNCaret(0), 2) self.assertEquals(self.ed.GetSelectionNAnchor(1), 5) self.assertEquals(self.ed.GetSelectionNCaret(1), 6) self.assertEquals(self.ed.GetSelectionNAnchor(2), 9) self.assertEquals(self.ed.GetSelectionNCaret(2), 10) def testVirtualSpace(self): self.ed.SetSelection(3, 7) self.ed.SetSelectionNCaretVirtualSpace(0, 3) self.assertEquals(self.ed.GetSelectionNCaretVirtualSpace(0), 3) self.ed.SetSelectionNAnchorVirtualSpace(0, 2) self.assertEquals(self.ed.GetSelectionNAnchorVirtualSpace(0), 2) # Does not check that virtual space is valid by being at end of line self.ed.SetSelection(1, 1) self.ed.SetSelectionNCaretVirtualSpace(0, 3) self.assertEquals(self.ed.GetSelectionNCaretVirtualSpace(0), 3) def testRectangularVirtualSpace(self): self.ed.VirtualSpaceOptions=1 self.ed.RectangularSelectionAnchor = 3 self.assertEquals(self.ed.RectangularSelectionAnchor, 3) self.ed.RectangularSelectionCaret = 7 self.assertEquals(self.ed.RectangularSelectionCaret, 7) self.ed.RectangularSelectionAnchorVirtualSpace = 1 self.assertEquals(self.ed.RectangularSelectionAnchorVirtualSpace, 1) self.ed.RectangularSelectionCaretVirtualSpace = 10 self.assertEquals(self.ed.RectangularSelectionCaretVirtualSpace, 10) self.assertEquals(self.ed.Selections, 2) self.assertEquals(self.ed.MainSelection, 1) self.assertEquals(self.ed.GetSelectionNAnchor(0), 3) self.assertEquals(self.ed.GetSelectionNAnchorVirtualSpace(0), 1) self.assertEquals(self.ed.GetSelectionNCaret(0), 3) self.assertEquals(self.ed.GetSelectionNCaretVirtualSpace(0), 10) def testRectangularVirtualSpaceOptionOff(self): # Same as previous test but virtual space option off so no virtual space in result self.ed.VirtualSpaceOptions=0 self.ed.RectangularSelectionAnchor = 3 self.assertEquals(self.ed.RectangularSelectionAnchor, 3) self.ed.RectangularSelectionCaret = 7 self.assertEquals(self.ed.RectangularSelectionCaret, 7) self.ed.RectangularSelectionAnchorVirtualSpace = 1 self.assertEquals(self.ed.RectangularSelectionAnchorVirtualSpace, 1) self.ed.RectangularSelectionCaretVirtualSpace = 10 self.assertEquals(self.ed.RectangularSelectionCaretVirtualSpace, 10) self.assertEquals(self.ed.Selections, 2) self.assertEquals(self.ed.MainSelection, 1) self.assertEquals(self.ed.GetSelectionNAnchor(0), 3) self.assertEquals(self.ed.GetSelectionNAnchorVirtualSpace(0), 0) self.assertEquals(self.ed.GetSelectionNCaret(0), 3) self.assertEquals(self.ed.GetSelectionNCaretVirtualSpace(0), 0) class TestCaseMapping(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() def tearDown(self): self.ed.SetCodePage(0) self.ed.StyleSetCharacterSet(self.ed.STYLE_DEFAULT, self.ed.SC_CHARSET_DEFAULT) def testEmpty(self): # Trying to upper case an empty string caused a crash at one stage t = b"x" self.ed.SetText(len(t), t) self.ed.UpperCase() self.assertEquals(self.ed.Contents(), b"x") def testASCII(self): t = b"x" self.ed.SetText(len(t), t) self.ed.SetSel(0,1) self.ed.UpperCase() self.assertEquals(self.ed.Contents(), b"X") def testLatin1(self): t = "å".encode("Latin-1") r = "Å".encode("Latin-1") self.ed.SetText(len(t), t) self.ed.SetSel(0,1) self.ed.UpperCase() self.assertEquals(self.ed.Contents(), r) def testRussian(self): self.ed.StyleSetCharacterSet(self.ed.STYLE_DEFAULT, self.ed.SC_CHARSET_RUSSIAN) t = "Б".encode("Windows-1251") r = "б".encode("Windows-1251") self.ed.SetText(len(t), t) self.ed.SetSel(0,1) self.ed.LowerCase() self.assertEquals(self.ed.Contents(), r) def testUTF(self): self.ed.SetCodePage(65001) t = "å".encode("UTF-8") r = "Å".encode("UTF-8") self.ed.SetText(len(t), t) self.ed.SetSel(0,2) self.ed.UpperCase() self.assertEquals(self.ed.Contents(), r) def testUTFDifferentLength(self): self.ed.SetCodePage(65001) t = "ı".encode("UTF-8") r = "I".encode("UTF-8") self.ed.SetText(len(t), t) self.assertEquals(self.ed.Length, 2) self.ed.SetSel(0,2) self.ed.UpperCase() self.assertEquals(self.ed.Length, 1) self.assertEquals(self.ed.Contents(), r) class TestCaseInsensitiveSearch(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() def tearDown(self): self.ed.SetCodePage(0) self.ed.StyleSetCharacterSet(self.ed.STYLE_DEFAULT, self.ed.SC_CHARSET_DEFAULT) def testEmpty(self): text = b" x X" searchString = b"" self.ed.SetText(len(text), text) self.ed.TargetStart = 0 self.ed.TargetEnd = self.ed.Length-1 self.ed.SearchFlags = 0 pos = self.ed.SearchInTarget(len(searchString), searchString) self.assertEquals(0, pos) def testASCII(self): text = b" x X" searchString = b"X" self.ed.SetText(len(text), text) self.ed.TargetStart = 0 self.ed.TargetEnd = self.ed.Length-1 self.ed.SearchFlags = 0 pos = self.ed.SearchInTarget(len(searchString), searchString) self.assertEquals(1, pos) def testLatin1(self): text = "Frånd Åå".encode("Latin-1") searchString = "Å".encode("Latin-1") self.ed.SetText(len(text), text) self.ed.TargetStart = 0 self.ed.TargetEnd = self.ed.Length-1 self.ed.SearchFlags = 0 pos = self.ed.SearchInTarget(len(searchString), searchString) self.assertEquals(2, pos) def testRussian(self): self.ed.StyleSetCharacterSet(self.ed.STYLE_DEFAULT, self.ed.SC_CHARSET_RUSSIAN) text = "=(Б tex б)".encode("Windows-1251") searchString = "б".encode("Windows-1251") self.ed.SetText(len(text), text) self.ed.TargetStart = 0 self.ed.TargetEnd = self.ed.Length-1 self.ed.SearchFlags = 0 pos = self.ed.SearchInTarget(len(searchString), searchString) self.assertEquals(2, pos) def testUTF(self): self.ed.SetCodePage(65001) text = "Frånd Åå".encode("UTF-8") searchString = "Å".encode("UTF-8") self.ed.SetText(len(text), text) self.ed.TargetStart = 0 self.ed.TargetEnd = self.ed.Length-1 self.ed.SearchFlags = 0 pos = self.ed.SearchInTarget(len(searchString), searchString) self.assertEquals(2, pos) def testUTFDifferentLength(self): # Searching for a two byte string "ı" finds a single byte "I" self.ed.SetCodePage(65001) text = "Fråndi Ååİ $".encode("UTF-8") firstPosition = len("Frånd".encode("UTF-8")) searchString = "İ".encode("UTF-8") self.assertEquals(len(searchString), 2) self.ed.SetText(len(text), text) self.ed.TargetStart = 0 self.ed.TargetEnd = self.ed.Length-1 self.ed.SearchFlags = 0 pos = self.ed.SearchInTarget(len(searchString), searchString) self.assertEquals(firstPosition, pos) self.assertEquals(firstPosition+1, self.ed.TargetEnd) class TestLexer(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() def testLexerNumber(self): self.ed.Lexer = self.ed.SCLEX_CPP self.assertEquals(self.ed.GetLexer(), self.ed.SCLEX_CPP) def testLexerName(self): self.ed.LexerLanguage = b"cpp" self.assertEquals(self.ed.GetLexer(), self.ed.SCLEX_CPP) name = b"-" * 100 length = self.ed.GetLexerLanguage(0, name) name = name[:length] self.assertEquals(name, b"cpp") class TestAutoComplete(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() # 1 line of 3 characters t = b"xxx\n" self.ed.AddText(len(t), t) def testDefaults(self): self.assertEquals(self.ed.AutoCGetSeparator(), ord(' ')) self.assertEquals(self.ed.AutoCGetMaxHeight(), 5) self.assertEquals(self.ed.AutoCGetMaxWidth(), 0) self.assertEquals(self.ed.AutoCGetTypeSeparator(), ord('?')) self.assertEquals(self.ed.AutoCGetIgnoreCase(), 0) self.assertEquals(self.ed.AutoCGetAutoHide(), 1) self.assertEquals(self.ed.AutoCGetDropRestOfWord(), 0) def testChangeDefaults(self): self.ed.AutoCSetSeparator(ord('-')) self.assertEquals(self.ed.AutoCGetSeparator(), ord('-')) self.ed.AutoCSetSeparator(ord(' ')) self.ed.AutoCSetMaxHeight(100) self.assertEquals(self.ed.AutoCGetMaxHeight(), 100) self.ed.AutoCSetMaxHeight(5) self.ed.AutoCSetMaxWidth(100) self.assertEquals(self.ed.AutoCGetMaxWidth(), 100) self.ed.AutoCSetMaxWidth(0) self.ed.AutoCSetTypeSeparator(ord('@')) self.assertEquals(self.ed.AutoCGetTypeSeparator(), ord('@')) self.ed.AutoCSetTypeSeparator(ord('?')) self.ed.AutoCSetIgnoreCase(1) self.assertEquals(self.ed.AutoCGetIgnoreCase(), 1) self.ed.AutoCSetIgnoreCase(0) self.ed.AutoCSetAutoHide(0) self.assertEquals(self.ed.AutoCGetAutoHide(), 0) self.ed.AutoCSetAutoHide(1) self.ed.AutoCSetDropRestOfWord(1) self.assertEquals(self.ed.AutoCGetDropRestOfWord(), 1) self.ed.AutoCSetDropRestOfWord(0) def testAutoShow(self): self.assertEquals(self.ed.AutoCActive(), 0) self.ed.SetSel(0, 0) self.ed.AutoCShow(0, b"za defn ghi") self.assertEquals(self.ed.AutoCActive(), 1) #~ time.sleep(2) self.assertEquals(self.ed.AutoCPosStart(), 0) self.assertEquals(self.ed.AutoCGetCurrent(), 0) t = b"xxx" l = self.ed.AutoCGetCurrentText(5, t) #~ self.assertEquals(l, 3) self.assertEquals(t, b"za\0") self.ed.AutoCCancel() self.assertEquals(self.ed.AutoCActive(), 0) def testAutoShowComplete(self): self.assertEquals(self.ed.AutoCActive(), 0) self.ed.SetSel(0, 0) self.ed.AutoCShow(0, b"za defn ghi") self.ed.AutoCComplete() self.assertEquals(self.ed.Contents(), b"zaxxx\n") self.assertEquals(self.ed.AutoCActive(), 0) def testAutoShowSelect(self): self.assertEquals(self.ed.AutoCActive(), 0) self.ed.SetSel(0, 0) self.ed.AutoCShow(0, b"za defn ghi") self.ed.AutoCSelect(0, b"d") self.ed.AutoCComplete() self.assertEquals(self.ed.Contents(), b"defnxxx\n") self.assertEquals(self.ed.AutoCActive(), 0) class TestDirectAccess(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() def testGapPosition(self): text = b"abcd" self.ed.SetText(len(text), text) self.assertEquals(self.ed.GapPosition, 4) self.ed.TargetStart = 1 self.ed.TargetEnd = 1 rep = b"-" self.ed.ReplaceTarget(len(rep), rep) self.assertEquals(self.ed.GapPosition, 2) def testCharacterPointerAndRangePointer(self): text = b"abcd" self.ed.SetText(len(text), text) characterPointer = self.ed.CharacterPointer rangePointer = self.ed.GetRangePointer(0,3) self.assertEquals(characterPointer, rangePointer) cpBuffer = ctypes.c_char_p(characterPointer) self.assertEquals(cpBuffer.value, text) # Gap will not be moved as already moved for CharacterPointer call rangePointer = self.ed.GetRangePointer(1,3) cpBuffer = ctypes.c_char_p(rangePointer) self.assertEquals(cpBuffer.value, text[1:]) class TestWordChars(unittest.TestCase): def setUp(self): self.xite = XiteWin.xiteFrame self.ed = self.xite.ed self.ed.ClearAll() self.ed.EmptyUndoBuffer() def tearDown(self): self.ed.SetCharsDefault() def _setChars(self, charClass, chars): """ Wrapper to call self.ed.Set*Chars with the right type @param charClass {str} the character class, "word", "space", etc. @param chars {iterable of int} characters to set """ if sys.version_info.major == 2: # Python 2, use latin-1 encoded str unichars = (unichr(x) for x in chars if x != 0) # can't use literal u"", that's a syntax error in Py3k # uncode() doesn't exist in Py3k, but we never run it there result = unicode("").join(unichars).encode("latin-1") else: # Python 3, use bytes() result = bytes(x for x in chars if x != 0) meth = getattr(self.ed, "Set%sChars" % (charClass.capitalize())) return meth(None, result) def assertCharSetsEqual(self, first, second, *args, **kwargs): """ Assert that the two character sets are equal. If either set are an iterable of numbers, convert them to chars first. """ first_set = set() for c in first: first_set.add(chr(c) if isinstance(c, int) else c) second_set = set() for c in second: second_set.add(chr(c) if isinstance(c, int) else c) return self.assertEqual(first_set, second_set, *args, **kwargs) def testDefaultWordChars(self): # check that the default word chars are as expected import string dataLen = self.ed.GetWordChars(None, None) data = b"\0" * dataLen self.ed.GetWordChars(None, data) self.assertEquals(dataLen, len(data)) expected = set(string.digits + string.ascii_letters + '_') | \ set(chr(x) for x in range(0x80, 0x100)) self.assertCharSetsEqual(data, expected) def testDefaultWhitespaceChars(self): # check that the default whitespace chars are as expected import string dataLen = self.ed.GetWhitespaceChars(None, None) data = b"\0" * dataLen self.ed.GetWhitespaceChars(None, data) self.assertEquals(dataLen, len(data)) expected = (set(chr(x) for x in (range(0, 0x20))) | set(' ')) - \ set(['\r', '\n']) self.assertCharSetsEqual(data, expected) def testDefaultPunctuationChars(self): # check that the default punctuation chars are as expected import string dataLen = self.ed.GetPunctuationChars(None, None) data = b"\0" * dataLen self.ed.GetPunctuationChars(None, data) self.assertEquals(dataLen, len(data)) expected = set(chr(x) for x in range(0x20, 0x80)) - \ set(string.ascii_letters + string.digits + "\r\n_ ") self.assertCharSetsEqual(data, expected) def testCustomWordChars(self): # check that setting things to whitespace chars makes them not words self._setChars("whitespace", range(1, 0x100)) dataLen = self.ed.GetWordChars(None, None) data = b"\0" * dataLen self.ed.GetWordChars(None, data) self.assertEquals(dataLen, len(data)) expected = set() self.assertCharSetsEqual(data, expected) # and now set something to make sure that works too expected = set(range(1, 0x100, 2)) self._setChars("word", expected) dataLen = self.ed.GetWordChars(None, None) data = b"\0" * dataLen self.ed.GetWordChars(None, data) self.assertEquals(dataLen, len(data)) self.assertCharSetsEqual(data, expected) def testCustomWhitespaceChars(self): # check setting whitespace chars to non-default values self._setChars("word", range(1, 0x100)) # we can't change chr(0) from being anything but whitespace expected = set([0]) dataLen = self.ed.GetWhitespaceChars(None, None) data = b"\0" * dataLen self.ed.GetWhitespaceChars(None, data) self.assertEquals(dataLen, len(data)) self.assertCharSetsEqual(data, expected) # now try to set it to something custom expected = set(range(1, 0x100, 2)) | set([0]) self._setChars("whitespace", expected) dataLen = self.ed.GetWhitespaceChars(None, None) data = b"\0" * dataLen self.ed.GetWhitespaceChars(None, data) self.assertEquals(dataLen, len(data)) self.assertCharSetsEqual(data, expected) def testCustomPunctuationChars(self): # check setting punctuation chars to non-default values self._setChars("word", range(1, 0x100)) expected = set() dataLen = self.ed.GetPunctuationChars(None, None) data = b"\0" * dataLen self.ed.GetPunctuationChars(None, data) self.assertEquals(dataLen, len(data)) self.assertEquals(set(data), expected) # now try to set it to something custom expected = set(range(1, 0x100, 1)) self._setChars("punctuation", expected) dataLen = self.ed.GetPunctuationChars(None, None) data = b"\0" * dataLen self.ed.GetPunctuationChars(None, data) self.assertEquals(dataLen, len(data)) self.assertCharSetsEqual(data, expected) #~ import os #~ for x in os.getenv("PATH").split(";"): #~ n = "scilexer.dll" #~ nf = x + "\\" + n #~ print os.access(nf, os.R_OK), nf if __name__ == '__main__': uu = XiteWin.main("simpleTests") #~ for x in sorted(uu.keys()): #~ print(x, uu[x]) #~ print() |
Added test/unit/README.
> > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
The test/unit directory contains unit tests for Scintilla data structures. The tests can be run on Windows or Linux using g++ and GNU make. The Google Test framework is used. http://code.google.com/p/googletest/ Google test must be installed first. On Linux, install the google test packages libgtest-dev and libgtest0. On Windows download Google test and install it as a peer to the directory containing scintilla. The makefile assumes it is in ../../../../gtest-1.5.0. To run the tests: make ./unitTest |
Added test/unit/SciTE.properties.
> > > > |
1 2 3 4 |
if PLAT_WIN make.command=mingw32-make command.go.*.cxx=./unitTest command.go.needs.$(file.patterns.cplusplus)=$(make.command) |
Added test/unit/makefile.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# Build all the unit tests # Should be run using mingw32-make on Windows .SUFFIXES: .cxx GTEST_DIR = ../../../../gtest-1.5.0 ifdef windir DEL = del /q # Find Google Test headers. CPPFLAGS += -I$(GTEST_DIR)/include GTEST_ALL = gtest-all.o LINKFLAGS = $(CPPFLAGS) $(CXXFLAGS) EXE = unitTest.exe else DEL = rm -f CPPFLAGS = $(shell gtest-config --cppflags) CXXFLAGS = $(shell gtest-config --cxxflags) LINKFLAGS = $(shell gtest-config --ldflags --libs) EXE = unitTest # For coverage testing with gcov #CPPFLAGS += -fprofile-arcs -ftest-coverage #LINKFLAGS += -fprofile-arcs -ftest-coverage endif #vpath %.cxx ../src ../lexlib ../lexers vpath %.cxx ../../src INCLUDEDIRS = -I ../../include -I ../../src -I../../lexlib # Find headers of test code. CPPFLAGS += $(INCLUDEDIRS) CXXFLAGS += -g -Wall -Wextra -Wno-unused-function #~ CXXFLAGS += -g -Wall CASES:=$(addsuffix .o,$(basename $(notdir $(wildcard test*.cxx)))) TESTEDOBJS=ContractionState.o RunStyles.o CharClassify.o TESTS=$(EXE) GTEST_HEADERS=$(GTEST_DIR)/include/gtest/*.h $(GTEST_DIR)/include/gtest/internal/*.h all: $(TESTS) clean: $(DEL) $(TESTS) *.a *.o *.exe *.gcov *.gcda *.gcno # Usually you shouldn't tweak such internal variables, indicated by a # trailing _. GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS) gtest-all.o: $(GTEST_SRCS_) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -I$(GTEST_DIR) -c \ $(GTEST_DIR)/src/gtest-all.cc .cxx.o: $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< $(EXE): $(CASES) $(TESTEDOBJS) unitTest.o $(GTEST_ALL) $(CXX) $(LINKFLAGS) $^ -o $@ |
Added test/unit/testCharClassify.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
// Unit Tests for Scintilla internal data structures #include <string.h> #include "Platform.h" #include "CharClassify.h" #include <gtest/gtest.h> // Test CharClassify. class CharClassifyTest : public::testing::Test { protected: virtual void SetUp() { pcc = new CharClassify(); for (int ch = 0; ch < 256; ch++) { if (ch == '\r' || ch == '\n') charClass[ch] = CharClassify::ccNewLine; else if (ch < 0x20 || ch == ' ') charClass[ch] = CharClassify::ccSpace; else if (ch >= 0x80 || isalnum(ch) || ch == '_') charClass[ch] = CharClassify::ccWord; else charClass[ch] = CharClassify::ccPunctuation; } } virtual void TearDown() { delete pcc; pcc = 0; } CharClassify *pcc; CharClassify::cc charClass[256]; static const char* GetClassName(CharClassify::cc charClass) { switch(charClass) { #define CASE(c) case CharClassify::c: return #c CASE(ccSpace); CASE(ccNewLine); CASE(ccWord); CASE(ccPunctuation); #undef CASE default: return "<unknown>"; } } }; TEST_F(CharClassifyTest, Defaults) { for (int i = 0; i < 256; i++) { EXPECT_EQ(charClass[i], pcc->GetClass(i)) << "Character " << i << " should be class " << GetClassName(charClass[i]) << ", but got " << GetClassName(pcc->GetClass(i)); } } TEST_F(CharClassifyTest, Custom) { unsigned char buf[2] = {0, 0}; for (int i = 0; i < 256; i++) { CharClassify::cc thisClass = CharClassify::cc(i % 4); buf[0] = i; pcc->SetCharClasses(buf, thisClass); charClass[i] = thisClass; } for (int i = 0; i < 256; i++) { EXPECT_EQ(charClass[i], pcc->GetClass(i)) << "Character " << i << " should be class " << GetClassName(charClass[i]) << ", but got " << GetClassName(pcc->GetClass(i)); } } TEST_F(CharClassifyTest, CharsOfClass) { unsigned char buf[2] = {0, 0}; for (int i = 1; i < 256; i++) { CharClassify::cc thisClass = CharClassify::cc(i % 4); buf[0] = i; pcc->SetCharClasses(buf, thisClass); charClass[i] = thisClass; } for (int classVal = 0; classVal < 4; ++classVal) { CharClassify::cc thisClass = CharClassify::cc(classVal % 4); int size = pcc->GetCharsOfClass(thisClass, NULL); unsigned char* buffer = reinterpret_cast<unsigned char*>(malloc(size + 1)); ASSERT_TRUE(buffer); buffer[size] = '\0'; pcc->GetCharsOfClass(thisClass, buffer); for (int i = 1; i < 256; i++) { if (charClass[i] == thisClass) { EXPECT_TRUE(memchr(reinterpret_cast<char*>(buffer), i, size)) << "Character " << i << " should be class " << GetClassName(thisClass) << ", but was not in GetCharsOfClass;" << " it is reported to be " << GetClassName(pcc->GetClass(i)); } else { EXPECT_FALSE(memchr(reinterpret_cast<char*>(buffer), i, size)) << "Character " << i << " should not be class " << GetClassName(thisClass) << ", but was in GetCharsOfClass" << " it is reported to be " << GetClassName(pcc->GetClass(i)); } } free(buffer); } } |
Added test/unit/testContractionState.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
// Unit Tests for Scintilla internal data structures #include <string.h> #include "Platform.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" #include "ContractionState.h" #include <gtest/gtest.h> // Test ContractionState. class ContractionStateTest : public ::testing::Test { protected: virtual void SetUp() { pcs = new ContractionState(); } virtual void TearDown() { delete pcs; pcs = 0; } ContractionState *pcs; }; TEST_F(ContractionStateTest, IsEmptyInitially) { EXPECT_EQ(1, pcs->LinesInDoc()); EXPECT_EQ(1, pcs->LinesDisplayed()); EXPECT_EQ(0, pcs->DisplayFromDoc(0)); EXPECT_EQ(0, pcs->DocFromDisplay(0)); } TEST_F(ContractionStateTest, OneLine) { pcs->InsertLine(0); EXPECT_EQ(2, pcs->LinesInDoc()); EXPECT_EQ(2, pcs->LinesDisplayed()); EXPECT_EQ(0, pcs->DisplayFromDoc(0)); EXPECT_EQ(0, pcs->DocFromDisplay(0)); EXPECT_EQ(1, pcs->DisplayFromDoc(1)); EXPECT_EQ(1, pcs->DocFromDisplay(1)); } TEST_F(ContractionStateTest, InsertionThenDeletions) { pcs->InsertLines(0,4); pcs->DeleteLine(1); EXPECT_EQ(4, pcs->LinesInDoc()); EXPECT_EQ(4, pcs->LinesDisplayed()); for (int l=0;l<4;l++) { EXPECT_EQ(l, pcs->DisplayFromDoc(l)); EXPECT_EQ(l, pcs->DocFromDisplay(l)); } pcs->DeleteLines(0,2); EXPECT_EQ(2, pcs->LinesInDoc()); EXPECT_EQ(2, pcs->LinesDisplayed()); for (int l=0;l<2;l++) { EXPECT_EQ(l, pcs->DisplayFromDoc(l)); EXPECT_EQ(l, pcs->DocFromDisplay(l)); } } TEST_F(ContractionStateTest, ShowHide) { pcs->InsertLines(0,4); EXPECT_EQ(true, pcs->GetVisible(0)); EXPECT_EQ(true, pcs->GetVisible(1)); EXPECT_EQ(true, pcs->GetVisible(2)); EXPECT_EQ(5, pcs->LinesDisplayed()); pcs->SetVisible(1, 1, false); EXPECT_EQ(true, pcs->GetVisible(0)); EXPECT_EQ(0, pcs->GetVisible(1)); EXPECT_EQ(true, pcs->GetVisible(2)); EXPECT_EQ(4, pcs->LinesDisplayed()); EXPECT_EQ(1, pcs->HiddenLines()); pcs->SetVisible(1, 2, true); for (int l=0;l<4;l++) { EXPECT_EQ(true, pcs->GetVisible(0)); } pcs->SetVisible(1, 1, false); EXPECT_EQ(0, pcs->GetVisible(1)); pcs->ShowAll(); for (int l=0;l<4;l++) { EXPECT_EQ(true, pcs->GetVisible(0)); } EXPECT_EQ(0, pcs->HiddenLines()); } TEST_F(ContractionStateTest, Hidden) { pcs->InsertLines(0,1); for (int l=0;l<2;l++) { EXPECT_EQ(true, pcs->GetVisible(0)); } EXPECT_EQ(0, pcs->HiddenLines()); pcs->SetVisible(1, 1, false); EXPECT_EQ(true, pcs->GetVisible(0)); EXPECT_EQ(0, pcs->GetVisible(1)); EXPECT_EQ(1, pcs->HiddenLines()); pcs->SetVisible(1, 1, true); for (int l=0;l<2;l++) { EXPECT_EQ(true, pcs->GetVisible(0)); } EXPECT_EQ(0, pcs->HiddenLines()); } TEST_F(ContractionStateTest, Contracting) { pcs->InsertLines(0,4); for (int l=0;l<4;l++) { EXPECT_EQ(true, pcs->GetExpanded(l)); } pcs->SetExpanded(2, false); EXPECT_EQ(true, pcs->GetExpanded(1)); EXPECT_EQ(0, pcs->GetExpanded(2)); EXPECT_EQ(true, pcs->GetExpanded(3)); EXPECT_EQ(2, pcs->ContractedNext(0)); EXPECT_EQ(2, pcs->ContractedNext(1)); EXPECT_EQ(2, pcs->ContractedNext(2)); EXPECT_EQ(-1, pcs->ContractedNext(3)); pcs->SetExpanded(2, true); EXPECT_EQ(true, pcs->GetExpanded(1)); EXPECT_EQ(true, pcs->GetExpanded(2)); EXPECT_EQ(true, pcs->GetExpanded(3)); } TEST_F(ContractionStateTest, ChangeHeight) { pcs->InsertLines(0,4); for (int l=0;l<4;l++) { EXPECT_EQ(1, pcs->GetHeight(l)); } pcs->SetHeight(1, 2); EXPECT_EQ(1, pcs->GetHeight(0)); EXPECT_EQ(2, pcs->GetHeight(1)); EXPECT_EQ(1, pcs->GetHeight(2)); } |
Added test/unit/testPartitioning.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
// Unit Tests for Scintilla internal data structures #include <string.h> #include "Platform.h" #include "SplitVector.h" #include "Partitioning.h" #include <gtest/gtest.h> const int growSize = 4; const int lengthTestArray = 8; static const int testArray[lengthTestArray] = {3, 4, 5, 6, 7, 8, 9, 10}; // Test SplitVectorWithRangeAdd. class SplitVectorWithRangeAddTest : public ::testing::Test { protected: virtual void SetUp() { psvwra = new SplitVectorWithRangeAdd(growSize); } virtual void TearDown() { delete psvwra; psvwra = 0; } SplitVectorWithRangeAdd *psvwra; }; TEST_F(SplitVectorWithRangeAddTest, IsEmptyInitially) { EXPECT_EQ(0, psvwra->Length()); } TEST_F(SplitVectorWithRangeAddTest, IncrementExceptEnds) { psvwra->InsertFromArray(0, testArray, 0, lengthTestArray); psvwra->RangeAddDelta(1, lengthTestArray-1, 1); for (int i=0; i<psvwra->Length(); i++) { if ((i == 0) || (i == lengthTestArray-1)) EXPECT_EQ(i+3, psvwra->ValueAt(i)); else EXPECT_EQ(i+4, psvwra->ValueAt(i)); } } // Test Partitioning. class PartitioningTest : public ::testing::Test { protected: virtual void SetUp() { pp = new Partitioning(growSize); } virtual void TearDown() { delete pp; pp = 0; } Partitioning *pp; }; TEST_F(PartitioningTest, IsEmptyInitially) { EXPECT_EQ(1, pp->Partitions()); EXPECT_EQ(0, pp->PositionFromPartition(pp->Partitions())); EXPECT_EQ(0, pp->PartitionFromPosition(0)); } TEST_F(PartitioningTest, SimpleInsert) { pp->InsertText(0, 1); EXPECT_EQ(1, pp->Partitions()); EXPECT_EQ(1, pp->PositionFromPartition(pp->Partitions())); } TEST_F(PartitioningTest, TwoPartitions) { pp->InsertText(0, 2); pp->InsertPartition(1, 1); EXPECT_EQ(2, pp->Partitions()); EXPECT_EQ(0, pp->PositionFromPartition(0)); EXPECT_EQ(1, pp->PositionFromPartition(1)); EXPECT_EQ(2, pp->PositionFromPartition(2)); } TEST_F(PartitioningTest, MoveStart) { pp->InsertText(0, 3); pp->InsertPartition(1, 2); pp->SetPartitionStartPosition(1,1); EXPECT_EQ(2, pp->Partitions()); EXPECT_EQ(0, pp->PositionFromPartition(0)); EXPECT_EQ(1, pp->PositionFromPartition(1)); EXPECT_EQ(3, pp->PositionFromPartition(2)); } TEST_F(PartitioningTest, InsertAgain) { pp->InsertText(0, 3); pp->InsertPartition(1, 2); pp->InsertText(0,3); pp->InsertText(1,2); EXPECT_EQ(2, pp->Partitions()); EXPECT_EQ(0, pp->PositionFromPartition(0)); EXPECT_EQ(5, pp->PositionFromPartition(1)); EXPECT_EQ(8, pp->PositionFromPartition(2)); } TEST_F(PartitioningTest, InsertReversed) { pp->InsertText(0, 3); pp->InsertPartition(1, 2); pp->InsertText(1,2); pp->InsertText(0,3); EXPECT_EQ(2, pp->Partitions()); EXPECT_EQ(0, pp->PositionFromPartition(0)); EXPECT_EQ(5, pp->PositionFromPartition(1)); EXPECT_EQ(8, pp->PositionFromPartition(2)); } TEST_F(PartitioningTest, InverseSearch) { pp->InsertText(0, 3); pp->InsertPartition(1, 2); pp->SetPartitionStartPosition(1,1); EXPECT_EQ(2, pp->Partitions()); EXPECT_EQ(0, pp->PositionFromPartition(0)); EXPECT_EQ(1, pp->PositionFromPartition(1)); EXPECT_EQ(3, pp->PositionFromPartition(2)); EXPECT_EQ(0, pp->PartitionFromPosition(0)); EXPECT_EQ(1, pp->PartitionFromPosition(1)); EXPECT_EQ(1, pp->PartitionFromPosition(2)); EXPECT_EQ(1, pp->PartitionFromPosition(3)); } TEST_F(PartitioningTest, DeletePartition) { pp->InsertText(0, 2); pp->InsertPartition(1, 1); pp->RemovePartition(1); EXPECT_EQ(1, pp->Partitions()); EXPECT_EQ(0, pp->PositionFromPartition(0)); EXPECT_EQ(2, pp->PositionFromPartition(1)); } TEST_F(PartitioningTest, DeleteAll) { pp->InsertText(0, 3); pp->InsertPartition(1, 2); pp->SetPartitionStartPosition(1,1); pp->DeleteAll(); // Back to initial state EXPECT_EQ(1, pp->Partitions()); EXPECT_EQ(0, pp->PositionFromPartition(pp->Partitions())); } TEST_F(PartitioningTest, TestBackwards) { pp->InsertText(0, 10); pp->InsertPartition(1, 3); pp->InsertPartition(2, 6); pp->InsertPartition(3, 9); pp->InsertText(2,4); pp->InsertText(1,2); pp->InsertText(0,3); EXPECT_EQ(4, pp->Partitions()); EXPECT_EQ(0, pp->PositionFromPartition(0)); EXPECT_EQ(6, pp->PositionFromPartition(1)); EXPECT_EQ(11, pp->PositionFromPartition(2)); EXPECT_EQ(18, pp->PositionFromPartition(3)); EXPECT_EQ(19, pp->PositionFromPartition(4)); } TEST_F(PartitioningTest, TestMany) { // Provoke backstep call pp->InsertText(0, 42); for (int i=0; i<20; i++) { pp->InsertPartition(i+1, (i+1) * 2); } for (int i=20; i>0; i--) { pp->InsertText(i,2); } EXPECT_EQ(21, pp->Partitions()); for (int i=1; i<20; i++) { EXPECT_EQ(i*4 - 2, pp->PositionFromPartition(i)); EXPECT_EQ(i, pp->PartitionFromPosition(i*4 - 2)); } pp->InsertText(19,2); EXPECT_EQ(3, pp->PartitionFromPosition(10)); pp->InsertText(0,2); pp->InsertText(0,-2); pp->RemovePartition(1); EXPECT_EQ(0, pp->PositionFromPartition(0)); EXPECT_EQ(6, pp->PositionFromPartition(1)); EXPECT_EQ(10, pp->PositionFromPartition(2)); pp->RemovePartition(10); EXPECT_EQ(46, pp->PositionFromPartition(10)); EXPECT_EQ(10, pp->PartitionFromPosition(46)); EXPECT_EQ(50, pp->PositionFromPartition(11)); EXPECT_EQ(11, pp->PartitionFromPosition(50)); } #if !PLAT_WIN // Omit death tests on Windows where they trigger a system "unitTest.exe has stopped working" popup. TEST_F(PartitioningTest, OutOfRangeDeathTest) { ::testing::FLAGS_gtest_death_test_style = "threadsafe"; pp->InsertText(0, 2); pp->InsertPartition(1, 1); EXPECT_EQ(2, pp->Partitions()); ASSERT_DEATH(pp->PositionFromPartition(-1), "Assertion"); ASSERT_DEATH(pp->PositionFromPartition(3), "Assertion"); } #endif |
Added test/unit/testRunStyles.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 |
// Unit Tests for Scintilla internal data structures #include <string.h> #include "Platform.h" #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" #include <gtest/gtest.h> // Test RunStyles. class RunStylesTest : public ::testing::Test { protected: virtual void SetUp() { prs = new RunStyles(); } virtual void TearDown() { delete prs; prs = 0; } RunStyles *prs; }; TEST_F(RunStylesTest, IsEmptyInitially) { EXPECT_EQ(0, prs->Length()); EXPECT_EQ(1, prs->Runs()); } TEST_F(RunStylesTest, SimpleInsert) { prs->InsertSpace(0, 1); EXPECT_EQ(1, prs->Length()); EXPECT_EQ(1, prs->Runs()); EXPECT_EQ(0, prs->ValueAt(0)); EXPECT_EQ(1, prs->FindNextChange(0, prs->Length())); EXPECT_EQ(2, prs->FindNextChange(1, prs->Length())); } TEST_F(RunStylesTest, TwoRuns) { prs->InsertSpace(0, 2); EXPECT_EQ(2, prs->Length()); EXPECT_EQ(1, prs->Runs()); prs->SetValueAt(0, 2); EXPECT_EQ(2, prs->Runs()); EXPECT_EQ(2, prs->ValueAt(0)); EXPECT_EQ(0, prs->ValueAt(1)); EXPECT_EQ(1, prs->FindNextChange(0, prs->Length())); EXPECT_EQ(2, prs->FindNextChange(1, prs->Length())); EXPECT_EQ(3, prs->FindNextChange(2, prs->Length())); } TEST_F(RunStylesTest, LongerRuns) { prs->InsertSpace(0, 5); prs->SetValueAt(0, 3); prs->SetValueAt(1, 3); EXPECT_EQ(3, prs->ValueAt(0)); EXPECT_EQ(3, prs->ValueAt(1)); EXPECT_EQ(0, prs->ValueAt(2)); EXPECT_EQ(2, prs->Runs()); EXPECT_EQ(0, prs->StartRun(0)); EXPECT_EQ(2, prs->EndRun(0)); EXPECT_EQ(0, prs->StartRun(1)); EXPECT_EQ(2, prs->EndRun(1)); EXPECT_EQ(2, prs->StartRun(2)); EXPECT_EQ(5, prs->EndRun(2)); EXPECT_EQ(2, prs->StartRun(3)); EXPECT_EQ(5, prs->EndRun(3)); EXPECT_EQ(2, prs->StartRun(4)); EXPECT_EQ(5, prs->EndRun(4)); // At end EXPECT_EQ(2, prs->StartRun(5)); EXPECT_EQ(5, prs->EndRun(5)); // After end is same as end EXPECT_EQ(2, prs->StartRun(6)); EXPECT_EQ(5, prs->EndRun(6)); EXPECT_EQ(2, prs->FindNextChange(0, prs->Length())); EXPECT_EQ(5, prs->FindNextChange(2, prs->Length())); EXPECT_EQ(6, prs->FindNextChange(5, prs->Length())); } TEST_F(RunStylesTest, FillRange) { prs->InsertSpace(0, 5); int startFill = 1; int lengthFill = 3; EXPECT_EQ(true, prs->FillRange(startFill, 99, lengthFill)); EXPECT_EQ(1, startFill); EXPECT_EQ(3, lengthFill); EXPECT_EQ(0, prs->ValueAt(0)); EXPECT_EQ(99, prs->ValueAt(1)); EXPECT_EQ(99, prs->ValueAt(2)); EXPECT_EQ(99, prs->ValueAt(3)); EXPECT_EQ(0, prs->ValueAt(4)); EXPECT_EQ(0, prs->StartRun(0)); EXPECT_EQ(1, prs->EndRun(0)); EXPECT_EQ(1, prs->StartRun(1)); EXPECT_EQ(4, prs->EndRun(1)); } TEST_F(RunStylesTest, FillRangeAlreadyFilled) { prs->InsertSpace(0, 5); int startFill = 1; int lengthFill = 3; EXPECT_EQ(true, prs->FillRange(startFill, 99, lengthFill)); EXPECT_EQ(1, startFill); EXPECT_EQ(3, lengthFill); int startFill2 = 2; int lengthFill2 = 1; // Compiler warnings if 'false' used instead of '0' as expected value: EXPECT_EQ(0, prs->FillRange(startFill2, 99, lengthFill2)); EXPECT_EQ(2, startFill2); EXPECT_EQ(1, lengthFill2); EXPECT_EQ(0, prs->ValueAt(0)); EXPECT_EQ(99, prs->ValueAt(1)); EXPECT_EQ(99, prs->ValueAt(2)); EXPECT_EQ(99, prs->ValueAt(3)); EXPECT_EQ(0, prs->ValueAt(4)); EXPECT_EQ(3, prs->Runs()); } TEST_F(RunStylesTest, FillRangeAlreadyPartFilled) { prs->InsertSpace(0, 5); int startFill = 1; int lengthFill = 2; EXPECT_EQ(true, prs->FillRange(startFill, 99, lengthFill)); EXPECT_EQ(1, startFill); EXPECT_EQ(2, lengthFill); int startFill2 = 2; int lengthFill2 = 2; EXPECT_EQ(true, prs->FillRange(startFill2, 99, lengthFill2)); EXPECT_EQ(3, startFill2); EXPECT_EQ(1, lengthFill2); EXPECT_EQ(3, prs->Runs()); } TEST_F(RunStylesTest, DeleteRange) { prs->InsertSpace(0, 5); prs->SetValueAt(0, 3); EXPECT_EQ(2, prs->Runs()); prs->SetValueAt(1, 3); EXPECT_EQ(2, prs->Runs()); prs->DeleteRange(1, 1); EXPECT_EQ(4, prs->Length()); EXPECT_EQ(2, prs->Runs()); EXPECT_EQ(3, prs->ValueAt(0)); EXPECT_EQ(0, prs->ValueAt(1)); EXPECT_EQ(0, prs->StartRun(0)); EXPECT_EQ(1, prs->EndRun(0)); EXPECT_EQ(1, prs->StartRun(1)); EXPECT_EQ(4, prs->EndRun(1)); EXPECT_EQ(1, prs->StartRun(2)); EXPECT_EQ(4, prs->EndRun(2)); } TEST_F(RunStylesTest, Find) { prs->InsertSpace(0, 5); int startFill = 1; int lengthFill = 3; EXPECT_EQ(true, prs->FillRange(startFill, 99, lengthFill)); EXPECT_EQ(1, startFill); EXPECT_EQ(3, lengthFill); EXPECT_EQ(0, prs->Find(0,0)); EXPECT_EQ(1, prs->Find(99,0)); EXPECT_EQ(-1, prs->Find(3,0)); EXPECT_EQ(4, prs->Find(0,1)); EXPECT_EQ(1, prs->Find(99,1)); EXPECT_EQ(-1, prs->Find(3,1)); EXPECT_EQ(4, prs->Find(0,2)); EXPECT_EQ(2, prs->Find(99,2)); EXPECT_EQ(-1, prs->Find(3,2)); EXPECT_EQ(4, prs->Find(0,4)); EXPECT_EQ(-1, prs->Find(99,4)); EXPECT_EQ(-1, prs->Find(3,4)); EXPECT_EQ(-1, prs->Find(0,5)); EXPECT_EQ(-1, prs->Find(99,5)); EXPECT_EQ(-1, prs->Find(3,5)); EXPECT_EQ(-1, prs->Find(0,6)); EXPECT_EQ(-1, prs->Find(99,6)); EXPECT_EQ(-1, prs->Find(3,6)); } TEST_F(RunStylesTest, AllSame) { EXPECT_EQ(true, prs->AllSame()); prs->InsertSpace(0, 5); EXPECT_EQ(true, prs->AllSame()); EXPECT_EQ(0, prs->AllSameAs(88)); EXPECT_EQ(true, prs->AllSameAs(0)); int startFill = 1; int lengthFill = 3; EXPECT_EQ(true, prs->FillRange(startFill, 99, lengthFill)); EXPECT_EQ(0, prs->AllSame()); EXPECT_EQ(0, prs->AllSameAs(88)); EXPECT_EQ(0, prs->AllSameAs(0)); EXPECT_EQ(true, prs->FillRange(startFill, 0, lengthFill)); EXPECT_EQ(true, prs->AllSame()); EXPECT_EQ(0, prs->AllSameAs(88)); EXPECT_EQ(true, prs->AllSameAs(0)); } TEST_F(RunStylesTest, FindWithReversion) { prs->InsertSpace(0, 5); EXPECT_EQ(1, prs->Runs()); int startFill = 1; int lengthFill = 1; EXPECT_EQ(true, prs->FillRange(startFill, 99, lengthFill)); EXPECT_EQ(1, startFill); EXPECT_EQ(1, lengthFill); EXPECT_EQ(3, prs->Runs()); startFill = 2; lengthFill = 1; EXPECT_EQ(true, prs->FillRange(startFill, 99, lengthFill)); EXPECT_EQ(2, startFill); EXPECT_EQ(1, lengthFill); EXPECT_EQ(3, prs->Runs()); startFill = 1; lengthFill = 1; EXPECT_EQ(true, prs->FillRange(startFill, 0, lengthFill)); EXPECT_EQ(3, prs->Runs()); EXPECT_EQ(1, lengthFill); startFill = 2; lengthFill = 1; EXPECT_EQ(true, prs->FillRange(startFill, 0, lengthFill)); EXPECT_EQ(1, prs->Runs()); EXPECT_EQ(1, lengthFill); EXPECT_EQ(-1, prs->Find(0,6)); } TEST_F(RunStylesTest, FinalRunInversion) { EXPECT_EQ(1, prs->Runs()); prs->InsertSpace(0, 1); EXPECT_EQ(1, prs->Runs()); prs->SetValueAt(0, 1); EXPECT_EQ(1, prs->Runs()); prs->InsertSpace(1, 1); EXPECT_EQ(1, prs->Runs()); prs->SetValueAt(1, 1); EXPECT_EQ(1, prs->Runs()); prs->SetValueAt(1, 0); EXPECT_EQ(2, prs->Runs()); prs->SetValueAt(1, 1); EXPECT_EQ(1, prs->Runs()); } TEST_F(RunStylesTest, DeleteAll) { prs->InsertSpace(0, 5); prs->SetValueAt(0, 3); prs->SetValueAt(1, 3); prs->DeleteAll(); EXPECT_EQ(0, prs->Length()); EXPECT_EQ(0, prs->ValueAt(0)); EXPECT_EQ(1, prs->Runs()); } TEST_F(RunStylesTest, DeleteSecond) { prs->InsertSpace(0, 3); int startFill = 1; int lengthFill = 1; EXPECT_EQ(true, prs->FillRange(startFill, 99, lengthFill)); EXPECT_EQ(3, prs->Length()); EXPECT_EQ(3, prs->Runs()); prs->DeleteRange(1, 1); EXPECT_EQ(2, prs->Length()); EXPECT_EQ(1, prs->Runs()); } TEST_F(RunStylesTest, DeleteEndRun) { prs->InsertSpace(0, 2); int startFill = 1; int lengthFill = 1; EXPECT_EQ(true, prs->FillRange(startFill, 99, lengthFill)); EXPECT_EQ(2, prs->Length()); EXPECT_EQ(2, prs->Runs()); EXPECT_EQ(0, prs->StartRun(0)); EXPECT_EQ(1, prs->EndRun(0)); EXPECT_EQ(1, prs->StartRun(1)); EXPECT_EQ(2, prs->EndRun(1)); prs->DeleteRange(1, 1); EXPECT_EQ(1, prs->Length()); EXPECT_EQ(1, prs->Runs()); EXPECT_EQ(0, prs->StartRun(0)); EXPECT_EQ(1, prs->EndRun(0)); EXPECT_EQ(0, prs->StartRun(1)); EXPECT_EQ(1, prs->EndRun(1)); } |
Added test/unit/testSparseState.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
// Unit Tests for Scintilla internal data structures #include <string> #include <vector> #include <algorithm> #include "Platform.h" #include "SparseState.h" #include <gtest/gtest.h> // Test SparseState. class SparseStateTest : public ::testing::Test { protected: virtual void SetUp() { pss = new SparseState<int>(); } virtual void TearDown() { delete pss; pss = 0; } SparseState<int> *pss; }; TEST_F(SparseStateTest, IsEmptyInitially) { EXPECT_EQ(0u, pss->size()); int val = pss->ValueAt(0); EXPECT_EQ(0, val); } TEST_F(SparseStateTest, SimpleSetAndGet) { pss->Set(0, 22); pss->Set(1, 23); EXPECT_EQ(2u, pss->size()); EXPECT_EQ(0, pss->ValueAt(-1)); EXPECT_EQ(22, pss->ValueAt(0)); EXPECT_EQ(23, pss->ValueAt(1)); EXPECT_EQ(23, pss->ValueAt(2)); } TEST_F(SparseStateTest, RetrieveBetween) { pss->Set(0, 10); pss->Set(2, 12); EXPECT_EQ(2u, pss->size()); EXPECT_EQ(0, pss->ValueAt(-1)); EXPECT_EQ(10, pss->ValueAt(0)); EXPECT_EQ(10, pss->ValueAt(1)); EXPECT_EQ(12, pss->ValueAt(2)); } TEST_F(SparseStateTest, RetrieveBefore) { pss->Set(2, 12); EXPECT_EQ(1u, pss->size()); EXPECT_EQ(0, pss->ValueAt(-1)); EXPECT_EQ(0, pss->ValueAt(0)); EXPECT_EQ(0, pss->ValueAt(1)); EXPECT_EQ(12, pss->ValueAt(2)); } TEST_F(SparseStateTest, Delete) { pss->Set(0, 30); pss->Set(2, 32); pss->Delete(2); EXPECT_EQ(1u, pss->size()); EXPECT_EQ(0, pss->ValueAt(-1)); EXPECT_EQ(30, pss->ValueAt(0)); EXPECT_EQ(30, pss->ValueAt(1)); EXPECT_EQ(30, pss->ValueAt(2)); } TEST_F(SparseStateTest, DeleteBetweeen) { pss->Set(0, 30); pss->Set(2, 32); pss->Delete(1); EXPECT_EQ(1u, pss->size()); EXPECT_EQ(0, pss->ValueAt(-1)); EXPECT_EQ(30, pss->ValueAt(0)); EXPECT_EQ(30, pss->ValueAt(1)); EXPECT_EQ(30, pss->ValueAt(2)); } TEST_F(SparseStateTest, ReplaceLast) { pss->Set(0, 30); pss->Set(2, 31); pss->Set(2, 32); EXPECT_EQ(2u, pss->size()); EXPECT_EQ(0, pss->ValueAt(-1)); EXPECT_EQ(30, pss->ValueAt(0)); EXPECT_EQ(30, pss->ValueAt(1)); EXPECT_EQ(32, pss->ValueAt(2)); EXPECT_EQ(32, pss->ValueAt(3)); } TEST_F(SparseStateTest, OnlyChangeAppended) { pss->Set(0, 30); pss->Set(2, 31); pss->Set(3, 31); EXPECT_EQ(2u, pss->size()); } TEST_F(SparseStateTest, MergeBetween) { pss->Set(0, 30); pss->Set(2, 32); pss->Set(4, 34); EXPECT_EQ(3u, pss->size()); SparseState<int> ssAdditions(3); ssAdditions.Set(4, 34); EXPECT_EQ(1u, ssAdditions.size()); bool mergeChanged = pss->Merge(ssAdditions,5); EXPECT_EQ(0, mergeChanged); ssAdditions.Set(4, 44); EXPECT_EQ(1u, ssAdditions.size()); mergeChanged = pss->Merge(ssAdditions,5); EXPECT_EQ(true, mergeChanged); EXPECT_EQ(3u, pss->size()); EXPECT_EQ(44, pss->ValueAt(4)); } TEST_F(SparseStateTest, MergeAtExisting) { pss->Set(0, 30); pss->Set(2, 32); pss->Set(4, 34); EXPECT_EQ(3u, pss->size()); SparseState<int> ssAdditions(4); ssAdditions.Set(4, 34); EXPECT_EQ(1u, ssAdditions.size()); bool mergeChanged = pss->Merge(ssAdditions,5); EXPECT_EQ(0, mergeChanged); ssAdditions.Set(4, 44); EXPECT_EQ(1u, ssAdditions.size()); mergeChanged = pss->Merge(ssAdditions,5); EXPECT_EQ(true, mergeChanged); EXPECT_EQ(3u, pss->size()); EXPECT_EQ(44, pss->ValueAt(4)); } TEST_F(SparseStateTest, MergeWhichRemoves) { pss->Set(0, 30); pss->Set(2, 32); pss->Set(4, 34); EXPECT_EQ(3u, pss->size()); SparseState<int> ssAdditions(2); ssAdditions.Set(2, 22); EXPECT_EQ(1u, ssAdditions.size()); EXPECT_EQ(22, ssAdditions.ValueAt(2)); bool mergeChanged = pss->Merge(ssAdditions,5); EXPECT_EQ(true, mergeChanged); EXPECT_EQ(2u, pss->size()); EXPECT_EQ(22, pss->ValueAt(2)); } TEST_F(SparseStateTest, MergeIgnoreSome) { pss->Set(0, 30); pss->Set(2, 32); pss->Set(4, 34); SparseState<int> ssAdditions(2); ssAdditions.Set(2, 32); bool mergeChanged = pss->Merge(ssAdditions,3); EXPECT_EQ(0, mergeChanged); EXPECT_EQ(2u, pss->size()); EXPECT_EQ(32, pss->ValueAt(2)); } TEST_F(SparseStateTest, MergeIgnoreSomeStart) { pss->Set(0, 30); pss->Set(2, 32); pss->Set(4, 34); SparseState<int> ssAdditions(2); ssAdditions.Set(2, 32); bool mergeChanged = pss->Merge(ssAdditions,2); EXPECT_EQ(0, mergeChanged); EXPECT_EQ(2u, pss->size()); EXPECT_EQ(32, pss->ValueAt(2)); } TEST_F(SparseStateTest, MergeIgnoreRepeat) { pss->Set(0, 30); pss->Set(2, 32); pss->Set(4, 34); SparseState<int> ssAdditions(5); // Appending same value as at end of pss. ssAdditions.Set(5, 34); bool mergeChanged = pss->Merge(ssAdditions,6); EXPECT_EQ(0, mergeChanged); EXPECT_EQ(3u, pss->size()); EXPECT_EQ(34, pss->ValueAt(4)); } class SparseStateStringTest : public ::testing::Test { protected: virtual void SetUp() { pss = new SparseState<std::string>(); } virtual void TearDown() { delete pss; pss = 0; } SparseState<std::string> *pss; }; TEST_F(SparseStateStringTest, IsEmptyInitially) { EXPECT_EQ(0u, pss->size()); std::string val = pss->ValueAt(0); EXPECT_EQ("", val); } TEST_F(SparseStateStringTest, SimpleSetAndGet) { EXPECT_EQ(0u, pss->size()); pss->Set(0, "22"); pss->Set(1, "23"); EXPECT_EQ(2u, pss->size()); EXPECT_EQ("", pss->ValueAt(-1)); EXPECT_EQ("22", pss->ValueAt(0)); EXPECT_EQ("23", pss->ValueAt(1)); EXPECT_EQ("23", pss->ValueAt(2)); } TEST_F(SparseStateStringTest, DeleteBetweeen) { pss->Set(0, "30"); pss->Set(2, "32"); pss->Delete(1); EXPECT_EQ(1u, pss->size()); EXPECT_EQ("", pss->ValueAt(-1)); EXPECT_EQ("30", pss->ValueAt(0)); EXPECT_EQ("30", pss->ValueAt(1)); EXPECT_EQ("30", pss->ValueAt(2)); } |
Added test/unit/testSplitVector.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
// Unit Tests for Scintilla internal data structures #include <string.h> #include "Platform.h" #include "SplitVector.h" #include <gtest/gtest.h> // Test SplitVector. class SplitVectorTest : public ::testing::Test { protected: virtual void SetUp() { psv = new SplitVector<int>; } virtual void TearDown() { delete psv; psv = 0; } SplitVector<int> *psv; }; const int lengthTestArray = 4; static const int testArray[4] = {3, 4, 5, 6}; TEST_F(SplitVectorTest, IsEmptyInitially) { EXPECT_EQ(0, psv->Length()); } TEST_F(SplitVectorTest, InsertOne) { psv->InsertValue(0, 10, 0); psv->Insert(5, 3); EXPECT_EQ(11, psv->Length()); for (int i=0; i<psv->Length(); i++) { EXPECT_EQ((i == 5) ? 3 : 0, psv->ValueAt(i)); } } TEST_F(SplitVectorTest, Insertion) { psv->InsertValue(0, 10, 0); EXPECT_EQ(10, psv->Length()); for (int i=0; i<psv->Length(); i++) { EXPECT_EQ(0, psv->ValueAt(i)); } } TEST_F(SplitVectorTest, EnsureLength) { psv->EnsureLength(4); EXPECT_EQ(4, psv->Length()); for (int i=0; i<psv->Length(); i++) { EXPECT_EQ(0, psv->ValueAt(i)); } } TEST_F(SplitVectorTest, InsertFromArray) { psv->InsertFromArray(0, testArray, 0, lengthTestArray); EXPECT_EQ(lengthTestArray, psv->Length()); for (int i=0; i<psv->Length(); i++) { EXPECT_EQ(i+3, psv->ValueAt(i)); } } TEST_F(SplitVectorTest, SetValue) { psv->InsertValue(0, 10, 0); psv->SetValueAt(5, 3); EXPECT_EQ(10, psv->Length()); for (int i=0; i<psv->Length(); i++) { EXPECT_EQ((i == 5) ? 3 : 0, psv->ValueAt(i)); } // Move the gap psv->InsertValue(7, 1, 17); EXPECT_EQ(17, psv->ValueAt(7)); EXPECT_EQ(0, psv->ValueAt(8)); // Set after the gap psv->SetValueAt(8, 19); EXPECT_EQ(19, psv->ValueAt(8)); } TEST_F(SplitVectorTest, Indexing) { psv->InsertValue(0, 10, 0); psv->SetValueAt(5, 3); EXPECT_EQ(10, psv->Length()); for (int i=0; i<psv->Length(); i++) { EXPECT_EQ((i == 5) ? 3 : 0, (*psv)[i]); } } TEST_F(SplitVectorTest, Fill) { psv->InsertValue(0, 10, 0); EXPECT_EQ(10, psv->Length()); psv->InsertValue(7, 1, 1); EXPECT_EQ(11, psv->Length()); for (int i=0; i<psv->Length(); i++) { EXPECT_EQ((i == 7) ? 1 : 0, psv->ValueAt(i)); } } TEST_F(SplitVectorTest, DeleteOne) { psv->InsertFromArray(0, testArray, 0, lengthTestArray); psv->Delete(2); EXPECT_EQ(lengthTestArray-1, psv->Length()); EXPECT_EQ(3, (*psv)[0]); EXPECT_EQ(4, (*psv)[1]); EXPECT_EQ(6, (*psv)[2]); } TEST_F(SplitVectorTest, DeleteRange) { psv->InsertValue(0, 10, 0); EXPECT_EQ(10, psv->Length()); psv->InsertValue(7, 1, 1); EXPECT_EQ(11, psv->Length()); psv->DeleteRange(2, 3); EXPECT_EQ(8, psv->Length()); for (int i=0; i<psv->Length(); i++) { EXPECT_EQ((i == 4) ? 1 : 0, psv->ValueAt(i)); } } TEST_F(SplitVectorTest, DeleteAll) { psv->InsertValue(0, 10, 0); psv->InsertValue(7, 1, 1); psv->DeleteRange(2, 3); psv->DeleteAll(); EXPECT_EQ(0, psv->Length()); } TEST_F(SplitVectorTest, GetRange) { psv->InsertValue(0, 10, 0); psv->InsertValue(7, 1, 1); int retrieveArray[11] = {0}; psv->GetRange(retrieveArray, 0, 11); for (int i=0; i<psv->Length(); i++) { EXPECT_EQ((i==7) ? 1 : 0, retrieveArray[i]); } } TEST_F(SplitVectorTest, GetRangeOverGap) { psv->InsertFromArray(0, testArray, 0, lengthTestArray); EXPECT_EQ(lengthTestArray, psv->Length()); int retrieveArray[lengthTestArray] = {0}; psv->GetRange(retrieveArray, 0, lengthTestArray); for (int i=0; i<psv->Length(); i++) { EXPECT_EQ(i+3, retrieveArray[i]); } } TEST_F(SplitVectorTest, ReplaceUp) { // Replace each element by inserting and then deleting the displaced element // This should perform many moves const int testLength=105; psv->EnsureLength(testLength); for (int i=0; i<testLength; i++) psv->SetValueAt(i, i+2); EXPECT_EQ(testLength, psv->Length()); for (int i=0; i<psv->Length(); i++) { psv->InsertValue(i, 1, i+9); psv->Delete(i+1); } for (int i=0; i<psv->Length(); i++) EXPECT_EQ(i+9, psv->ValueAt(i)); } TEST_F(SplitVectorTest, ReplaceDown) { // From the end, replace each element by inserting and then deleting the displaced element // This should perform many moves const int testLength=24; psv->EnsureLength(testLength); for (int i=0; i<testLength; i++) psv->SetValueAt(i, i+12); EXPECT_EQ(testLength, psv->Length()); for (int i=psv->Length()-1; i>=0; i--) { psv->InsertValue(i, 1, i+5); psv->Delete(i+1); } for (int i=0; i<psv->Length(); i++) EXPECT_EQ(i+5, psv->ValueAt(i)); } TEST_F(SplitVectorTest, BufferPointer) { psv->InsertFromArray(0, testArray, 0, lengthTestArray); int *retrievePointer = psv->BufferPointer(); for (int i=0; i<psv->Length(); i++) { EXPECT_EQ(i+3, retrievePointer[i]); } } TEST_F(SplitVectorTest, DeleteBackAndForth) { psv->InsertValue(0, 10, 87); for (int i=0; i<10; i+=2) { int len = 10 - i; EXPECT_EQ(len, psv->Length()); for (int i=0; i<psv->Length(); i++) { EXPECT_EQ(87, psv->ValueAt(i)); } psv->Delete(len-1); psv->Delete(0); } } TEST_F(SplitVectorTest, GrowSize) { psv->SetGrowSize(5); EXPECT_EQ(5, psv->GetGrowSize()); } TEST_F(SplitVectorTest, OutsideBounds) { psv->InsertValue(0, 10, 87); EXPECT_EQ(0, psv->ValueAt(-1)); EXPECT_EQ(0, psv->ValueAt(10)); /* Could be a death test as this asserts: psv->SetValueAt(-1,98); psv->SetValueAt(10,99); EXPECT_EQ(0, psv->ValueAt(-1)); EXPECT_EQ(0, psv->ValueAt(10)); */ } |
Added test/unit/unitTest.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
// Unit Tests for Scintilla internal data structures /* Currently tested: SplitVector Partitioning RunStyles ContractionState To do: Decoration DecorationList PerLine * CellBuffer * Range StyledText CaseFolder ... Document RESearch Selection UniConversion Style lexlib: Accessor LexAccessor CharacterSet OptionSet PropSetSimple StyleContext WordList */ #include <stdio.h> #include "Platform.h" #include <gtest/gtest.h> // Needed for PLATFORM_ASSERT in code being tested void Platform::Assert(const char *c, const char *file, int line) { fprintf(stderr, "Assertion [%s] failed at %s %d\n", c, file, line); abort(); } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } |
Added test/xite.py.
> > > > > > |
1 2 3 4 5 6 |
# -*- coding: utf-8 -*- import XiteWin if __name__ == "__main__": XiteWin.main("") |
Added tgzsrc.
> > > > |
1 2 3 4 |
cd .. rm -f scintilla.tgz tar --create --exclude \*.o --exclude \*.obj --exclude \*.dll --exclude \*.exe --exclude \*.a scintilla/* \ | gzip -c >scintilla.tgz |
Added tk/DynLexer.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 |
// Scintilla source code edit control /** @file DynLexer.cxx ** Lexer for Spice, modified for dynamic loading as an example **/ // Copyright 2006 by Fabien Proriol // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <assert.h> #include <ctype.h> #include <string> #include "ILexer.h" #include "Scintilla.h" #include "SciLexer.h" #include "WordList.h" #include "LexAccessor.h" #include "Accessor.h" #include "StyleContext.h" #include "CharacterSet.h" #include "LexerModule.h" #include "PropSetSimple.h" #include "LexerBase.h" #ifdef _WIN32 #define DLLEXPORT __declspec(dllexport) #else #define DLLEXPORT /*nothing*/ #endif #ifdef SCI_NAMESPACE using namespace Scintilla; #endif /* * Interface */ static void ColouriseDocument( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler); static const char * const spiceWordListDesc[] = { "Keywords", // SPICE command "Keywords2", // SPICE functions "Keywords3", // SPICE params 0 }; // Don't define LexerModule when dynamic loading external lexer //LexerModule lmDynLexer(SCLEX_AUTOMATIC, ColouriseDocument, "dynlexer", NULL, spiceWordListDesc); /* * Implementation */ static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute); static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute); static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute); static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute); static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute); static inline bool IsDelimiterCharacter(int ch); static inline bool IsNumberStartCharacter(int ch); static inline bool IsNumberCharacter(int ch); static inline bool IsSeparatorOrDelimiterCharacter(int ch); static inline bool IsWordStartCharacter(int ch); static inline bool IsWordCharacter(int ch); static void ColouriseComment(StyleContext& sc, bool&) { sc.SetState(SCE_SPICE_COMMENTLINE); while (!sc.atLineEnd) { sc.Forward(); } } static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) { apostropheStartsAttribute = sc.Match (')'); sc.SetState(SCE_SPICE_DELIMITER); sc.ForwardSetState(SCE_SPICE_DEFAULT); } static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) { apostropheStartsAttribute = true; std::string number; sc.SetState(SCE_SPICE_NUMBER); // Get all characters up to a delimiter or a separator, including points, but excluding // double points (ranges). while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) { number += static_cast<char>(sc.ch); sc.Forward(); } // Special case: exponent with sign if ((sc.chPrev == 'e' || sc.chPrev == 'E') && (sc.ch == '+' || sc.ch == '-')) { number += static_cast<char>(sc.ch); sc.Forward (); while (!IsSeparatorOrDelimiterCharacter(sc.ch)) { number += static_cast<char>(sc.ch); sc.Forward(); } } sc.SetState(SCE_SPICE_DEFAULT); } static void ColouriseWhiteSpace(StyleContext& sc, bool& ) { sc.SetState(SCE_SPICE_DEFAULT); sc.ForwardSetState(SCE_SPICE_DEFAULT); } static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute) { apostropheStartsAttribute = true; sc.SetState(SCE_SPICE_IDENTIFIER); std::string word; while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) { word += static_cast<char>(tolower(sc.ch)); sc.Forward(); } if (keywords.InList(word.c_str())) { sc.ChangeState(SCE_SPICE_KEYWORD); if (word != "all") { apostropheStartsAttribute = false; } } else if (keywords2.InList(word.c_str())) { sc.ChangeState(SCE_SPICE_KEYWORD2); if (word != "all") { apostropheStartsAttribute = false; } } else if (keywords3.InList(word.c_str())) { sc.ChangeState(SCE_SPICE_KEYWORD3); if (word != "all") { apostropheStartsAttribute = false; } } sc.SetState(SCE_SPICE_DEFAULT); } // // ColouriseDocument // static void ColouriseDocument( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; StyleContext sc(startPos, length, initStyle, styler); int lineCurrent = styler.GetLine(startPos); bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0; while (sc.More()) { if (sc.atLineEnd) { // Go to the next line sc.Forward(); lineCurrent++; // Remember the line state for future incremental lexing styler.SetLineState(lineCurrent, apostropheStartsAttribute); // Don't continue any styles on the next line sc.SetState(SCE_SPICE_DEFAULT); } // Comments if ((sc.Match('*') && sc.atLineStart) || sc.Match('*','~')) { ColouriseComment(sc, apostropheStartsAttribute); // Whitespace } else if (IsASpace(sc.ch)) { ColouriseWhiteSpace(sc, apostropheStartsAttribute); // Delimiters } else if (IsDelimiterCharacter(sc.ch)) { ColouriseDelimiter(sc, apostropheStartsAttribute); // Numbers } else if (IsADigit(sc.ch) || sc.ch == '#') { ColouriseNumber(sc, apostropheStartsAttribute); // Keywords or identifiers } else { ColouriseWord(sc, keywords, keywords2, keywords3, apostropheStartsAttribute); } } sc.Complete(); } static inline bool IsDelimiterCharacter(int ch) { switch (ch) { case '&': case '\'': case '(': case ')': case '*': case '+': case ',': case '-': case '.': case '/': case ':': case ';': case '<': case '=': case '>': case '|': return true; default: return false; } } static inline bool IsNumberCharacter(int ch) { return IsNumberStartCharacter(ch) || ch == '_' || ch == '.' || ch == '#' || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'); } static inline bool IsNumberStartCharacter(int ch) { return IsADigit(ch); } static inline bool IsSeparatorOrDelimiterCharacter(int ch) { return IsASpace(ch) || IsDelimiterCharacter(ch); } static inline bool IsWordCharacter(int ch) { return IsWordStartCharacter(ch) || IsADigit(ch); } static inline bool IsWordStartCharacter(int ch) { return (isascii(ch) && isalpha(ch)) || ch == '_'; } class DynLexer : public LexerBase { public: DynLexer() { } void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { try { Accessor astyler(pAccess, &props); ColouriseDocument(startPos, length, initStyle, keyWordLists, astyler); astyler.Flush(); } catch (...) { // Should not throw into caller as may be compiled with different compiler or options pAccess->SetErrorStatus(SC_STATUS_FAILURE); } } void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) { try { Accessor astyler(pAccess, &props); // folding unsupported by this lexer //FoldDoc(startPos, length, initStyle, keyWordLists, astyler); astyler.Flush(); } catch (...) { // Should not throw into caller as may be compiled with different compiler or options pAccess->SetErrorStatus(SC_STATUS_FAILURE); } } static ILexer *LexerFactoryDynLexer() { try { return new DynLexer(); } catch (...) { // Should not throw into caller as may be compiled with different compiler or options return 0; } } }; /* * External Lexer "glue" functions */ extern "C" { DLLEXPORT int GetLexerCount() { // return number of lexers in this library return 1; } DLLEXPORT void GetLexerName(unsigned int Index, char *name, int buflength) { *name = 0; if (Index == 0) { if (buflength > 9) { strcpy(name, "dynlexer"); } } } DLLEXPORT LexerFactoryFunction GetLexerFactory(unsigned int index) { if (index == 0) { return DynLexer::LexerFactoryDynLexer; } else return NULL; } } |
Added tk/Makefile.in.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 |
# Makefile.in -- # # This file is a Makefile for Sample TEA Extension. If it has the name # "Makefile.in" then it is a template for a Makefile; to generate the # actual Makefile, run "./configure", which is a configuration script # generated by the "autoconf" program (constructs like "@foo@" will get # replaced in the actual Makefile. # # Copyright (c) 1999 Scriptics Corporation. # Copyright (c) 2002-2005 ActiveState Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. #======================================================================== # Add additional lines to handle any additional AC_SUBST cases that # have been added in a customized configure script. #======================================================================== #SAMPLE_NEW_VAR = @SAMPLE_NEW_VAR@ #======================================================================== # Nothing of the variables below this line should need to be changed. # Please check the TARGETS section below to make sure the make targets # are correct. #======================================================================== #======================================================================== # The names of the source files is defined in the configure script. # The object files are used for linking into the final library. # This will be used when a dist target is added to the Makefile. # It is not important to specify the directory, as long as it is the # $(srcdir) or in the generic, win or unix subdirectory. #======================================================================== LEXOBJS = $(addsuffix .$(OBJEXT),$(basename $(notdir $(wildcard $(srcdir)/../lexers/Lex*.cxx)))) SRCOBJS = $(addsuffix .$(OBJEXT),$(basename $(notdir $(wildcard $(srcdir)/../lexlib/*cxx $(srcdir)/../src/*.cxx)))) PKG_SOURCES = @PKG_SOURCES@ PKG_OBJECTS = $(SRCOBJS) @PKG_OBJECTS@ $(LEXOBJS) PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ #======================================================================== # PKG_TCL_SOURCES identifies Tcl runtime files that are associated with # this package that need to be installed, if any. #======================================================================== PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ #======================================================================== # This is a list of public header files to be installed, if any. #======================================================================== PKG_HEADERS = @PKG_HEADERS@ #======================================================================== # "PKG_LIB_FILE" refers to the library (dynamic or static as per # configuration options) composed of the named objects. #======================================================================== PKG_LIB_FILE = @PKG_LIB_FILE@ PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ lib_BINARIES = $(PKG_LIB_FILE) BINARIES = $(lib_BINARIES) DynLexer${SHLIB_SUFFIX} iface.tcl SHELL = @SHELL@ srcdir = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ libdir = @libdir@ includedir = @includedir@ datarootdir = @datarootdir@ datadir = @datadir@ mandir = @mandir@ DESTDIR = PKG_DIR = $(PACKAGE_NAME)$(PACKAGE_VERSION) pkgdatadir = $(datadir)/$(PKG_DIR) pkglibdir = $(libdir)/$(PKG_DIR) pkgincludedir = $(includedir)/$(PKG_DIR) top_builddir = . INSTALL_OPTIONS = INSTALL = $(SHELL) $(srcdir)/tclconfig/install-sh -c ${INSTALL_OPTIONS} INSTALL_DATA_DIR = ${INSTALL} -d -m 755 INSTALL_PROGRAM = ${INSTALL} -m 555 INSTALL_DATA = ${INSTALL} -m 444 INSTALL_SCRIPT = ${INSTALL_PROGRAM} INSTALL_LIBRARY = ${INSTALL_PROGRAM} PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PACKAGE_DATE = $(shell date "+%Y-%m-%d (beta)") CC = @CC@ CXX = @CXX@ CFLAGS_DEFAULT = @CFLAGS_DEFAULT@ CFLAGS_WARNING = @CFLAGS_WARNING@ EXEEXT = @EXEEXT@ LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@ MAKE_LIB = @MAKE_LIB@ MAKE_SHARED_LIB = @MAKE_SHARED_LIB@ MAKE_STATIC_LIB = @MAKE_STATIC_LIB@ MAKE_STUB_LIB = @MAKE_STUB_LIB@ OBJEXT = @OBJEXT@ RANLIB = @RANLIB@ RANLIB_STUB = @RANLIB_STUB@ SHLIB_CFLAGS = @SHLIB_CFLAGS@ SHLIB_SUFFIX = @SHLIB_SUFFIX@ SHLIB_LD = @SHLIB_LD@ SHLIB_LD_LIBS = @SHLIB_LD_LIBS@ STLIB_LD = @STLIB_LD@ TCL_DEFS = @TCL_DEFS@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_SRC_DIR = @TCL_SRC_DIR@ TK_BIN_DIR = @TK_BIN_DIR@ TK_SRC_DIR = @TK_SRC_DIR@ # Not used, but retained for reference of what libs Tcl required TCL_LIBS = @TCL_LIBS@ #======================================================================== # TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our # package without installing. The other environment variables allow us # to test against an uninstalled Tcl. Add special env vars that you # require for testing here (like TCLX_LIBRARY). #======================================================================== #EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR) EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR) TCLLIBPATH = $(top_builddir) TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` PKG_ENV = @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \ PATH="$(EXTRA_PATH):$(PATH)" \ TCLLIBPATH="$(TCLLIBPATH)" TCLSH_PROG = @TCLSH_PROG@ TCLSH = $(PKG_ENV) $(TCLSH_ENV) $(TCLSH_PROG) #WISH_ENV = TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library` #WISH_PROG = @WISH_PROG@ #WISH = $(PKG_ENV) $(TCLSH_ENV) $(WISH_ENV) $(WISH_PROG) SHARED_BUILD = @SHARED_BUILD@ #INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@ PKG_CFLAGS = @PKG_CFLAGS@ # TCL_DEFS is not strictly need here, but if you remove it, then you # must make sure that configure.in checks for the necessary components # that your library may use. TCL_DEFS can actually be a problem if # you do not compile with a similar machine setup as the Tcl core was # compiled with. #DEFS = $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS) DEFS = @DEFS@ $(PKG_CFLAGS) # Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl CLEANFILES = @CLEANFILES@ CPPFLAGS = @CPPFLAGS@ LIBS = @PKG_LIBS@ @LIBS@ AR = @AR@ CFLAGS = -DPACKAGE_DATE="\"$(PACKAGE_DATE)\"" @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) COMPILEXX = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(CXXFLAGS) .SUFFIXES: .cxx .c .$(OBJEXT) .h .a #======================================================================== # Start of user-definable TARGETS section #======================================================================== #======================================================================== # TEA TARGETS. Please note that the "libraries:" target refers to platform # independent files, and the "binaries:" target includes executable programs and # platform-dependent libraries. Modify these targets so that they install # the various pieces of your package. The make and install rules # for the BINARIES that you specified above have already been done. #======================================================================== all: binaries libraries doc examples #======================================================================== # The binaries target builds executable programs, Windows .dll's, unix # shared/static libraries, and any other platform-dependent files. # The list of targets to build for "binaries:" is specified at the top # of the Makefile, in the "BINARIES" variable. #======================================================================== binaries: $(BINARIES) libraries: examples: DynLexer${SHLIB_SUFFIX} DynLexer${SHLIB_SUFFIX}: DynLexer.$(OBJEXT) LexerBase.$(OBJEXT) Accessor.$(OBJEXT) WordList.$(OBJEXT) PropSetSimple.$(OBJEXT) rm -rf $@ os=`uname -o`; \ if test "$$os" = "Cygwin"; then \ ${SHLIB_LD} -out:$@ $^; \ else \ ${SHLIB_LD} -o $@ $^; \ fi ${RANLIB} $@ iface.tcl: Scintilla.iface echo "# constant values defined in Scintilla.iface to be used by TCL clients" > iface.tcl echo "namespace eval ScintillaTk {" >> iface.tcl grep ^val $^ | sed -e s/^val/set/ -e s/=/\ / >> iface.tcl echo "}" >> iface.tcl #======================================================================== # Your doc target should differentiate from doc builds (by the developer) # and doc installs (see install-doc), which just install the docs on the # end user machine when building from source. #======================================================================== doc: @echo "If you have documentation to create, place the commands to" @echo "build the docs in the 'doc:' target. For example:" @echo " xml2nroff sample.xml > sample.n" @echo " xml2html sample.xml > sample.html" install: all install-binaries install-libraries install-doc install-binaries: binaries install-lib-binaries install-bin-binaries #======================================================================== # This rule installs platform-independent files, such as header files. # The list=...; for p in $$list handles the empty list case x-platform. #======================================================================== install-libraries: libraries @$(INSTALL_DATA_DIR) $(DESTDIR)$(includedir) @echo "Installing header files in $(DESTDIR)$(includedir)" @list='$(PKG_HEADERS)'; for i in $$list; do \ echo "Installing $(srcdir)/$$i" ; \ $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \ done; #======================================================================== # Install documentation. Unix manpages should go in the $(mandir) # directory. #======================================================================== install-doc: doc @$(INSTALL_DATA_DIR) $(DESTDIR)$(mandir)/mann @echo "Installing documentation in $(DESTDIR)$(mandir)" @list='$(srcdir)/doc/*.n'; for i in $$list; do \ echo "Installing $$i"; \ $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \ done @$(INSTALL_DATA_DIR) $(DESTDIR)$(pkglibdir)/doc @list='$(srcdir)/doc/*.html'; for i in $$list; do \ echo "Installing $$i"; \ $(INSTALL_DATA) $$i $(DESTDIR)$(pkglibdir)/doc ; \ done @$(INSTALL_DATA_DIR) $(DESTDIR)$(pkglibdir)/doc/demos @list='$(srcdir)/doc/demos/*.tcl'; for i in $$list; do \ echo "Installing $$i"; \ $(INSTALL_DATA) $$i $(DESTDIR)$(pkglibdir)/doc/demos ; \ done test: binaries libraries $(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) shell: binaries libraries @$(TCLSH) $(SCRIPT) gdb: $(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT) VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high \ --leak-check=yes --show-reachable=yes -v valgrind: binaries libraries $(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) \ `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) valgrindshell: binaries libraries $(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT) depend: #======================================================================== # $(PKG_LIB_FILE) should be listed as part of the BINARIES variable # mentioned above. That will ensure that this target is built when you # run "make binaries". # # The $(PKG_OBJECTS) objects are created and linked into the final # library. In most cases these object files will correspond to the # source files above. #======================================================================== $(PKG_LIB_FILE): $(PKG_OBJECTS) -rm -f $(PKG_LIB_FILE) ${MAKE_LIB} $(RANLIB) $(PKG_LIB_FILE) $(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS) -rm -f $(PKG_STUB_LIB_FILE) ${MAKE_STUB_LIB} $(RANLIB_STUB) $(PKG_STUB_LIB_FILE) #======================================================================== # We need to enumerate the list of .c to .o lines here. # # In the following lines, $(srcdir) refers to the toplevel directory # containing your extension. If your sources are in a subdirectory, # you will have to modify the paths to reflect this: # # sample.$(OBJEXT): $(srcdir)/generic/sample.c # $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@ # # Setting the VPATH variable to a list of paths will cause the makefile # to look into these paths when resolving .c to .obj dependencies. # As necessary, add $(srcdir):$(srcdir)/compat:.... #======================================================================== VPATH = $(srcdir):$(srcdir)/../src:$(srcdir)/../include:$(srcdir)/../lexlib:$(srcdir)/../lexers .c.@OBJEXT@: $(COMPILE) -c `@CYGPATH@ $<` -o $@ .cxx.@OBJEXT@: $(COMPILEXX) -c `@CYGPATH@ $<` -o $@ #======================================================================== # Distribution creation # You may need to tweak this target to make it work correctly. #======================================================================== #COMPRESS = tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar COMPRESS = tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR) DIST_ROOT = /tmp/dist DIST_DIR = $(DIST_ROOT)/$(PKG_DIR) dist-clean: rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.* dist: dist-clean mkdir -p $(DIST_DIR) cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license* \ $(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \ $(DIST_DIR)/ chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4 chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in for i in $(srcdir)/*.[ch]; do \ if [ -f $$i ]; then \ cp -p $$i $(DIST_DIR)/ ; \ fi; \ done; mkdir $(DIST_DIR)/tclconfig cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \ $(DIST_DIR)/tclconfig/ chmod 664 $(DIST_DIR)/tclconfig/tcl.m4 chmod +x $(DIST_DIR)/tclconfig/install-sh list='demos doc generic library mac tests unix win'; \ for p in $$list; do \ if test -d $(srcdir)/$$p ; then \ mkdir $(DIST_DIR)/$$p; \ cp -p $(srcdir)/$$p/*.* $(DIST_DIR)/$$p/; \ fi; \ done (cd $(DIST_ROOT); $(COMPRESS);) #======================================================================== # End of user-definable section #======================================================================== #======================================================================== # Don't modify the file to clean here. Instead, set the "CLEANFILES" # variable in configure.in #======================================================================== clean: -test -z "$(BINARIES)" || rm -f $(BINARIES) -rm -f *.$(OBJEXT) core *.core -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean: clean -rm -f *.tab.c -rm -f $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log config.status #======================================================================== # Install binary object libraries. On Windows this includes both .dll and # .lib files. Because the .lib files are not explicitly listed anywhere, # we need to deduce their existence from the .dll file of the same name. # Library files go into the lib directory. # In addition, this will generate the pkgIndex.tcl # file in the install location (assuming it can find a usable tclsh shell) # # You should not have to modify this target. #======================================================================== install-lib-binaries: binaries @$(INSTALL_DATA_DIR) $(DESTDIR)$(pkglibdir) @list='$(lib_BINARIES)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \ $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p; \ stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \ if test "x$$stub" = "xstub"; then \ echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \ $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \ else \ echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \ $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \ fi; \ ext=`echo $$p|sed -e "s/.*\.//"`; \ if test "x$$ext" = "xdll"; then \ lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \ if test -f $$lib; then \ echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \ $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \ fi; \ fi; \ fi; \ done @list='$(PKG_TCL_SOURCES)'; for p in $$list; do \ if test -f $(srcdir)/$$p; then \ destp=`basename $$p`; \ echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \ fi; \ done @if test "x$(SHARED_BUILD)" = "x1"; then \ echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \ $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \ fi $(INSTALL_DATA) iface.tcl $(DESTDIR)$(pkglibdir); \ #======================================================================== # Install binary executables (e.g. .exe files and dependent .dll files) # This is for files that must go in the bin directory (located next to # wish and tclsh), like dependent .dll files on Windows. # # You should not have to modify this target, except to define bin_BINARIES # above if necessary. #======================================================================== install-bin-binaries: binaries @$(INSTALL_DATA_DIR) $(DESTDIR)$(bindir) @list='$(bin_BINARIES)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \ fi; \ done Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status uninstall-binaries: list='$(lib_BINARIES)'; for p in $$list; do \ rm -f $(DESTDIR)$(pkglibdir)/$$p; \ done list='$(PKG_TCL_SOURCES)'; for p in $$list; do \ p=`basename $$p`; \ rm -f $(DESTDIR)$(pkglibdir)/$$p; \ done list='$(bin_BINARIES)'; for p in $$list; do \ rm -f $(DESTDIR)$(bindir)/$$p; \ done .PHONY: all binaries clean depend distclean doc install libraries test # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: |
Added tk/PlatTK.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 |
// Scintilla source code edit control // PlatTK.cxx - implementation of platform facilities on Linux using Tk // Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. // Copyright (c) 2013 Mentor Graphics Corporation // The license.terms file describes the conditions under which this software may be distributed. #include <string.h> #include <stdio.h> #include <stdlib.h> #include <stddef.h> #include <math.h> #include <vector> #include <map> #ifdef _WIN32 #include <windows.h> #endif #include <tk.h> #ifdef SCI_LEXER #ifndef _WIN32 /* we include tclInt.h to pick up the definition of TclpFindSymbol. This doesn't work * on Windows because the symbol isn't exported. */ extern "C" { #include <tclInt.h> } #endif // dynamic loader also requires interpreter extern Tcl_Interp *scintilla_interp; #endif #include "Platform.h" #include "Scintilla.h" #include "ScintillaWidget.h" #include "UniConversion.h" #include "XPM.h" #include "scintilla-ext.h" using namespace TkSciExt; /* Use fast way of getting char data on win32 to work around problems with gdk_string_extents. */ #define FAST_WAY #define USE_LOCK 0 #define DISABLE_GDK_FONT #ifdef SCI_NAMESPACE using namespace Scintilla; #endif enum encodingType { singleByte, UTF8, dbcs}; #ifdef SCI_NAMESPACE namespace Scintilla { #endif #if USE_LOCK static GMutex *fontMutex = NULL; static void InitializeGLIBThreads() { if (!g_thread_supported()) { g_thread_init(NULL); } } #endif static void FontMutexAllocate() { #if USE_LOCK if (!fontMutex) { InitializeGLIBThreads(); fontMutex = g_mutex_new(); } #endif } static void FontMutexFree() { #if USE_LOCK if (fontMutex) { g_mutex_free(fontMutex); fontMutex = NULL; } #endif } static void FontMutexLock() { #if USE_LOCK g_mutex_lock(fontMutex); #endif } static void FontMutexUnlock() { #if USE_LOCK if (fontMutex) { g_mutex_unlock(fontMutex); } #endif } // The following will encapsulate the platform-specific font class FontHandle { int width[128]; encodingType et; public: Tk_Font tkfont; int characterSet; FontHandle(Tk_Font tkfont_) { et = singleByte; tkfont = tkfont_; characterSet = -1; ResetWidths(et); } ~FontHandle() { Tk_FreeFont(tkfont); } void ResetWidths(encodingType et_) { et = et_; for (int i=0; i<=127; i++) { width[i] = 0; } } int CharWidth(unsigned char ch, encodingType et_) { int w = 0; FontMutexLock(); if ((ch <= 127) && (et == et_)) { w = width[ch]; } FontMutexUnlock(); return w; } void SetCharWidth(unsigned char ch, int w, encodingType et_) { if (ch <= 127) { FontMutexLock(); if (et != et_) { ResetWidths(et_); } width[ch] = w; FontMutexUnlock(); } } }; // X has a 16 bit coordinate space, so stop drawing here to avoid wrapping static const int maxCoordinate = 32000; static FontHandle *PFont(Font &f) { return reinterpret_cast<FontHandle *>(f.GetID()); } /////////////////////////////////////////////////////////// // CLASS: SurfaceImpl /////////////////////////////////////////////////////////// class SurfaceImpl : public Surface { encodingType et; Tk_Window tkwin; Tcl_Interp *interp; ScintillaObject *sc_obj; Display *display; GC gc; GC copyGC; Pixmap pixmap; int x; int y; bool inited; bool mainWindow; // TRUE if this is the main(client) window int mainWidth; int mainHeight; int characterSet; void SetConverter(int characterSet_); void FreeGC(); public: SurfaceImpl(); virtual ~SurfaceImpl(); void Init(WindowID wid); void Init(SurfaceID sid, WindowID wid); void InitPixMap(int width, int height, Surface *surface_, WindowID wid); void Release(); bool Initialised(); void PenColour(ColourDesired fore); int LogPixelsY(); int DeviceHeightFont(int points); void MoveTo(int x_, int y_); void LineTo(int x_, int y_); void Polygon(Point *pts, int npts, ColourDesired fore, ColourDesired back); void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back); void FillRectangle(PRectangle rc, ColourDesired back); void FillRectangle(PRectangle rc, Surface &surfacePattern); void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back); void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, ColourDesired outline, int alphaOutline, int flags); void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage); void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back); void Copy(PRectangle rc, Point from, Surface &surfaceSource); void DrawTextBase(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore); void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back); void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back); void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore); void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions); XYPOSITION WidthText(Font &font_, const char *s, int len); XYPOSITION WidthChar(Font &font_, char ch); XYPOSITION Ascent(Font &font_); XYPOSITION Descent(Font &font_); XYPOSITION InternalLeading(Font &font_); XYPOSITION ExternalLeading(Font &font_); XYPOSITION Height(Font &font_); XYPOSITION AverageCharWidth(Font &font_); void SetClip(PRectangle rc); void FlushCachedState(); void SetUnicodeMode(bool unicodeMode_); void SetDBCSMode(int codePage); }; #ifdef SCI_NAMESPACE } #endif const char *CharacterSetID(int characterSet) { switch (characterSet) { case SC_CHARSET_ANSI: return ""; case SC_CHARSET_DEFAULT: return "ISO-8859-1"; case SC_CHARSET_BALTIC: return "ISO-8859-13"; case SC_CHARSET_CHINESEBIG5: return "BIG-5"; case SC_CHARSET_EASTEUROPE: return "ISO-8859-2"; case SC_CHARSET_GB2312: return "CP936"; case SC_CHARSET_GREEK: return "ISO-8859-7"; case SC_CHARSET_HANGUL: return "CP949"; case SC_CHARSET_MAC: return "MACINTOSH"; case SC_CHARSET_OEM: return "ASCII"; case SC_CHARSET_RUSSIAN: return "KOI8-R"; case SC_CHARSET_CYRILLIC: return "CP1251"; case SC_CHARSET_SHIFTJIS: return "SHIFT-JIS"; case SC_CHARSET_SYMBOL: return ""; case SC_CHARSET_TURKISH: return "ISO-8859-9"; case SC_CHARSET_JOHAB: return "CP1361"; case SC_CHARSET_HEBREW: return "ISO-8859-8"; case SC_CHARSET_ARABIC: return "ISO-8859-6"; case SC_CHARSET_VIETNAMESE: return ""; case SC_CHARSET_THAI: return "ISO-8859-11"; case SC_CHARSET_8859_15: return "ISO-8859-15"; default: return ""; } } void SurfaceImpl::SetConverter(int characterSet_) { // if (characterSet != characterSet_) { // characterSet = characterSet_; // conv.Open("UTF-8", CharacterSetID(characterSet), false); // } } SurfaceImpl::SurfaceImpl() : et(singleByte), sc_obj(0), display(0), gc(0), copyGC(0), pixmap(0), x(0), y(0), inited(false), mainWindow(false),mainWidth(0),mainHeight(0), characterSet(-1) { } SurfaceImpl::~SurfaceImpl() { //printf("Surface DTOR(main=%d) -- THIS=%p\n",mainWindow,(void *)this); FreeGC(); if (pixmap && display) { Tk_FreePixmap(display, pixmap); } } /* *---------------------------------------------------------------------- * Release -- * * Handles releases resources used by this surface * * Results: * None * * Side affects: * Resources releases and flags are reset * *---------------------------------------------------------------------- */ void SurfaceImpl::Release() { #if 0 et = singleByte; //printf("---RELEASE(main=%d) %p\n",mainWindow,(void *)this); //_print_trace(1); FreeGC(); if (pixmap && display) { Tk_FreePixmap(display, pixmap); pixmap = 0; } #endif characterSet = -1; x = 0; y = 0; inited = false; } void SurfaceImpl::FreeGC() { if (gc) { //printf("FreeGC (%p) >>> %d\n",(void *)this,gc); Tk_FreeGC(display, gc); gc = 0; } } bool SurfaceImpl::Initialised() { //printf("SurfaceImpl::Initialised THIS=%p inited=%d pixmap=%d\n",(void *)this,inited,(int)pixmap); return (inited && (pixmap != 0)); } static Tk_Window _curr_tkwin = 0; /* *---------------------------------------------------------------------- * Init -- * * Called by Editor to get the drawing pixmap for one of the internal * surfaces initialized. * * Results: * None * * Side affects: * Creates drawing pixmap with requested dimensions * *---------------------------------------------------------------------- */ void SurfaceImpl::Init(WindowID wid) { PLATFORM_ASSERT(wid); sc_obj = reinterpret_cast<ScintillaObject *>(wid); mainWindow = sc_obj->main; //printf("SurfaceImpl::Init(main=%d) THIS=%p WID=%p\n",mainWindow,(void *)this,(void *)wid); if (!mainWindow) { Release(); } tkwin = sc_obj->tkwin; //TODO: figure how to avoid needed the next line!!!! _curr_tkwin = tkwin; interp = Tk_Interp(tkwin); display = Tk_Display(tkwin); if (mainWindow && Tk_WindowId(tkwin)) { int new_w = Tk_Width(tkwin); int new_h = Tk_Height(tkwin); if ((new_w != mainWidth) || (new_h != mainHeight)) { if (pixmap) Tk_FreePixmap(display, pixmap); pixmap = Tk_GetPixmap(display, Tk_WindowId(tkwin), new_w, new_h, Tk_Depth(tkwin)); mainWidth = new_w; mainHeight = new_h; //printf("SurfaceImpl::Init THIS=%p WID=%p PIXMAP=%d WIDTH=%d HEIGHT=%d\n",(void *)this,(void *)wid,(int)pixmap,Tk_Width(tkwin),Tk_Height(tkwin)); } } inited = true; } void SurfaceImpl::Init(SurfaceID sid, WindowID wid) { // it's not clear why we need to support this API, but since we're // required to implement it, just call the simple version Init(wid); } /* *---------------------------------------------------------------------- * InitPixMap -- * * Called by Editor to get the drawing pixmap for one of the internal * surfaces initialized. The surface which is passed in corresponds * to the main(client) window. * * Results: * None * * Side affects: * Creates drawing pixmap with requested dimensions * *---------------------------------------------------------------------- */ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID wid) { PLATFORM_ASSERT(surface_); sc_obj = reinterpret_cast<ScintillaObject *>(wid); Release(); SurfaceImpl *surfImpl = static_cast<SurfaceImpl *>(surface_); //printf("INIT PIXMAP(main=%d, wid=%p): THIS=%p SRC=%p width=%d height=%d\n",sc_obj->main,(void *)wid,(void *)this,(void *)surfImpl,width,height); if (height > 0 && width > 0) { if (pixmap) Tk_FreePixmap(Tk_Display(tkwin), pixmap); pixmap = Tk_GetPixmap( surfImpl->display, Tk_WindowId(surfImpl->tkwin), width, height, Tk_Depth(surfImpl->tkwin) ); //printf("---InitPixMap: THIS=%p SRC=%p width=%d height=%d PIX=%d\n",(void *)this,(void *)surfImpl,width,height,(int)pixmap); } #if 1 tkwin = sc_obj->tkwin; interp = Tk_Interp(tkwin); display = Tk_Display(tkwin); inited = true; #else if ( ! Initialised() ) { Init(wid); } #endif } /* *---------------------------------------------------------------------- * PenColour -- * * Called prior to drawing operation to set a specified color * * Results: * None * * Side affects: * A GC is obtained (Tk is allowed to reuse) with the specified * color defined for the foreground. * *---------------------------------------------------------------------- */ void SurfaceImpl::PenColour(ColourDesired fore) { FreeGC(); XGCValues gcvalues; XColor *xc; static char rgb[7]; sprintf(rgb, "#%02x%02x%02x", fore.GetRed(), fore.GetGreen(), fore.GetBlue()); xc = Tk_GetColor(interp, tkwin, rgb); if (xc) { gcvalues.foreground = xc->pixel; gc = Tk_GetGC(tkwin, GCForeground, &gcvalues); //printf("PenColour ####### SET GC = %ld for THIS=%p RGB=%d,%d,%d\n",(long)gc,(void *)this,fore.GetRed(),fore.GetGreen(),fore.GetBlue()); Tk_FreeColor(xc); } } int SurfaceImpl::LogPixelsY() { return 72; } int SurfaceImpl::DeviceHeightFont(int points) { int logPix = LogPixelsY(); return (points * logPix + logPix / 2) / 72; } void SurfaceImpl::MoveTo(int x_, int y_) { //printf("MOVETO: %d,%d\n",x_,y_); x = x_; y = y_; } void SurfaceImpl::LineTo(int x_, int y_) { if (gc) { //printf("LINETO: %d,%d -> %d,%d\n",x_,y_,x,y); XDrawLine( display, pixmap, gc, x_, y_, x, y ); } x = x_; y = y_; } void SurfaceImpl::Polygon(Point *pts, int npts, ColourDesired fore, ColourDesired back) { #if 0 printf("SurfaceImpl::Polygon BG=%d,%d,%d FG=%d,%d,%d\n", back.GetRed(),back.GetGreen(),back.GetBlue(), fore.GetRed(),fore.GetGreen(),fore.GetBlue()); #endif XPoint points[20]; if (npts < static_cast<int>((sizeof(points) / sizeof(points[0])))) { int i; int _x = 0; int _y = 0; for (i = 0;i < npts;i++) { if (i==0) { _x = pts[i].x; _y = pts[i].y; } points[i].x = static_cast<short>(pts[i].x); points[i].y = static_cast<short>(pts[i].y); } // add the closing coordinate points[i].x = _x; points[i].y = _y; npts++; PenColour(back); XFillPolygon(display, pixmap, gc, points, npts, Convex, CoordModeOrigin); PenColour(fore); XDrawLines(display, pixmap, gc, points, npts, CoordModeOrigin); } } void SurfaceImpl::RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) { #if 0 printf("##################################\n"); printf("# SurfaceImpl::RectangleDraw\n"); printf("# FORE=%d,%d,%d", fore.GetRed(),fore.GetGreen(),fore.GetBlue()); printf(" BACK=%d,%d,%d\n",back.GetRed(),back.GetGreen(),back.GetBlue()); printf("##################################\n"); #endif int x = rc.left; int y = rc.top; int w = (rc.right - rc.left); int h = (rc.bottom - rc.top); PenColour(back); XDrawRectangle(display, pixmap, gc, x + 1, y + 1, w - 2, h - 2); PenColour(fore); // The subtraction of 1 off the width and height here shouldn't be needed but // otherwise a different rectangle is drawn than would be done if the fill // parameter == 1 XDrawRectangle(display, pixmap, gc, x, y, w - 1, h -1); } void SurfaceImpl::FillRectangle(PRectangle rc, ColourDesired back) { #if 0 if ((rc.right-rc.left)>1 && (rc.bottom-rc.top)>1) printf("\nFILL RECT1 RGB=%d,%d,%d THIS=%p|PIX=%d|GC=%ld|+%d+%dx%dx%d\n", back.GetRed(),back.GetGreen(),back.GetBlue(), (void *)this,(int)pixmap,(long)gc, rc.left,rc.top,(rc.right-rc.left),(rc.bottom-rc.top)); #endif PenColour(back); if (gc && (rc.left < maxCoordinate)) { // Protect against out of range ////////////////////// //-------CHANGE TO : Tk_Fill3DRectangle --- use Tk_3DBorder bool to_screen = false; if (to_screen) { XFillRectangle(display, Tk_WindowId(tkwin), gc, rc.left, rc.top, (rc.right - rc.left), (rc.bottom - rc.top)); Tcl_DoOneEvent(2); //DRAW NOW!!!! } else { XFillRectangle(display, pixmap, gc, rc.left, rc.top, (rc.right - rc.left), (rc.bottom - rc.top)); } } } void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) { //printf("SurfaceImpl::FillRectangle 2 THIS=%p\n",(void *)this); SurfaceImpl &surfOther = static_cast<SurfaceImpl &>(surfacePattern); if (Initialised() && surfOther.Initialised()) { // Tile pattern over rectangle // Currently assumes 8x8 pattern int widthPat = 8; int heightPat = 8; for (int xTile = rc.left; xTile < rc.right; xTile += widthPat) { int widthx = (xTile + widthPat > rc.right) ? rc.right - xTile : widthPat; for (int yTile = rc.top; yTile < rc.bottom; yTile += heightPat) { int heighty = (yTile + heightPat > rc.bottom) ? rc.bottom - yTile : heightPat; if (!gc) { XGCValues gcValues; // just use defaults gc = Tk_GetGC(tkwin, GCGraphicsExposures, &gcValues); } XCopyArea(display, surfOther.pixmap, pixmap, gc, 0, 0, /* src X/Y */ widthx, heighty, xTile, yTile /* dest X/Y */ ); } } } else { // Something is wrong so try to show anyway // Shows up black because colour not allocated FillRectangle(rc, ColourDesired(0)); } } void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back) { if (((rc.right - rc.left) > 4) && ((rc.bottom - rc.top) > 4)) { // Approximate a round rect with some cut off corners Point pts[] = { Point(rc.left + 2, rc.top), Point(rc.right - 2, rc.top), Point(rc.right, rc.top + 2), Point(rc.right, rc.bottom - 3), Point(rc.right - 3, rc.bottom), Point(rc.left + 3, rc.bottom), Point(rc.left, rc.bottom - 3), Point(rc.left, rc.top + 2), }; Polygon(pts, sizeof(pts) / sizeof(pts[0]), fore, back); } else { RectangleDraw(rc, fore, back); } } void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, ColourDesired outline, int alphaOutline, int flags) { #if 1 // TEMPORARY HACK - the assumption is this will be called to draw one of the // indicators that would normally try to create a translucent interior if (cornerSize == 0) FillRectangle(rc, fill); else RoundedRectangle(rc, fill, fill); return; #endif fprintf(stderr, "WARNING: The AlphaRectangle Surface function has not been implemented!!\n"); #if TK_CAN_DO_TRANSPARENCY if (gc && drawable && rc.Width() > 0) { int width = rc.Width(); int height = rc.Height(); // Ensure not distorted too much by corners when small cornerSize = Platform::Minimum(cornerSize, (Platform::Minimum(width, height) / 2) - 2); // Make a 32 bit deep pixbuf with alpha GdkPixbuf *pixalpha = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height); guint32 valEmpty = u32FromRGBA(0,0,0,0); guint32 valFill = u32FromRGBA(GetRValue(fill.AsLong()), GetGValue(fill.AsLong()), GetBValue(fill.AsLong()), alphaFill); guint32 valOutline = u32FromRGBA(GetRValue(outline.AsLong()), GetGValue(outline.AsLong()), GetBValue(outline.AsLong()), alphaOutline); guint32 *pixels = reinterpret_cast<guint32 *>(gdk_pixbuf_get_pixels(pixalpha)); int stride = gdk_pixbuf_get_rowstride(pixalpha) / 4; for (int yr=0; yr<height; yr++) { for (int xr=0; xr<width; xr++) { if ((xr==0) || (xr==width-1) || (yr == 0) || (yr == height-1)) { pixels[yr*stride+xr] = valOutline; } else { pixels[yr*stride+xr] = valFill; } } } for (int c=0;c<cornerSize; c++) { for (int xr=0;xr<c+1; xr++) { AllFour(pixels, stride, width, height, xr, c-xr, valEmpty); } } for (int xr=1;xr<cornerSize; xr++) { AllFour(pixels, stride, width, height, xr, cornerSize-xr, valOutline); } // Draw with alpha gdk_draw_pixbuf(drawable, gc, pixalpha, 0,0, rc.left,rc.top, width,height, GDK_RGB_DITHER_NORMAL, 0, 0); g_object_unref(pixalpha); } #endif } void SurfaceImpl::DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) { fprintf(stderr, "WARNING: The DrawRGBAImage Surface function has not been implemented!!\n"); #if TK_CAN_DO_TRANSPARENCY if (rc.Width() > width) rc.left += (rc.Width() - width) / 2; rc.right = rc.left + width; if (rc.Height() > height) rc.top += (rc.Height() - height) / 2; rc.bottom = rc.top + height; GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(pixelsImage, GDK_COLORSPACE_RGB, TRUE, 8, width, height, width * 4, NULL, NULL); gdk_draw_pixbuf(drawable, gc, pixbuf, 0,0, rc.left,rc.top, width,height, GDK_RGB_DITHER_NORMAL, 0, 0); g_object_unref(pixbuf); #endif } void SurfaceImpl::Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) { static int full_circle = 64 * 360; PenColour(back); XFillArc(display, pixmap, gc, rc.left + 1, rc.top + 1, rc.right - rc.left - 2, rc.bottom - rc.top - 2, 0, full_circle); // The subtraction of 1 here is similar to the case for RectangleDraw PenColour(fore); XDrawArc(display, pixmap, gc, rc.left, rc.top, rc.right - rc.left - 1, rc.bottom - rc.top - 1, 0, full_circle); } /**************************************************************** // Func: Copy // Desc: Called from Editor code to copy a region from a source // surface to the screen as a result of a paint action *****************************************************************/ //int cnt = 0; void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) { bool to_screen; GC _gc; SurfaceImpl &surfOther = static_cast<SurfaceImpl &>(surfaceSource); //printf("\nSurfaceImpl::Copy THIS=%p<%d> OTHER=%p<%d>\n",(void *)this,(int)pixmap,(void *)&surfOther,(int)surfOther.pixmap); if (!Initialised() || !surfOther.Initialised()) { return; } to_screen = (surfOther.pixmap == pixmap); if (to_screen) { if (!copyGC) { XGCValues gcValues; gcValues.graphics_exposures = True; copyGC = Tk_GetGC(tkwin, GCGraphicsExposures, &gcValues); } _gc = copyGC; } else { _gc = surfOther.gc; } // cnt++; if (to_screen) { TkSciExt::SetPixmap((ClientData)sc_obj->client, pixmap); //printf(">>>>>XCopyArea %d FROM %02d %02d SCREEN +%02d+%02dx%dx%d \n",cnt, from.x, from.y,rc.left,rc.top,(rc.right-rc.left),(rc.bottom-rc.top)); XCopyArea(display,surfOther.pixmap,Tk_WindowId(tkwin),_gc,rc.left, rc.top,rc.right - rc.left, rc.bottom - rc.top,rc.left, rc.top); } else { //printf(">>>>>XCopyArea %d FROM %02d %02d BUFFER +%02d+%02dx%dx%d \n",cnt, from.x, from.y, rc.left,rc.top,(rc.right-rc.left),(rc.bottom-rc.top)); XCopyArea(display,surfOther.pixmap, pixmap, _gc,from.x, from.y,rc.right - rc.left, rc.bottom - rc.top, rc.left, rc.top); } } char *UTF8FromLatin1(const char *s, int &len) { char *utfForm = new char[len*2+1]; size_t lenU = 0; for (int i=0;i<len;i++) { unsigned int uch = static_cast<unsigned char>(s[i]); if (uch < 0x80) { utfForm[lenU++] = uch; } else { utfForm[lenU++] = static_cast<char>(0xC0 | (uch >> 6)); utfForm[lenU++] = static_cast<char>(0x80 | (uch & 0x3f)); } } utfForm[lenU] = '\0'; len = lenU; return utfForm; } void SurfaceImpl::DrawTextBase( PRectangle rc, Scintilla::Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore ) { //printf("DRAW TEXT(%d): @%d,%d THIS=%p pixmap=%d GC=%ld STR=%s\n",len,rc.left,ybase,(void *)this,(int)pixmap,(long)gc,s); PenColour(fore); if (pixmap && gc && PFont(font_)) { Tk_Font tkfont = PFont(font_)->tkfont; #ifdef _WIN32 gc->font = (unsigned long)tkfont; #endif Tk_DrawChars(display, pixmap, gc, tkfont, s, len, rc.left, ybase); } else { //printf("DRAW TEXT ############### SKIPPED pixmap=%d gc=%ld\n",(int)pixmap,(long)gc); } } void SurfaceImpl::DrawTextNoClip(PRectangle rc, Scintilla::Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) { FillRectangle(rc, back); DrawTextBase(rc, font_, ybase, s, len, fore); } // On GTK+, exactly same as DrawTextNoClip void SurfaceImpl::DrawTextClipped(PRectangle rc, Scintilla::Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) { FillRectangle(rc, back); DrawTextBase(rc, font_, ybase, s, len, fore); } void SurfaceImpl::DrawTextTransparent(PRectangle rc, Scintilla::Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore) { // Avoid drawing spaces in transparent mode for (int i=0;i<len;i++) { if (s[i] != ' ') { DrawTextBase(rc, font_, ybase, s, len, fore); return; } } } void SurfaceImpl::MeasureWidths(Scintilla::Font &font_, const char *s, int len, XYPOSITION *positions) { if (font_.GetID()) { Tk_Font tkfont = PFont(font_)->tkfont; int totalWidth = 0; for (int i = 0; i < len; i++) { int width = Tk_TextWidth(tkfont, (s+i), 1); totalWidth += width; positions[i] = totalWidth; } } else { // No font so return an ascending range of values for (int i = 0; i < len; i++) { positions[i] = i + 1; } } } XYPOSITION SurfaceImpl::WidthText(Scintilla::Font &font_, const char *s, int len) { if (font_.GetID()) { return Tk_TextWidth(PFont(font_)->tkfont, s, len); } else { return 10; } } XYPOSITION SurfaceImpl::WidthChar(Scintilla::Font &font_, char ch) { return WidthText(font_, &ch, 1); } // Ascent and descent determined by Pango font metrics. XYPOSITION SurfaceImpl::Ascent(Scintilla::Font &font_) { if (!(font_.GetID())) { return 1; } Tk_FontMetrics fm; Tk_GetFontMetrics(PFont(font_)->tkfont, &fm); return fm.ascent; } XYPOSITION SurfaceImpl::Descent(Scintilla::Font &font_) { if (!(font_.GetID())) return 1; Tk_FontMetrics fm; Tk_GetFontMetrics(PFont(font_)->tkfont, &fm); return fm.descent; } XYPOSITION SurfaceImpl::InternalLeading(Scintilla::Font &) { return 0; } XYPOSITION SurfaceImpl::ExternalLeading(Scintilla::Font &) { return 0; } XYPOSITION SurfaceImpl::Height(Scintilla::Font &font_) { return Ascent(font_) + Descent(font_); } XYPOSITION SurfaceImpl::AverageCharWidth(Scintilla::Font &font_) { return WidthChar(font_, 'n'); } void SurfaceImpl::SetClip(PRectangle rc) { //TODO: is this something that needs to be implemented?? } void SurfaceImpl::FlushCachedState() {} void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) { if (unicodeMode_) et = UTF8; } void SurfaceImpl::SetDBCSMode(int codePage) { if (codePage && (codePage != SC_CP_UTF8)) et = dbcs; } // The editor code calls this static function to get a surface object Surface *Surface::Allocate(int) { Surface *surf = new SurfaceImpl(); //printf("Surface::Allocate -- THIS=%p\n",(void *)surf); return surf; } #ifdef SCI_LEXER /* we can't get TclpFindSymbol from the TCL library because it's not exported. The following is a copy of the code */ #ifdef _WIN32 /* *---------------------------------------------------------------------- * * TclpFindSymbol -- * * Looks up a symbol, by name, through a handle associated with a * previously loaded piece of code (shared library). * * Results: * Returns a pointer to the function associated with 'symbol' if it is * found. Otherwise returns NULL and may leave an error message in the * interp's result. * *---------------------------------------------------------------------- */ Tcl_PackageInitProc * TclpFindSymbol( Tcl_Interp *interp, Tcl_LoadHandle loadHandle, CONST char *symbol) { Tcl_PackageInitProc *proc = NULL; HINSTANCE handle = (HINSTANCE)loadHandle; /* * For each symbol, check for both Symbol and _Symbol, since Borland * generates C symbols with a leading '_' by default. */ proc = (Tcl_PackageInitProc *) GetProcAddress(handle, symbol); if (proc == NULL) { Tcl_DString ds; Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, "_", 1); symbol = Tcl_DStringAppend(&ds, symbol, -1); proc = (Tcl_PackageInitProc *) GetProcAddress(handle, symbol); Tcl_DStringFree(&ds); } return proc; } #endif class DynamicLibraryImpl : public DynamicLibrary { protected: Tcl_LoadHandle handle; Tcl_FSUnloadFileProc *unloadProc; public: DynamicLibraryImpl(const char *modulePath) { // convert modulePath to Tcl_Obj Tcl_Obj *pathPtr = Tcl_NewStringObj(modulePath, strlen(modulePath)); Tcl_PackageInitProc *unused; Tcl_IncrRefCount(pathPtr); if (Tcl_FSLoadFile(scintilla_interp, pathPtr, "unused1", "unused2", &unused, &unused, &handle, &unloadProc) != TCL_OK) { fprintf(stderr,"File load of %s failed %s\n", modulePath, Tcl_GetStringResult(scintilla_interp)); handle = NULL; } Tcl_DecrRefCount(pathPtr); } virtual ~DynamicLibraryImpl() { } // Use g_module_symbol to get a pointer to the relevant function. virtual Function FindFunction(const char *name) { if (handle != NULL) { void *ptr = (void*) TclpFindSymbol(scintilla_interp, handle, name); if (ptr) { return ptr; } else return NULL; } else return NULL; } virtual bool IsValid() { return handle != NULL; } }; DynamicLibrary *DynamicLibrary::Load(const char *modulePath) { return static_cast<DynamicLibrary *>( new DynamicLibraryImpl(modulePath) ); } #endif ColourDesired Platform::Chrome() { return ColourDesired(0xe0, 0xe0, 0xe0); } ColourDesired Platform::ChromeHighlight() { return ColourDesired(0x00, 0x00, 0xff); // return ColourDesired(0xff, 0xff, 0xff); } const char *Platform::DefaultFont() { return "courier"; } int Platform::DefaultFontSize() { return 12; } unsigned int Platform::DoubleClickTime() { return 500; // Half a second } bool Platform::MouseButtonBounce() { return true; } void Platform::DebugDisplay(const char *s) { fprintf(stderr, "%s", s); } bool Platform::IsKeyDown(int) { // TODO: discover state of keys in GTK+/X return false; } long Platform::SendScintilla( WindowID w, unsigned int msg, unsigned long wParam, long lParam) { return 0;//scintilla_send_message(SCINTILLA(w), msg, wParam, lParam); } long Platform::SendScintillaPointer( WindowID w, unsigned int msg, unsigned long wParam, void *lParam) { return 0; // return scintilla_send_message(SCINTILLA(w), msg, wParam, // reinterpret_cast<sptr_t>(lParam)); } bool Platform::IsDBCSLeadByte(int codePage, char ch) { // Byte ranges found in Wikipedia articles with relevant search strings in each case unsigned char uch = static_cast<unsigned char>(ch); switch (codePage) { case 932: // Shift_jis return ((uch >= 0x81) && (uch <= 0x9F)) || ((uch >= 0xE0) && (uch <= 0xFC)); // Lead bytes F0 to FC may be a Microsoft addition. case 936: // GBK return (uch >= 0x81) && (uch <= 0xFE); case 950: // Big5 return (uch >= 0x81) && (uch <= 0xFE); // Korean EUC-KR may be code page 949. } return false; } int Platform::DBCSCharLength(int codePage, const char *s) { if (codePage == 932 || codePage == 936 || codePage == 950) { return IsDBCSLeadByte(codePage, s[0]) ? 2 : 1; } else { int bytes = mblen(s, MB_CUR_MAX); if (bytes >= 1) return bytes; else return 1; } } int Platform::DBCSCharMaxLength() { return MB_CUR_MAX; //return 2; } // These are utility functions not really tied to a platform int Platform::Minimum(int a, int b) { if (a < b) return a; else return b; } int Platform::Maximum(int a, int b) { if (a > b) return a; else return b; } //#define TRACE #ifdef TRACE void Platform::DebugPrintf(const char *format, ...) { char buffer[2000]; va_list pArguments; va_start(pArguments, format); vsprintf(buffer, format, pArguments); va_end(pArguments); Platform::DebugDisplay(buffer); } #else void Platform::DebugPrintf(const char *, ...) {} #endif // Not supported for GTK+ static bool assertionPopUps = true; bool Platform::ShowAssertionPopUps(bool assertionPopUps_) { bool ret = assertionPopUps; assertionPopUps = assertionPopUps_; return ret; } void Platform::Assert(const char *c, const char *file, int line) { char buffer[2000]; sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line); strcat(buffer, "\r\n"); Platform::DebugDisplay(buffer); abort(); } int Platform::Clamp(int val, int minVal, int maxVal) { if (val > maxVal) val = maxVal; if (val < minVal) val = minVal; return val; } void Platform_Initialise() { FontMutexAllocate(); } void Platform_Finalise() { FontMutexFree(); } #ifdef SCI_NAMESPACE namespace Scintilla { #endif //========================================================================== // CLASS Menu implementations (that seem to be needed from based class // to get symbols to resolve during library loading) // Menu::Menu() : mid(0) {} void Menu::Destroy() { } void Menu::CreatePopUp() { } void Menu::Show(Point pt, Window &) { } //========================================================================== // CLASS Font implementation (also seemingly required) // Font::Font() : fid(0) {} Font::~Font() {} void Font::Create(const FontParameters &fp) { //fprintf(stderr,"Font::Create ((%p))--> %s / %f / %d / italic=%d\n",(void *)this,fp.faceName,fp.size,fp.weight,fp.italic); //TODO: NEED THE tkwin REFERENCE FOR THIS!! //TODO: FIGURE OUT HOW TO SPECIFY THE Tk_Font BASED FROM FontParameters //NOTE: The FontParameters gets family/size from Platform::DefaultFont // and Platform::DefaultFontSize // check if the point size is encoded to represent a negative value, which // for Tk would mean it will use that value as the number of pixels. int ptsize = static_cast<int>(fp.size); if (ptsize > MAGIC_FONT_OFFSET) ptsize = (MAGIC_FONT_OFFSET - ptsize); //######################################################## // Font format: <family name> ?pt size? ?bold? ?italic? //######################################################## #if (TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION < 5) Tcl_Obj *objPtr = Tcl_NewObj(); char dbuf[64]; sprintf(dbuf," %d", ptsize); Tcl_AppendStringsToObj(objPtr,"{", fp.faceName, "}", dbuf, (char*)NULL); #else Tcl_Obj *objPtr = Tcl_ObjPrintf("{%s} %d", fp.faceName, ptsize); #endif if (fp.weight == SC_WEIGHT_BOLD) { Tcl_AppendStringsToObj(objPtr, " bold", (char *)NULL); } if (fp.italic) { Tcl_AppendStringsToObj(objPtr, " italic", (char *)NULL); } Tk_Font tkf = Tk_GetFont(Tk_Interp(_curr_tkwin),_curr_tkwin, Tcl_GetString(objPtr)); fid = new FontHandle(tkf); } void Font::Release() { if (fid) { delete reinterpret_cast<FontHandle *>(fid); } fid = 0; } //========================================================================== // CLASS Window implementation (also seemingly required) // Window::~Window() {} void Window::Destroy() {} PRectangle Window::GetMonitorRect(Point pt) { return PRectangle(0,0,0,0); } void Window::SetCursor(Cursor curs) { ScintillaObject *sc_obj = reinterpret_cast<ScintillaObject *>(wid); if (!sc_obj) return; if ( ! Tk_IsMapped(sc_obj->tkwin) ) return; //printf("##################Window::SetCursor %d\n",curs); TkSciExt::MSG_SetCursor((ClientData)sc_obj->client, static_cast<int>(curs)); } void Window::SetFont(Scintilla::Font &) { } void Window::Show(bool show) { } void Window::SetPosition(PRectangle rc) { } void Window::SetPositionRelative(PRectangle rc, Window relativeTo) { } PRectangle Window::GetPosition() { return PRectangle(0,0,0,0); } PRectangle Window::GetClientPosition() { return GetPosition(); } void Window::InvalidateRectangle(PRectangle rc) { ScintillaObject *sc_obj = reinterpret_cast<ScintillaObject *>(wid); if (!sc_obj) { return; } if ( ! Tk_IsMapped(sc_obj->tkwin) ) { //printf("Window::InvalidateRectangle NOT MAPPED YET for sc_obj=%p\n",(void *)sc_obj); return; } //printf("Window::InvalidateRectangle((%p)) >> +%d+%dx%dx%d\n",(void *)this,rc.left,rc.top,(rc.right-rc.left),(rc.bottom-rc.top)); // We use an Expose event to indicate to the Tk widget functionality // what region needs to be repainted XEvent e; e.xexpose.type = Expose; e.xexpose.count = -1; e.xexpose.display = Tk_Display(sc_obj->tkwin); e.xexpose.window = Tk_WindowId(sc_obj->tkwin); // HACK ALERT(maybe) We manually force the expose region to include // any margins which are visible if (rc.left > 0) { rc.left = 0; rc.right++; } e.xexpose.x = rc.left; e.xexpose.y = rc.top; e.xexpose.width = (rc.right - rc.left); e.xexpose.height = (rc.bottom - rc.top); Tk_QueueWindowEvent(&e, TCL_QUEUE_TAIL); } void Window::InvalidateAll() { printf("Window::InvalidateAll\n"); } //========================================================================== // CLASS ListBox implementation (also seemingly required) // NOTE: even if calltips and code-completion aren't going to be used, the // following class _IS_ required // class ListBoxX : public ListBox { public: ListBoxX() {} virtual ~ListBoxX() {} void SetFont(Font &) {} void Create(Window &, int, Point, int, bool, int) {} void SetAverageCharWidth(int) {} void SetVisibleRows(int) {} int GetVisibleRows() const {return 0;} PRectangle GetDesiredRect() { return PRectangle(); } int CaretFromEdge() { return 0; } void Clear() {} void Append(char *s, int type = -1) {} int Length() { return 0; } void Select(int n) {} int GetSelection() { return 0; } int Find(const char *prefix) { return -1; } void GetValue(int n, char *value, int len) {} void RegisterImage(int type, const char *xpm_data) {} void RegisterRGBAImage(int, int, int, const unsigned char *) {} void ClearRegisteredImages() {} void SetDoubleClickAction(CallBackAction, void *) {} void SetList(const char* list, char separator, char typesep) {} }; ListBox::ListBox() {} ListBox::~ListBox() {} ListBox *ListBox::Allocate() { return new ListBoxX(); } //========================================================================== // CLASS ElapsedTime implementation (also seemingly required) ElapsedTime::ElapsedTime() { } #ifdef SCI_NAMESPACE } #endif |
Added tk/README.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
What is ScintillaTk? Scintilla is a free source code editing component for Win32 and GTK+ developped by Neil Hodgson. For more information about Scintilla, see http://www.scintilla.org. This packages provides the Scintilla widget as a Tk Toolkit widget. This Tk widget extension is modeled after the Tk text widget for common or similar operations. There are also additional subcommands unique to Scintilla's features. See the ScintillaTk man page for more details. This extension was developed using Tcl/Tk 8.5. It will not currently build with 8.4, but it may be possible with a little bit of work. It also requires Tk to have xft support in order to work correctly. This is a freely available open source package. You can do virtually anything you like with it, such as modifying it, redistributing it, and selling it either in whole or in part. See the file "license.terms" for complete information. CONTENTS ======== The following is a short description of the files you will find in the tk platform directory. Makefile.in Makefile template. The configure script uses this file to produce the final Makefile. README This file aclocal.m4 Generated file. Do not edit. Autoconf uses this as input when generating the final configure script. See "tcl.m4" below. configure Generated file. Do not edit. This must be regenerated anytime configure.in or tclconfig/tcl.m4 changes. configure.in Configure script template. Autoconf uses this file as input to produce the final configure script. pkgIndex.tcl.in Package index template. The configure script will use this file as input to create pkgIndex.tcl. license.terms The licensing terms. PlatTK.cxx Tk platform implementation source files. ScintillaTK.cxx sciwrappers.cxx sciwrappers.h scintilla-ext.cxx scintilla-ext.h scintilla-cmd.cxx scintilla-cmd.h doc/scintilla.n Unix nroff man page widget-test.tcl widget-text-test.tcl tclconfig/ This directory contains various template files that build the configure script. They should not need modification. install-sh Program used for copying binaries and script files to their install locations. tcl.m4 Collection of Tcl autoconf macros. Included by aclocal.m4 to define SC_* macros. Scintilla Changes ================= As part of this platform implementation, the following Scintilla source files have been modified: include/ ILexer.h - Add virtual destructors. Platform.h - Add Tk platform defines and definitions. ScintillaWidget.h - Add Tk platform defines and definitions. src/ Editor.cxx - Force number conversion via casts. XPM.h - Support 1-4 character color indexes. XPM.cxx This allows more colorful marker images. UNIX BUILD ========== Building under most UNIX systems is easy, just run the configure script and then run make. For more information about the build process, see the tcl/unix/README file in the Tcl src dist. The following minimal example will install the extension in the /opt/scintillatk directory. $ cd scintilla/tk $ ./configure $ make $ make install WINDOWS BUILD ============= The recommended method to build extensions under windows is to use the Msys + Mingw build process. This provides a Unix-style build while generating native Windows binaries. Using the Msys + Mingw build tools means that you can use the same configure script as per the Unix build to create a Makefile. See the tcl/win/README file for the URL of the Msys + Mingw download. INSTALLATION ============ The installation of a TEA package is structure like so: $exec_prefix / \ lib bin | | PACKAGEx.y (dependent .dll files on Windows) | pkgIndex.tcl (.so|.dll files) The main .so|.dll library file gets installed in the versioned PACKAGE directory, which is OK on all platforms because it will be directly referenced with by 'load' in the pkgIndex.tcl file. Dependent DLL files on Windows must go in the bin directory (or other directory on the user's PATH) in order for them to be found. |
Added tk/ScintillaTK.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 |
// Scintilla source code edit control // ScintillaTK.cxx - Tk specific subclass of ScintillaBase // Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be // distributed. // Copyright (c) 2013 Mentor Graphics Corporation // The license.terms file describes the conditions under which this software may be distributed. #include <tk.h> #include <stdlib.h> #include <string> #include <string.h> #include <vector> #include <map> #include "Platform.h" #include "SplitVector.h" #include "ILexer.h" #include "Scintilla.h" #include "ScintillaWidget.h" #include "AutoComplete.h" #include "Partitioning.h" #include "CallTip.h" #include "CellBuffer.h" #include "CharClassify.h" #include "RunStyles.h" #include "ContractionState.h" #include "Decoration.h" #include "Document.h" #include "KeyMap.h" #include "Indicator.h" #include "XPM.h" #include "LineMarker.h" #include "Style.h" #include "ViewStyle.h" #include "Selection.h" #include "PositionCache.h" #include "Editor.h" #include "ScintillaBase.h" #ifdef SCI_LEXER #include "SciLexer.h" #include "LexerModule.h" #include "ExternalLexer.h" #endif #include "scintilla-ext.h" using namespace TkSciExt; #ifdef SCI_NAMESPACE using namespace Scintilla; #endif ///////////////////////////////////////////////////////////////////// // CLASS: ScintillaTK // ///////////////////////////////////////////////////////////////////// class ScintillaTK : public ScintillaBase { // Private so ScintillaTK objects can not be copied ScintillaTK(const ScintillaTK &); ScintillaTK &operator=(const ScintillaTK &); public: ScintillaTK(_ScintillaObject *sci_); virtual ~ScintillaTK(); private: // Required virtuals (ScintillaBase) virtual void Initialise(); virtual void Finalise(); // Required virtuals (Editor) virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); virtual void ClaimSelection(); virtual void Copy(); virtual void CopyToClipboard(const SelectionText &selectedText); virtual void Paste(); virtual void SetVerticalScrollPos(); virtual void SetHorizontalScrollPos(); virtual bool ModifyScrollBars(int nMax, int nPage); virtual void NotifyChange(); virtual void NotifyParent(SCNotification scn); virtual void SetTicking(bool on); virtual void SetMouseCapture(bool on); virtual bool HaveMouseCapture(); virtual void CreateCallTipWindow(PRectangle rc) {} virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true) {} public: // Public for client code to call back to scintilla virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); // public to allow static "timeout" function access void Tick(); private: void CopyToScreen(bool margin_only = false); void PaintRect(PRectangle r); void FullPaint(); void StoreOnClipboard(SelectionText *clipText); virtual PRectangle GetClientRectangle(); virtual void DisplayCursor(Cursor c); // overload virtual void ScrollText(int linesToMove); bool capturedMouse; ScintillaObject *sc_obj; Surface *surfaceWindow; int press_button; // used to indicate which button was pressed int press_x; // records X location of the press int press_y; // Y location bool painted_region_set; PRectangle PaintedRegion; }; //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv // declared in ScintillaWidget.h #ifdef _WIN32 void _print_trace (bool on) {} #else #include <execinfo.h> //FOR DUMPING THE CALL STACK... void _print_trace (bool on) { if (!on) return; #define TLEVELS 20 void *array[TLEVELS]; size_t size, i; char **strings; size = backtrace (array, TLEVELS); strings = backtrace_symbols (array, size); printf ("Obtained %d stack frames.\n", (int)size); for (i = 0; i < size; i++) printf (">>> %s\n", strings[i]); free (strings); } #endif static int _x_error_count = 0; int _x_error_handler(Display *dsp, XErrorEvent *evt) { #ifndef _WIN32 char buf[1000]; if (_x_error_count++ > 10) { printf("X ERROR LIMIT EXCEEDED ... Bailing!!\n"); exit(99); return 0; } XGetErrorText( dsp, evt->error_code, buf, 1000); printf("XERROR: %s\n\tDisplay=%p type=%d resourceid=%ld serial=%ld\n\terror_code=%d request_code=%d minor_code=%d\n", buf, (void *)dsp, evt->type, evt->resourceid, evt->serial, evt->error_code, evt->request_code, evt->minor_code); _print_trace(1); #endif return 0; } //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ void ScintillaTK::Initialise() { //TODO: what goes in here??? printf("ScintillaTK::Initialise\n"); // maybe need to set up blinking of caret? } void ScintillaTK::Finalise() { // SetTicking(false); ScintillaBase::Finalise(); printf("ScintillaTK::Finalise\n"); } //============================================================= //CONSTRUCTOR //============================================================= extern int _Xdebug; ScintillaTK::ScintillaTK(ScintillaObject *sc_obj_) : capturedMouse(false), surfaceWindow(0) { //printf("ScintillaTK CTOR this=%p\n",(void *)this); sc_obj = sc_obj_; wMain = sc_obj; // base class relies on this being set!! //printf("CTOR >>>>>>>> wMain=%p\n",(void *)sc_obj); #if 0 //NOTE: Don't use this when running within vish !! _Xdebug = 1; // <<< this is a global in the X11 code XSetErrorHandler(_x_error_handler); #endif } ScintillaTK::~ScintillaTK() { //printf("ScintillaTK DTOR this=%p\n",(void *)this); if (surfaceWindow) { surfaceWindow->Release(); if (timer.ticking) { Tcl_DeleteTimerHandler(reinterpret_cast<Tcl_TimerToken>(timer.tickerID)); } delete surfaceWindow; } } /**************************************************************** // Func: WndProc // Desc: Handles message processing *****************************************************************/ sptr_t ScintillaTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { //printf("ScintillaTK::WndProc iMessage=%d\n",iMessage); try { switch (iMessage) { case SCI_TKMSG_ANNOTATIONLENGTH: { Document *doc = reinterpret_cast<Document *>(ScintillaBase::WndProc(SCI_GETDOCPOINTER,0,0)); return doc->AnnotationStyledText(wParam).length; } case SCI_TKMSG_ANNOTATIONINDENT: { int line = static_cast<int>(wParam); bool pixels = static_cast<int>(lParam); Document *doc = reinterpret_cast<Document *>(ScintillaBase::WndProc(SCI_GETDOCPOINTER,0,0)); // the indent value represents the number of spaces(tabs are converted to // the required number of spaces) preceding the text int indent = doc->GetLineIndentation(line); if ( ScintillaBase::WndProc(SCI_ANNOTATIONGETVISIBLE, 0,0) == ANNOTATION_BOXED ) { indent++; // box style adds extra space } if (pixels) { // adjust for width of margin(s) and pad region leftside of text int marginwidth = TkSciExt::GetMarginWidth((ClientData)sc_obj->client); marginwidth += ScintillaBase::WndProc(SCI_GETMARGINLEFT, 0,0); // adjust for hz scroll int xoff = ScintillaBase::WndProc(SCI_GETXOFFSET, 0,0); // the returned value will represent the X pixel location // of where the annotation text's left edge is. // Note: "vs" is a protected variable in Editor base class return (indent * vs.spaceWidth) + marginwidth - xoff; } return indent; } case SCI_TKMSG_RESIZE : { ChangeSize(); break; } case SCI_TKMSG_PAINT: { PRectangle *rc = reinterpret_cast<PRectangle *>(wParam); PaintRect(*rc); break; } case SCI_TKMSG_DESTROY: { delete this; break; } case SCI_TKMSG_DUMPSTYLES: { if (wParam != 0) { int n = static_cast<int>(ScintillaBase::WndProc(SCI_GETLENGTH,0,0)); int last = -1; for (int i=0;i < n;i++) { int curr = static_cast<int>(ScintillaBase::WndProc(SCI_GETSTYLEAT, i,0)); if (curr != last) { last = curr; printf("{%d}", curr); // << current style id } printf("%c", static_cast<char>(ScintillaBase::WndProc(SCI_GETCHARAT,i,0))); } printf("\n"); } break; } #ifdef SCI_LEXER case SCI_LOADLEXERLIBRARY: // support for dynamically loading external lexers LexerManager::GetInstance()->Load(reinterpret_cast<const char *>(lParam)); break; #endif case SCI_SETFOCUS: { //### KEEP THIS CASE ENTRY _LAST_ ### SetTicking(wParam != 0); // no "break", let base message handling deal with the rest } default: return ScintillaBase::WndProc(iMessage, wParam, lParam); } } catch (std::bad_alloc&) { errorStatus = SC_STATUS_BADALLOC; } catch (...) { errorStatus = SC_STATUS_FAILURE; } return 0l; } /**************************************************************** // Func: DefWndProc // Desc: Required by Editor base class. It's called if the base // class's WndProc function doesn't handle a message *****************************************************************/ sptr_t ScintillaTK::DefWndProc(unsigned int, uptr_t, sptr_t) { return 0; } /**************************************************************** // Func: PaintRect // Desc: *****************************************************************/ void ScintillaTK::PaintRect(PRectangle r) { try { paintState = painting; // see Editor.h rcPaint = r; PRectangle rcClient = GetClientRectangle(); //printf("PaintRect: +%02d+%02dx%03dx%03d\n",rcPaint.left,rcPaint.top,(rcPaint.right-rcPaint.left),(rcPaint.bottom-rcPaint.top)); paintingAllText = rcPaint.Contains(rcClient); if ( ! surfaceWindow) { surfaceWindow = Surface::Allocate(SC_TECHNOLOGY_DEFAULT); } //printf("PaintRect: SURFACE=%p\n",(void *)surfaceWindow); if (surfaceWindow) { sc_obj->main = true; surfaceWindow->Init(sc_obj); painted_region_set = true; PaintedRegion = rcPaint; Paint(surfaceWindow, rcPaint); // call base class's Paint painted_region_set = false; //printf("PaintRect: DONE\n^^^^^^^^^^\n"); } if (paintState == paintAbandoned) { // Painting area was insufficient to cover new styling or brace highlight positions FullPaint(); } paintState = notPainting; } catch (...) { // don't know how we would get here, but ScintiallaGTK does it this way... errorStatus = SC_STATUS_FAILURE; } } /**************************************************************** // Func: ScrollText // Desc: Called from Editor::ScrollTo *****************************************************************/ void ScintillaTK::ScrollText(int linesToMove) { int diff = vs.lineHeight * -linesToMove; //printf("ScrollText %d pixels\n",diff); ClientData d = (ClientData)sc_obj->client; TkSciExt::SetYScrollDelta(d, diff); TkSciExt::UpdateForScroll(d); // if ( !(sciwidgetPtr->flags & REDRAW_PENDING) ) { // //printf("ScrollText -- QUEUING DISPLAY\n"); // Tk_DoWhenIdle(SciWidgetDisplay, (ClientData)sciwidgetPtr); // } else { // //printf("ScrollText -- SKIPPING REDRAW...\n"); // } // sciwidgetPtr->flags |= REDRAW_PENDING|REDRAW_YSCROLL; //printf("OVERLOADED ScrollText moving %d lines\n",diff); // Editor::ScrollText(linesToMove); } /**************************************************************** // Func: GetClientRectangle // Desc: Returns the bounding rectangle encompassing the parent // window *****************************************************************/ PRectangle ScintillaTK::GetClientRectangle() { Tk_Window tkwin = sc_obj->tkwin; int w = Tk_Width(tkwin); int h = Tk_Height(tkwin); //TODO: factor in borders??? int bd=0; PRectangle rc(bd,bd, w-(bd*2), h-(bd*2)); return rc; } void ScintillaTK::DisplayCursor(Cursor c) { printf("ScintillaTK::DisplayCursor\n"); } // Redraw all of text area. This paint will not be abandoned. void ScintillaTK::FullPaint() { paintState = painting; rcPaint = GetClientRectangle(); paintingAllText = true; if (surfaceWindow) { Paint(surfaceWindow, rcPaint); } } void ScintillaTK::Copy() { if (!sel.Empty()) { SelectionText *clipText = new SelectionText(); CopySelectionRange(clipText); StoreOnClipboard(clipText); } } void ScintillaTK::CopyToClipboard(const SelectionText &selectedText) { SelectionText *clipText = new SelectionText(); clipText->Copy(selectedText); StoreOnClipboard(clipText); } void ScintillaTK::StoreOnClipboard(SelectionText *clipText) { //TODO: what do we do?? //Tk_ClipboardClear + Tk_ClipboardAppend ?? } void ScintillaTK::Paste() { //TODO: what do we do?? } void ScintillaTK::ClaimSelection() { // // X Windows has a 'primary selection' as well as the clipboard. // // Whenever the user selects some text, we become the primary selection // if (!sel.Empty() && IS_WIDGET_REALIZED(GTK_WIDGET(PWidget(wMain)))) { // primarySelection = true; // gtk_selection_owner_set(GTK_WIDGET(PWidget(wMain)), // GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME); // primary.Free(); // } else if (OwnPrimarySelection()) { // primarySelection = true; // if (primary.s == NULL) // gtk_selection_owner_set(NULL, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME); // } else { // primarySelection = false; // primary.Free(); // } } // *required* virtual void ScintillaTK::SetVerticalScrollPos() { DwellEnd(true); // most of the scroll functionality is handled in the widget's "yview" command TkSciExt::MSG_SyncYScroll((ClientData)sc_obj->client); } // *required* virtual void ScintillaTK::SetHorizontalScrollPos() { DwellEnd(true); // the actual scroll functionality is handled in the widget's "xview" command TkSciExt::MSG_SyncXScroll((ClientData)sc_obj->client); } // *required* virtual bool ScintillaTK::ModifyScrollBars(int nMax, int nPage) { bool modified = true; // this gets called _BEFORE_ the client window has it's size info set, which // means GetClientRectangle won't provide anything useful to the Editor code. // We'll deal with getting the initial scrollbar data set by handling the first // <Map> event - see widget.cxx in the SciWidgetEventProc function // CAVEAT: To support "scrollwidthtracking" we need to sync the horizontal // scrollbar because this function is called after Scintilla updates the // widest line info. if (!Tk_IsMapped(sc_obj->tkwin)) { // if the window isn't mapped don't waste time updating the scrollbars // the map notify event will force a scrollbar update return 0; } if (WndProc(SCI_GETHSCROLLBAR, 0,0) && WndProc(SCI_GETSCROLLWIDTHTRACKING, 0,0)) { TkSciExt::MSG_SyncXScroll((ClientData)sc_obj->client); } if (WndProc(SCI_GETVSCROLLBAR, 0,0)) { TkSciExt::MSG_SyncYScroll((ClientData)sc_obj->client); } return modified; } void ScintillaTK::NotifyChange() { //something changed in the document... //printf("NotifyChange\n"); } #define _RGB_(r,g,b) r | (g << 8) | (b << 16) #include <time.h> void ScintillaTK::NotifyParent(SCNotification scn) { //printf("ScintillaTK::NotifyParent scn=%d SURFACE=%p\n", scn.nmhdr.code,(void *)surfaceWindow); switch (scn.nmhdr.code) { case SCN_MODIFIED: { int mt = scn.modificationType; if (mt & (SC_MOD_INSERTTEXT|SC_MOD_DELETETEXT)) { ClientData d = (ClientData)sc_obj->client; if (scn.linesAdded) { // send lines added message int ln = WndProc(SCI_LINEFROMPOSITION, scn.position, 0); TkSciExt::MSG_LinesAdded(d, ln, scn.linesAdded); } TkSciExt::MSG_Modified(d); // send notification of document modification } break; } case SCN_PAINTED: { // This is called at the end of the Paint function, _BUT_ this // only happens if part of the text area had to be painted. // CopyToScreen(); break; } case SCN_UPDATEUI: { // Note that this is how SciTE does updates for the statusbar's // line and column indicator. TkSciExt::MSG_MoveUpdate((ClientData)sc_obj->client); break; } } } void ScintillaTK::CopyToScreen(bool margin_only) { PRectangle r; Point pt = Point(0,0); if (painted_region_set) { r = PaintedRegion; } else { r = GetClientRectangle(); } if (margin_only) { int marginwidth = TkSciExt::GetMarginWidth((ClientData)sc_obj->client); if (marginwidth <= 0) return; r.right = marginwidth; } // copy offscreen pixmap used by drawing operations // to the screen surfaceWindow->Copy(r, pt, *surfaceWindow); } ////////////////////////////////////////////////////// // BEGIN caret(aka "tick") management ////////////////////////////////////////////////////// static void _TimeOut(ClientData cd) { ScintillaTK *sc = reinterpret_cast<ScintillaTK *>(cd); sc->Tick(); // call our overloaded function } void ScintillaTK::Tick() { // Mimic how Tk shows the insert caret(which is 1-pixel wide // for the first column and thicker for the others) int currpos = CurrentPosition(); int col = WndProc(SCI_GETCOLUMN, currpos, 0); vs.caretWidth = (col == 0 ? 1 : 2); Editor::Tick(); // schedule another timer... timer.tickerID = reinterpret_cast<TickerID>( Tcl_CreateTimerHandler(timer.tickSize, _TimeOut, (ClientData)this) ); } // This is called from Editor void ScintillaTK::SetTicking(bool on) { if (timer.ticking != on) { timer.ticking = on; if (timer.ticking) { timer.tickerID = reinterpret_cast<TickerID>( Tcl_CreateTimerHandler(timer.tickSize, _TimeOut, (ClientData)this) ); } else { Tcl_DeleteTimerHandler(reinterpret_cast<Tcl_TimerToken>(timer.tickerID)); } } timer.ticksToWait = caret.period; } ////////////////////////////////////////////////////// void ScintillaTK::SetMouseCapture(bool on) { if (mouseDownCaptures) { if (on) { Tk_Grab(sc_obj->interp, sc_obj->tkwin, 0/*is_global*/); } else { Tk_Ungrab(sc_obj->tkwin); } } capturedMouse = on; } bool ScintillaTK::HaveMouseCapture() { return capturedMouse; } //--- end of class ScintillaTK //############################################################################# //# //# The following two functions, which are declared in ScintillaWidget.h, are //# how Tk-based widgets create and communicate with the Scintilla editor //# //############################################################################# ScintillaObject* scintilla_new(Tcl_Interp *interp, Tk_Window tkwin, ClientData cd) { ScintillaObject *sci_obj = new ScintillaObject; sci_obj->interp = interp; sci_obj->tkwin = tkwin; sci_obj->client = cd; sci_obj->main = false; sci_obj->pscin = new ScintillaTK(sci_obj); return sci_obj; } sptr_t scintilla_send_message(ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam) { ScintillaTK *psci = reinterpret_cast<ScintillaTK *>(sci->pscin); return psci->WndProc(iMessage, wParam, lParam); } |
Added tk/aclocal.m4.
> > > > > > > > > |
1 2 3 4 5 6 7 8 9 |
# # Include the TEA standard macro set # builtin(include,tclconfig/tcl.m4) # # Add here whatever m4 macros you want to define for your package # |
Added tk/configure.
more than 10,000 changes
Added tk/configure.in.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
#!/bin/bash -norc dnl This file is an input file used by the GNU "autoconf" program to dnl generate the file "configure", which is run during Tcl installation dnl to configure the system for the local environment. #----------------------------------------------------------------------- # Sample configure.in for Tcl Extensions. The only places you should # need to modify this file are marked by the string __CHANGE__ #----------------------------------------------------------------------- #----------------------------------------------------------------------- # __CHANGE__ # Set your package name and version numbers here. # # This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION # set as provided. These will also be added as -D defs in your Makefile # so you can encode the package version directly into the source files. # This will also define a special symbol for Windows (BUILD_sample in # this case) so that we create the export library with the dll. #----------------------------------------------------------------------- AC_INIT([ScintillaTk], [0.26]) #-------------------------------------------------------------------- # Call TEA_INIT as the first TEA_ macro to set up initial vars. # This will define a ${TEA_PLATFORM} variable == "unix" or "windows" # as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE. #-------------------------------------------------------------------- TEA_INIT([3.9]) AC_CONFIG_AUX_DIR(tclconfig) #-------------------------------------------------------------------- # Load the tclConfig.sh file #-------------------------------------------------------------------- TEA_PATH_TCLCONFIG TEA_LOAD_TCLCONFIG #-------------------------------------------------------------------- # Load the tkConfig.sh file if necessary (Tk extension) #-------------------------------------------------------------------- TEA_PATH_TKCONFIG TEA_LOAD_TKCONFIG #----------------------------------------------------------------------- # Handle the --prefix=... option by defaulting to what Tcl gave. # Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER. #----------------------------------------------------------------------- TEA_PREFIX #----------------------------------------------------------------------- # Standard compiler checks. # This sets up CC by using the CC env var, or looks for gcc otherwise. # This also calls AC_PROG_CC and a few others to create the basic setup # necessary to compile executables. #----------------------------------------------------------------------- TEA_SETUP_COMPILER AC_PROG_CXX AC_PROG_CXXCPP #----------------------------------------------------------------------- # __CHANGE__ # Specify the C source files to compile in TEA_ADD_SOURCES, # public headers that need to be installed in TEA_ADD_HEADERS, # stub library C source files to compile in TEA_ADD_STUB_SOURCES, # and runtime Tcl library files in TEA_ADD_TCL_SOURCES. # This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS # and PKG_TCL_SOURCES. #----------------------------------------------------------------------- TEA_ADD_SOURCES([PlatTK.cxx ScintillaTK.cxx sciwrappers.cxx scintilla-cmd.cxx scintilla-ext.cxx]) TEA_ADD_HEADERS([]) TEA_ADD_INCLUDES([-I\"${srcdir}/../include\" -I\"${srcdir}/../src\" -I\"${srcdir}/../lexlib\"]) TEA_ADD_LIBS([${TK_LIBS}]) SCI_CORE_VER=`cat ${srcdir}/../win32/ScintRes.rc | awk '/#define VERSION_SCINTILLA/ {printf("%s\n",$3);}'` TEA_ADD_CFLAGS([-DSCI_NAMESPACE -DTK -DSCI_LEXER -DSCI_CORE_VERSION=\\\"${SCI_CORE_VER}\\\"]) TEA_ADD_STUB_SOURCES([]) TEA_ADD_TCL_SOURCES([scintillatk.tcl]) #-------------------------------------------------------------------- # __CHANGE__ # # You can add more files to clean if your extension creates any extra # files by extending CLEANFILES. # Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure # and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var. # # A few miscellaneous platform-specific items: # TEA_ADD_* any platform specific compiler/build info here. #-------------------------------------------------------------------- #CLEANFILES="$CLEANFILES pkgIndex.tcl" if test "${TEA_PLATFORM}" = "windows" ; then # Ensure no empty if clauses : #TEA_ADD_SOURCES([win/winFile.c]) #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"]) else # Ensure no empty else clauses : #TEA_ADD_SOURCES([unix/unixFile.c]) #TEA_ADD_LIBS([-lsuperfly]) fi #-------------------------------------------------------------------- # __CHANGE__ # Choose which headers you need. Extension authors should try very # hard to only rely on the Tcl public header files. Internal headers # contain private data structures and are subject to change without # notice. # This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG #-------------------------------------------------------------------- TEA_PUBLIC_TCL_HEADERS #TEA_PRIVATE_TCL_HEADERS TEA_PUBLIC_TK_HEADERS #TEA_PRIVATE_TK_HEADERS #TEA_PATH_X #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. # This auto-enables if Tcl was compiled threaded. #-------------------------------------------------------------------- TEA_ENABLE_THREADS #-------------------------------------------------------------------- # The statement below defines a collection of symbols related to # building as a shared library instead of a static library. #-------------------------------------------------------------------- TEA_ENABLE_SHARED #-------------------------------------------------------------------- # This macro figures out what flags to use with the compiler/linker # when building shared/static debug/optimized objects. This information # can be taken from the tclConfig.sh file, but this figures it all out. #-------------------------------------------------------------------- TEA_CONFIG_CFLAGS #-------------------------------------------------------------------- # Set the default compiler switches based on the --enable-symbols option. #-------------------------------------------------------------------- TEA_ENABLE_SYMBOLS #-------------------------------------------------------------------- # Everyone should be linking against the Tcl stub library. If you # can't for some reason, remove this definition. If you aren't using # stubs, you also need to modify the SHLIB_LD_LIBS setting below to # link against the non-stubbed Tcl library. Add Tk too if necessary. #-------------------------------------------------------------------- AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs]) AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs]) #-------------------------------------------------------------------- # This macro generates a line to use when building a library. It # depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS, # and TEA_LOAD_TCLCONFIG macros above. #-------------------------------------------------------------------- TEA_MAKE_LIB #-------------------------------------------------------------------- # Determine the name of the tclsh and/or wish executables in the # Tcl and Tk build directories or the location they were installed # into. These paths are used to support running test cases only, # the Makefile should not be making use of these paths to generate # a pkgIndex.tcl file or anything else at extension build time. #-------------------------------------------------------------------- TEA_PROG_TCLSH #TEA_PROG_WISH #-------------------------------------------------------------------- # Finally, substitute all of the various values into the Makefile. # You may alternatively have a special pkgIndex.tcl.in or other files # which require substituting th AC variables in. Include these here. #-------------------------------------------------------------------- AC_OUTPUT([Makefile pkgIndex.tcl]) |
Added tk/doc/demos/ypedit.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 |
# ypedit.tcl -- # Shell procedures for Young Programmers Project: # It defines several utility commands: # ed - edit a file # vw - view the contents of a file # # From: http://wiki.tcl.tk/9600 # # Modified to use ScintillaTk text widget # use ttk widgets package require Tk lappend auto_path [file normalize ../../../../build/usr/lib] package require ScintillaTk ttk::style theme use clam # ypshell -- # Namespace for the commands # namespace eval ::ypshell { namespace export ed vw variable editfile set editfile(count) 0 } # ed -- # Edit a file # # Arguments: # filename Name of the file to edit # # Return value: # None # proc ::ypshell::ed { filename } { ::ypshell::EditFile 1 0 $filename } # vw -- # View a file # # Arguments: # filename Name of the file to view # # Return value: # None # proc ::ypshell::vw { filename } { ::ypshell::EditFile 0 0 $filename } # EditFile -- # Edit or view a file (actual procedure) # # Arguments: # editable Select edit mode (1=edit, 0=view) # newopen Allow new/open menu items (1=yes, 0=no) # filename Name of the file to edit/view # # Return value: # None # proc ::ypshell::EditFile { editable newopen filename } { variable editfile incr editfile(count) set w .edit$editfile(count) toplevel $w wm withdraw . wm title $w "Edit/view: $filename" set mb $w.menubar menu $mb #pack $mb -side top -fill x -pady 0 $w configure -menu $mb #ttk::menubutton $mb.file -text File -menu $mb.file.menu -underline 0 #ttk::menubutton $mb.edit -text Edit -menu $mb.edit.menu -underline 0 #ttk::menubutton $mb.search -text Search -menu $mb.search.menu -underline 0 #ttk::menubutton $mb.help -text Help -menu $mb.help.menu -underline 0 menu $mb.file -tearoff false; $mb add cascade -label File -menu $mb.file menu $mb.edit -tearoff false; $mb add cascade -label Edit -menu $mb.edit menu $mb.search -tearoff false; $mb add cascade -label Search -menu $mb.search menu $mb.help -tearoff false; $mb add cascade -label Help -menu $mb.help #pack $mb.file $mb.edit $mb.search -side left #pack $mb.help -side left ;# Platform-dependent! # # Set up the "File" menu # if { $newopen } { if { $editable } { $mb.file add command -label New -underline 0 \ -command [list ::ypshell::NewFile] } $mb.file add command -label Open -underline 0 \ -command [list ::ypshell::OpenFile] $mb.file add separator } if { $editable } { $mb.file add command -label Save -underline 0 \ -command [list ::ypshell::SaveFile $w $filename 0] if { $newopen } { $mb.file add command -label "Save as ..." -underline 1 \ -command [list ::ypshell::SaveFile $w $filename 1] } $mb.file add separator } $mb.file add command -label Exit -underline 1 \ -command [list ::ypshell::ExitEdit $w $newopen $editable $filename] # # Set up the "Edit" menu # if { $editable } { $mb.edit add command -label "Undo" -underline 0 \ -command [list ::ypshell::UndoChange] $mb.edit add command -label "Redo" -underline 0 \ -command [list ::ypshell::RedoChange] $mb.edit add separator } $mb.edit add command -label "Mark line(s)" -underline 0 \ -command [list ::ypshell::MarkLines] $mb.edit add command -label "Unmark line(s)" -underline 1 \ -command [list ::ypshell::UnmarkLines] $mb.edit add separator $mb.edit add command -label "Copy" -underline 0 \ -command [list ::ypshell::CopyBlock] if { $editable } { $mb.edit add command -label "Paste" -underline 0 \ -command [list ::ypshell::PasteBlock] $mb.edit add separator $mb.edit add command -label "Delete" -underline 0 \ -command [list ::ypshell::DeleteBlock] } # # Set up the "Search" menu # $mb.search add command -label "Find" -underline 0 \ -command [list ::ypshell::FindText $w] if { $editable } { $mb.search add command -label "Replace" -underline 0 \ -command [list ::ypshell::ChangeText] } # # Set up the "Help" menu # $mb.help add command -label "Overview" -underline 1 \ -command [list ::ypshell::HelpOverview] $mb.help add command -label "About" -underline 0 \ -command [list ::ypshell::AboutEdit] # # Create a thin separator # set ts $w.separator #frame $ts -height 2 -relief sunken -borderwidth 1 ttk::separator $ts -orient horizontal pack $ts -side top -fill x # # Create the toolbar # set fnt "Courier, 10" set fnt "systemfixed" set fixedfont "Courier" set tb $w.toolbar ttk::frame $tb -height 10 ttk::button $tb.goto -text "Go to:" -command [list ::ypshell::GotoLine $w ""] ttk::entry $tb.lineno -textvariable ::ypshell::editfile(lineno,$w) \ -width 5 -font $fnt ttk::button $tb.top -text "Top" -command [list ::ypshell::GotoLine $w 1] ttk::button $tb.bottom -text "Bottom" -command [list ::ypshell::GotoLine $w end] ttk::label $tb.empty1 -text " " ttk::label $tb.empty2 -text " " set ::ypshell::editfile(lineno,$w) 1 pack $tb.goto $tb.lineno $tb.empty1 $tb.top $tb.bottom $tb.empty2 -side left ttk::button $tb.find -text "Find:" -command [list ::ypshell::FindText $w] ttk::entry $tb.string -textvariable ::ypshell::editfile(find,$w) \ -font $fnt set ypshell::editfile(find,$w) "" pack $tb.goto $tb.find $tb.string -side left pack $tb -fill x -side top # # Create the text widget and the scroll bars # set tf $w.textframe set tw $tf.text ttk::frame $tf ttk::scrollbar $tf.scrollx -orient horiz -command "$tw xview" ttk::scrollbar $tf.scrolly -command "$tw yview" if {0} { text $tw -yscrollcommand "$tf.scrolly set" \ -xscrollcommand "$tf.scrollx set" \ -font $fixedfont } else { set bg [ttk::style lookup client -background] scintilla $tw -yscrollcommand "$tf.scrolly set" \ -xscrollcommand "$tf.scrollx set" \ -font $fixedfont \ -marginbackground $bg $tw margin configure 0 -type lnums $tw margin configure 4 -type fold $tw margin show 0 $tw margin show 4 $w configure -background $bg $mb configure -background $bg } grid $tw $tf.scrolly grid $tf.scrollx x grid $tw -sticky news grid $tf.scrolly -sticky ns grid $tf.scrollx -sticky ew grid columnconfigure $tf 0 -weight 1 grid rowconfigure $tf 0 -weight 1 if {0} { $tw configure -wrap none } pack $tf -fill both -side top -expand 1 set ypshell::editfile(textwidget,$w) $tw LoadFile $tw $filename } # LoadFile -- # Load the file into the text widget # # Arguments: # textw Text widget to use # filename Name of the file to edit/view # # Return value: # None # proc ::ypshell::LoadFile { textw filename } { set infile [ open "$filename" "r" ] set ext [string range [file extension $filename] 1 end] if {$ext ne ""} { catch {$textw configure -language $ext} } while { ! [ eof $infile ] } { gets $infile line $textw insert end $line $textw insert end "\n" } $textw tag configure pink -background #ffdddd -italic 1 $textw annotate set 14 "" $textw annotate set 14 "At this point, the scintilla code is loaded." pink $textw tag configure bright -bold 1 -background blue -foreground yellow $textw annotate set 16 "Dig those clams man!\nI like clam style because it's the only\nttk style that does not look boring!" bright $textw annotate show 2 close $infile } # SaveFile -- # Save the file (possibly under a different name) # # Arguments: # w Main widget holding the text # filename Name of the file to edit/view # newname Ask for a new name or not # # Return value: # None # proc ::ypshell::SaveFile { w filename newname } { variable editfile set tw $editfile(textwidget,$w) # Select a new file name -- TODO set outfile [ open "$filename" "w" ] set lineno 1 while { [$tw compare $lineno.0 < end] } { puts $outfile [$tw get "$lineno.0" "$lineno.0 lineend"] incr lineno } close $outfile } # GotoLine -- # Go to a specified line number # # Arguments: # w Main widget containing the text widget # pos Position # # Return value: # None # proc ::ypshell::GotoLine { w pos } { variable editfile set tw $editfile(textwidget,$w) if { $pos == "" } { set pos $editfile(lineno,$w) } if { $pos == "end" } { $tw mark set current "end linestart" } else { $tw mark set current "$pos.0" } $tw mark set insert [$tw index current] $tw see [$tw index current] focus $tw } # FindText -- # Find a text string # # Arguments: # w Main widget containing the text widget # # Return value: # None # proc ::ypshell::FindText { w } { variable editfile set string $editfile(find,$w) set tw $editfile(textwidget,$w) if { $string != "" } { set newpos [$editfile(textwidget,$w) search -forwards -exact -- $string "insert + 1 chars"] if { $newpos != "" } { $tw mark set current $newpos $tw mark set insert [$tw index current] $tw see [$tw index current] focus $tw } } } # ExitEdit -- # Exit and save the file (if wanted) # # Arguments: # w Widget from which it is called # editable Select edit mode (1=edit, 0=view) # newopen Allow new/open menu items (1=yes, 0=no) # filename Name of the file to edit/view # # Return value: # None # proc ::ypshell::ExitEdit { w editable newopen filename } { if { $editable } { if { !$newopen } { SaveFile $w $filename 0 } else { # Ask whether to save or not } } destroy $w } # # Simple test code # namespace import ::ypshell::ed namespace import ::ypshell::vw ed [file join [file dirname [info script]] ypedit.tcl] vw [file join [file dirname [info script]] ypedit.tcl] #$tw annotate set 210 "This is where margins are configured to show\ndifferent contents." |
Added tk/doc/scintillatk.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 |
<HTML> <BODY> <PRE> <!-- Manpage converted by man2html 3.0.1 --> scintilla - Scintilla text widget </PRE> <H2>SYNOPSIS</H2><PRE> <B>package</B> <B>require</B> <B>scintillatk</B> ?<B>0.25</B>? <B>scintilla</B> <I>pathName</I> ?<I>options</I>? </PRE> <H2>STANDARD OPTIONS</H2><PRE> <B>-autoseparators</B> <B>-highlight</B> <B>-moveupdatecommand</B> <B>-background</B> <B>-highlightthickness</B> <B>-relief</B> <B>-blink</B> <B>-highlightbackground</B> <B>-showws</B> <B>-borderwidth</B> <B>-language</B> <B>-state</B> <B>-busycursor</B> <B>-linesaddedcommand</B> <B>-tabwidth</B> <B>-cursor</B> <B>-marginbackground</B> <B>-takefocus</B> <B>-foldstyle</B> <B>-marginbg</B> <B>-xscrollcommand</B> <B>-font</B> <B>-marginforeground</B> <B>-yscrollcommand</B> <B>-foreground</B> <B>-marginfg</B> <B>-undo</B> <B>-height</B> <B>-marginwidthcommand</B> <B>-width</B> See the <B>options</B> manual entry for details on the standard options. </PRE> <H2>WIDGET-SPECIFIC OPTIONS</H2><PRE> Command-Line Name:<B>-autoseparators</B> Database Name: <B>autoSeparators</B> Database Class: <B>AutoSeparators</B> Specifies a boolean that says whether separators are automati- cally inserted in the undo stack. Only meaningful when the <B>-undo</B> option is true. Command-Line Name:<B>-height</B> Database Name: <B>height</B> Database Class: <B>Height</B> Specifies the desired height for the window, in units of charac- ters in the font given by the <B>-font</B> option. Must be at least one. Command-Line Name:<B>-state</B> Database Name: <B>state</B> Database Class: <B>State</B> Specifies one of two states for the text: <B>normal</B> or <B>disabled</B>. If the text is disabled then characters may not be inserted or deleted and no insertion cursor will be displayed, even if the input focus is in the widget. Command-Line Name:<B>-width</B> Database Name: <B>width</B> Database Class: <B>Width</B> Specifies the desired width for the window in units of charac- See Scintilla documentation for style values. Command-Line Name:<B>-language</B> Database Name: <B>language</B> Database Class: <B>Language</B> Specifies which programming language lexer to use for syntax highlighting. Command-Line Name:<B>-linesaddedcommand</B> Database Name: <B>lindesAddedCommand</B> Database Class: <B>LinesAddedCommand</B> Callback command when new lines are inserted in the document. This function can be used to update margin indicators if neces- sary. Command-Line Name:<B>-marginbackground</B> Database Name: <B>marginBackground</B> Database Class: <B>MarginBackground</B> The backgound color of the margin columns. Command-Line Name:<B>-marginforeground</B> Database Name: <B>marginForeground</B> Database Class: <B>MarginForeground</B> The foregound (font) color of the margin columns. Command-Line Name:<B>-marginwidthcommand</B> Database Name: Database Class: Callback command used when margin width changes. Command-Line Name:<B>-moveupdatecommand</B> Database Name: <B>moveUpdateCommand</B> Database Class: <B>MoveUpdateCommand</B> Callback command when margin changes. Command-Line Name:<B>-showws</B> Database Name: <B>showws</B> Database Class: <B>ShowWs</B> Show the ws??? _________________________________________________________________ </PRE> <H2>DESCRIPTION</H2><PRE> The <B>scintilla</B> command creates a new window (given by the <I>pathName</I> arg) and makes it into a Scintilla text widget. Additional options, <B>clearall</B> removes annotation strings for all lines <B>get</B> <I>line</I> Returns the annotation text for the specified line. <B>set</B> <I>line</I> <I>text</I> <I>?tagName</I> <I>text</I> <I>tagName</I> <I>...?</I> Assigns the specified text string to the specified line. If no tagName option is specified, the annotation text will use the default text styling. If a single tagName option is used it will control the appearance for all of the annotation text. By using multiple text and tagName options it's possible to have different appearances for different subranges of the text. <B>show</B> <I>0|1|2</I> Used to control the display of annotations where 0 - hid- ing, 1 - showing or 2 - showing with a bounding box. Note, this affects all lines with annotations. <I>pathName</I> <B>bbox</B> <I>index</I> Returns a list of four elements describing the screen area of the character given by index. The first two elements of the list give the x and y coordinates of the upper-left corner of the area occupied by the character, and the last two elements give the width and height of the area. If the character is not visi- ble on the screen then the return value is an empty list. <I>pathName</I> <B>cget</B> <I>option</I> Returns the current value of the configuration option given by option. Option may have any of the values accepted by the scin- tilla command. <I>pathName</I> <B>compare</B> <I>index1</I> <I>op</I> <I>index2</I> Compares the indices given by index1 and index2 according to the relational operator given by op, and returns 1 if the relation- ship is satisfied and 0 if it is not. Op must be one of the operators <, <=, =, >, >, or !. If op is == then 1 is returned if the two indices refer to the same character, if op is < then 1 is returned if index1 refers to an earlier character in the text than index2, and so on. <I>pathName</I> <B>configure</B> <I>?option?</I> <I>?value</I> <I>option</I> <I>value</I> <I>...?</I> Query or modify the configuration options of the widget. If no option is specified, returns a list describing all of the avail- able options for pathName. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). If one or more option-value pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. Option may have any of the <B>-displaylines</B> count all display lines (i.e. ignore lines which are folded) from the line of the first index up to, but not including the display line of the second index. Therefore if they are both on the same display line, zero will be returned. By definition displaylines are visible and therefore this only counts portions of actual visible lines. <B>-lines</B> count all lines (irrespective of folding) from the line of the first index up to, but not including the line of the second index. Therefore if they are both on the same line, zero will be returned. Lines are counted whether they are currently visible (non-folded) or not. <I>pathName</I> <B>delete</B> <I>index1</I> <I>?index2?</I> Delete a range of characters from the text. If both index1 and index2 are specified, then delete all the characters starting with the one given by index1 and stopping just before index2 (i.e. the character at index2 is not deleted). If index2 doesn't specify a position later in the text than index1 then no charac- ters are deleted. If index2 isn't specified then the single character at index1 is deleted. It is not allowable to delete characters in a way that would leave the text without a newline as the last character. The command returns an empty string. <I>pathName</I> <B>dump</B> <I>?switches?</I> <I>index1</I> <I>?index2?</I><B>_</B> Return the contents of the text widget from index1 up to, but not including index2, including the text and information about marks, tags, and embedded windows. If index2 is not specified, then it defaults to one character past index1. The information is returned in the following format:: key1 value1 index1 key2 value2 index2 ... The possible key values are indicatoron, indicatoroff, text, mark, styleon, styleoff, tagon, tagoff, image, and window. The corresponding value is the indicator type, text, mark name, style number, tag name, image name, or window name. The index information is the index of the start of the indicator transition, style transition, text, mark, tag transition, image or window. The image and window options are not supported and will return nothing. One or more of the fol- lowing switches (or abbreviations thereof) may be specified to control the dump: <B>-all</B> Return information about all elements: indicator, style, text, marks, tags, images and windows. This is the default. <B>-command</B> <I>command</I> Instead of returning the information as the result of the dump operation, invoke the command on each element of the text widget within the range. The command has three argu- <B>-style</B> Include information about style transitions in the dump results. Style information is returned as styleon and styleoff elements that indicate the begin and end of each range of each style, respectively. <B>-tag</B> Include information about tag transitions in the dump results. Tag information is returned as tagon and tagoff elements that indicate the begin and end of each range of each tag, respectively. <B>-text</B> Include information about text in the dump results. The value is the text up to the next element or the end of range indicated by index2. A text element does not span newlines. A multi-line block of text that contains no marks or tag transitions will still be dumped as a set of text segments that each end with a newline. The newline is part of the value. <B>-window</B> Include information about embedded windows in the dump results. This option is unsupported in Scintilla. <I>pathName</I> <B>edit</B> <I>option</I> <I>?arg</I> <I>arg</I> <I>...?</I> This command controls the undo mechanism and the modified flag. The exact behavior of the command depends on the option argument that follows the edit argument. The following forms of the com- mand are currently supported: <I>pathName</I> <B>edit</B> <B>canredo</B> Returns true if the redo stack is not empty. <I>pathName</I> <B>edit</B> <B>canundo</B> Returns true if the undo stack is not empty. <I>pathName</I> <B>edit</B> <B>Imodified</B> <I>?boolean?</I> If boolean is not specified, returns the modified flag of the widget. The insert, delete, edit undo and edit redo commands or the user can set or clear the modified flag. If boolean is specified, sets the modified flag of the widget to boolean. <I>pathName</I> <B>edit</B> <B>redo</B> When the -undo option is true, reapplies the last undone edits provided no other edits were done since then. Gen- erates an error when the redo stack is empty. Does noth- ing when the -undo option is false. <I>pathName</I> <B>edit</B> <B>reset</B> Clears the undo and redo stacks. <I>pathName</I> <B>edit</B> <B>separator</B> Inserts a separator (boundary) on the undo stack. Does document. The following commands are supported: <B>foldall</B> folds all lines within the document <B>foldbelow</B> <I>line</I> folds all lines which are after(below) line number line <B>foldparent</B> <I>line</I> returns the line containing the immediate fold parent of line <B>foldroot</B> <I>line</I> returns the line containing topmost fold parent of the specified line . This is at the top of the fold hierarchy containing line . <B>isfolded</B> <I>line</I> return 1 if line contained in a folded parent, and 0 if it isn't <B>show</B> <I>line</I> fully expand the containing fold hierarchy such that line is visible <B>toggle</B> <I>line</I> toggle the fold state of line (ie if collapsed, expand it; if expanded, collapse it) <B>topunfolded</B> <I>line</I> return the line of the highest fold parent for line which is currently expanded <B>unfoldall</B> unfold all lines <B>unfoldbelow</B> <I>line</I> unfold all lines which are after(below) line number line <I>pathName</I> <B>index</B> <I>index</I> <I>?-textonly?</I> Returns the position corresponding to index in the form line.char where line is the line number and char is the charac- ter number. See the documentation for the Tk Text widget for a description of the formats used to specify indices. NOTE: Speci- fying an X/Y location that corresponds to a line of annotation text will return the index for the end of the line associated with the annotation. If the -textonly option is used, then an empty string is returned if the X/Y location is over an annota- tion. <I>pathName</I> <B>insert</B> <I>index</I> <I>chars</I> Inserts all of the chars argument just before the character at alias name defined for the margin. The following forms of the command are currently supported: <I>pathName</I> <B>margin</B> <B>bbox</B> <I>marginID</I> <I>line</I> Returns a list of four elements describing the screen area of the margin identified by marginID, at the line specified by line. The first two elements of the list give the x and y coordinates of the upper-left corner of the area occupied by the character, and the last two ele- ments give the width and height of the area. If the char- acter is not visible on the screen then the return value is an empty list. <I>pathName</I> <B>margin</B> <B>cget</B> <I>marginID</I> <I>option</I> This command returns the current value of the option named option associated with the margin given by marginID. Option may have any of the values accepted by the pathName margin configure widget command. <I>pathName</I> <B>margin</B> <B>configure</B> <I>marginID</I> <I>?option?</I> <I>?value?</I> <I>?option</I> <I>value</I> <I>...?</I> This command is similar to the pathName configure widget command except that it modifies options associated with the margin given by marginID instead of modifying options for the overall text widget. If no option is specified, the command returns a list describing all of the avail- able options for marginID. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corre- sponding sublist of the value returned if no option is specified). If one or more option-value pairs are speci- fied, then the command modifies the given option(s) to have the given value(s) in marginID; in this case the command returns an empty string. <I>pathName</I> <B>margin</B> <B>count</B> Returns the number of margins <I>pathName</I> <B>margin</B> <B>dump</B> <I>marginID</I> <I>?option?</I> <I>Index1</I> <I>?Index2?</I> Return the contents of the text widget from index1 up to, but not including index2, including the text and informa- tion about marks, tags, and embedded windows. If index2 is not specified, then it defaults to one character past index1. The information is returned in the following for- mat:: key1 value1 index1 key2 value2 index2 ... The pos- sible key values are indicatoron, indicatoroff, text, mark, styleon, styleoff, tagon, and tagoff. The corre- sponding value is the indicator type, text, mark name, style number, or tag name. The index information is the index within the margin of the start of the indicator transition, style transition, text, mark, tag transition, image or window. One or more of the following switches Include information about indicator transitions in the dump results. Indicator information is returned as indi- catoron and indicatoroff elements that indicate the begin and end of each range of each indicator, respectively. <B>-mark</B> Include information about marks in the dump results. <B>-style</B> Include information about style transitions in the dump results. Style information is returned as styleon and styleoff elements that indicate the begin and end of each range of each style, respectively. <B>-tag</B> Include information about tag transitions in the dump results. Tag information is returned as tagon and tagoff elements that indicate the begin and end of each range of each tag, respectively. <B>-text</B> Include information about text in the dump results. The value is the text up to the next element or the end of range indicated by index2. A text element does not span newlines. A multi-line block of text that contains no marks or tag transitions will still be dumped as a set of text segments that each end with a newline. The newline is part of the value. <I>pathName</I> <B>margin</B> <B>fillnumbers</B> <I>marginID</I> <I>start</I> <I>count</I> <I>?tagName</I> <I>{line</I> <I>...}?</I> This would be used to manually managing filling a margin with line numbers. This is really only used for cases when control over the appearance of the line numbers is needed. The fillnumbers command would be called within the -linesaddedcommand callback function in a margin whose type was set to "lnums_alt". Setting the margin type to "lnums" would result in the Scintilla core code handling filling of the line numbers. The start option identifies where the line numbering should begin. The count option controls how many lines will be numbers. A value of <= 0 will number all lines from start until the end of the document. To apply custom styling to one or more line numbers, first configure a tag named tagName and then identify the list of line numbers as the argu- ment following tagName. For example, to fill the line numbers from 1 to 10 where only the odd numbers are styled in red, first create a tag (ex: $sci tag config red -margin -fg red) and then execute $sci margin fill- numbers 1 10 red {1 3 5 7 9}. <I>pathName</I> <B>margin</B> <B>hide</B> <I>marginID</I> Hides the margin specified by marginID. The margin's con- figuration information is maintained while hidden. <I>pathName</I> <B>margin</B> <B>index</B> <I>@X,Y</I> identifies which lines to add or remove the marker for. When removing, if the lines list is empty, then the spec- ified marker would be removed from all lines. Also, when removing, if the markerName is set to "*", then all mark- ers present for the specified lines would be removed. <I>pathName</I> <B>margin</B> <B>marker</B> <I>marginID</I> <I>list</I> <I>markerName</I> <I>?line?</I> This command returns a list of the lines containing the specified marker. If markerName is specified as "*" the line argument is required. When this done, the all mark- ers present on the specified line will be returned. <I>pathName</I> <B>margin</B> <B>names</B> Returns information about each of the margins. Each mar- gin is identified by a three element list containing the following: 1) the ID value of the margin (where "0" is the leftmost margin), 2) the type of the margin, and 3) the alias name, or an empty string if one hasn't been defined. <I>pathName</I> <B>margin</B> <B>show</B> <I>marginID</I> Shows the margin specified by marginID. For margins that have not yet had a width set (ie their width is zero), the show operation will report an error unless the mar- gin's type is set for linenumbers or the special fold margin. For those margins, the widget will automatically determine the appropriate width to use in order to allow the margin to be made visible. <I>pathName</I> <B>margin</B> <B>tag</B> <I>{line</I> <I>...}</I> <I>?tagName</I> <I>-clear?</I> This command will either add or remove a tag that was previously configured for use in the margin area (see here for more details). The margin tag will affect only text-based margins (ie not those holding symbols). The tag named tagName will be added to the list of lines unless the -clear option is specified, in which case the tag will be removed. When removing a tag, it can be removed from all lines by specifying an empty list for the lines. To remove all margin tags from all lines, the tagName option should not be specified (ie $sci margin tag {} -clear). <I>pathName</I> <B>margin</B> <B>text</B> <I>marginID</I> <I>command</I> <I>arglist</I> This command is used to manipulate the margin text within the margin specified by marginID. The margin specified by marginID must be of type text or rtext. The operation performed is controlled by the command argument, which would either be one of "clear", "get", or "set". If com- mand is "clear", and there is no arglist, then the margin text for all lines in the document is removed. If arglist is provided, it is a list of one or more lines to clear. If the command argument is "get", the arglist must spec- <I>pathName</I> <B>mark</B> <I>option</I> <I>?arg</I> <I>arg</I> <I>...?</I> This command is used to manipulate marks. The exact behavior of the command depends on the option argument that follows the mark argument. The following forms of the command are currently sup- ported: <I>pathName</I> <B>mark</B> <B>exists</B> <I>markName</I> If markName exists, the command will return 1; otherwise 0 is returned. <I>pathName</I> <B>mark</B> <B>gravity</B> <I>markName</I> <I>?direction?</I> If direction is not specified, returns left or right to indicate which of its adjacent characters markName is attached to. If direction is specified, it must be left or right; the gravity of markName is set to the given value. <I>pathName</I> <B>mark</B> <B>names</B> Returns a list whose elements are the names of all the marks that are currently set. <I>pathName</I> <B>mark</B> <B>next</B> <I>index</I> Returns the name of the next mark at or after index. If index is specified in numerical form, then the search for the next mark begins at that index. If index is the name of a mark, then the search for the next mark begins imme- diately after that mark. This can still return a mark at the same position if there are multiple marks at the same index. These semantics mean that the mark next operation can be used to step through all the marks in a text wid- get. An empty string is returned if there are no marks after index. <I>pathName</I> <B>mark</B> <B>previous</B> <I>index</I> Returns the name of the mark at or before index. If index is specified in numerical form, then the search for the previous mark begins with the character just before that index. If index is the name of a mark, then the search for the next mark begins immediately before that mark. This can still return a mark at the same position if there are multiple marks at the same index. These seman- tics mean that the mark previous operation can be used to step through all the marks in a text widget. An empty string is returned if there are no marks before index. <I>pathName</I> <B>mark</B> <B>set</B> <I>markName</I> <I>index</I> Sets the mark named markName to a position just before the character at index. If markName already exists, it is moved from its old position; if it does not exist, a new mark is created. This command returns an empty string. <I>pathName</I> <B>marker</B> <B>configure</B> <I>markerName</I> <I>?option?</I> <I>?value</I> <I>option</I> <I>value</I> <I>...?</I> This command is similar to the pathName configure widget command except that it modifies options associated with the marker given by markName instead of modifying options for the overall widget. If no option is specified, the command returns a list describing all of the available options for markerName. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corre- sponding sublist of the value returned if no option is specified). If one or more option-value pairs are speci- fied, then the command modifies the given option(s) to have the given value(s) in markerName; in this case the command returns an empty string. <I>pathName</I> <B>marker</B> <B>delete</B> <I>markerName</I> <I>?markerName</I> <I>...?</I> Deletes the named markers <I>pathName</I> <B>marker</B> <B>exists</B> <I>markerName</I> <I>line</I> Checks if the marker specified by markerName exists for line. Returns 1 if it does, 0 otherwise. <I>pathName</I> <B>marker</B> <B>names</B> Returns a sorted list of all currently defined markers (created by using the marker configure command). <I>pathName</I> <B>marker</B> <B>types</B> Returns the list of type names which can be used with the -type option to the configure command. <I>pathName</I> <B>search</B> <I>?switches?</I> <I>pattern</I> <I>index</I> <I>?stopIndex?</I> Searches the text in pathName starting at index for a range of characters that matches pattern. If a match is found, the index of the first character in the match is returned as result; oth- erwise an empty string is returned. One or more of the following switches (or abbreviations thereof) may be specified to control the search: <B>-forwards</B> The search will proceed forward through the text, finding the first matching range starting at or after the posi- tion given by index. This is the default. <B>-backwards</B> The search will proceed backward through the text, find- ing the matching range closest to index whose first char- acter is before index (it is not allowed to be at index). Note that, for a variety of reasons, backwards searches can be substantially slower than forwards searches (par- ticularly when using -regexp), so it is recommended that performance-critical code use forward searches. <B>-nolinestop</B> This allows . and [^ sequences to match the newline char- acter 0 which they will otherwise not do (see the regexp command for details). This option is only meaningful if -regexp is also given, and an error will be thrown other- wise. For example, to match the entire text, use pathName search -nolinestop -regexp ".*" 1.0. <B>-nocase</B> Ignore case differences between the pattern and the text. <B>-count</B> <I>varName</I> The argument following -count gives the name of a vari- able; if a match is found, the number of index positions between beginning and end of the matching range will be stored in the variable. If there are no embedded images or windows in the matching range (and there are no elided characters if -elide is not given), this is equivalent to the number of characters matched. In either case, the range matchIdx to matchIdx + $count chars will return the entire matched text. <B>-all</B> Find all matches in the given range and return a list of the indices of the first character of each match. If a -count varName switch is given, then varName is also set to a list containing one element for each successful match. Note that, even for exact searches, the elements of this list may be different, if there are embedded images, windows or hidden text. Searches with -all behave very similarly to the Tcl command regexp -all, in that overlapping matches are not normally returned. For exam- ple, applying an -all search of the pattern 1992Z against ZooZooZoo will just match once. <B>-overlap</B> When performing -all searches, the normal behaviour is that matches which overlap an already-found match will not be returned. This switch changes that behaviour so that all matches which are not totally enclosed within another match are returned. For example, applying an -overlap search of the pattern 2304Z against ZooZooZoo will now match twice. An error will be thrown if this switch is used without -all. <B>-strictlimits</B> When performing any search, the normal behaviour is that the start and stop limits are checked with respect to the start of the matching text. With the -strictlimits flag, the entire matching range must lie inside the start and stop limits specified for the match to be valid. searches, no match at or after stopIndex will be considered; for back- ward searches, no match earlier in the text than stopIndex will be con- sidered. If stopIndex is omitted, the entire text will be searched: when the beginning or end of the text is reached, the search continues at the other end until the starting location is reached again; if stopIndex is specified, no wrap-around will occur. This means that, for example, if the search is -forwards but stopIndex is earlier in the text than startIndex, nothing will ever be found. See the Tk Text wid- get man page for more information. <I>pathName</I> <B>scisearch</B> <I>?switches?</I> <I>pattern</I> <I>index</I> <I>?stopIndex?</I> Scintilla Search searches the text in pathName starting at index for a range of characters that matches pattern. If a match is found, the index of the first character in the match is returned as result; otherwise an empty string is returned. One or more of the following switches (or abbreviations thereof) may be speci- fied to control the search: <B>-forwards</B> The search will proceed forward through the text, finding the first matching range starting at or after the posi- tion given by index. This is the default. <B>-backwards</B> The search will proceed backward through the text, find- ing the matching range closest to index whose first char- acter is before index (it is not allowed to be at index). <B>-count</B> <I>varName</I> The argument following -count gives the name of a vari- able; if a match is found, the number of index positions between beginning and end of the matching range will be stored in the variable. <B>-exact</B> Use exact matching: the characters in the matching range must be identical to those in pattern. This is the default. <B>-nocase</B> Ignore case differences between the pattern and the text. <B>-regexp</B> Treat pattern as a regular expression. In a regular expression, special characters interpreted are: Matches any character. <B>\(</B> This marks the start of a region for tagging a match. <B>\)</B> This marks the end of a tagged region. <B>\x</B> This allows you to use a character x that would otherwise have a special meaning. For example, \[ would be interpreted as [ and not as the start of a character set. <B>[...]</B> This indicates a set of characters, for example, [abc] means any of the characters a, b or c. You can also use ranges, for example [a-z] for any lower case character. <B>[^...]</B> The complement of the characters in the set. For example, [^A-Za-z] means any character except an alphabetic character. <B>^</B> This matches the start of a line (unless used inside a set, see above). <B>$</B> This matches the end of a line. <B>*</B> This matches 0 or more times. For example, Sa*m matches Sm, Sam, Saam, Saaam and so on. <B>+</B> This matches 1 or more times. For example, Sa+m matches Sam, Saam, Saaam and so on. Regular expressions will only match ranges within a single line, never matching over multiple lines. <B>-word</B> A match only occurs if the characters before and after are not word characters. <B>--</B> This switch has no effect except to terminate the list of switches: the next argument will be treated as pattern even if it starts with -. The matching range must be within a single line of text. For regular expression matching one can use the various newline-matching features such as $ to match the end of a line, ^ to match the beginning of a line. If stopIndex is specified, the search stops at that index: for forward searches, no match at or after stopIndex will be considered; for backward searches, no match earlier in the text than stopIndex will be considered. If stopIndex is omitted, the entire text will be searched. <I>pathName</I> <B>see</B> <I>index</I> <I>?-center?</I> Adjusts the view in the window so that the character given by index is completely visible. If index is already visible then the command does nothing. If index is a short distance out of view, the command adjusts the view just enough to make index visible at the edge of the window. If index is far out of view, then the command centers index in the window. The -center option can be used to force index to be centered in the window. <I>pathName</I> <B>tag</B> <I>?option?</I> <I>?arg</I> <I>arg</I> <I>...?</I> <I>pathName</I> <B>tag</B> <B>add</B> <I>tagName</I> <I>index1</I> <I>?index2?</I> Associate the tag tagName (one will be created if it doesn't already exist) with all of the characters start- ing with index1 and ending just before index2 (the char- acter at index2 is not tagged). If index2 is omitted then the single character at index1 is tagged. If there are no characters in the specified range (e.g. index1 is past the end of the file or index2 is less than or equal to index1) then the command has no effect. EXCEPTION: If tagName is the predefined selection tag (i.e. "sel"), then specifying index2 to be less than index1 will have the effect of positioning the insertion point at the start of the selection. <I>pathName</I> <B>tag</B> <B>bind</B> <I>tagName</I> <I>?sequence?</I> <I>?script?</I> This command associates script with the tag given by tag- Name. Whenever the event sequence given by sequence occurs for a character that has been tagged with tagName, the script will be invoked. This widget command is simi- lar to the bind command except that it operates on char- acters in a text rather than entire widgets. See the bind manual entry for complete details on the syntax of sequence and the substitutions performed on script before invoking it. If all arguments are specified then a new binding is created, replacing any existing binding for the same sequence and tagName (if the first character of script is + then script augments an existing binding rather than replacing it). In this case the return value is an empty string. If script is omitted then the command returns the script associated with tagName and sequence (an error occurs if there is no such binding). If both script and sequence are omitted then the command returns a list of all the sequences for which bindings have been defined for tagName. The only events for which bindings may be specified are those related to the mouse and key- board (such as Enter, Leave, ButtonPress, Motion, and KeyPress) or virtual events. Event bindings for a text widget use the current mark. An Enter event triggers for a tag when the tag first becomes present on the current character, and a Leave event triggers for a tag when it ceases to be present on the current character. Enter and Leave events can happen either because the current mark moved or because the character at that position changed. Note that these events are different than Enter and Leave events for windows. Mouse and keyboard events are directed to the current character. If a virtual event is used in a binding, that binding can trigger only if the virtual event is defined by an underlying mouse-related or keyboard-related event. <I>pathName</I> <B>tag</B> <B>cget</B> <I>tagName</I> <I>option</I> named option (this list will be identical to the corre- sponding sublist of the value returned if no option is specified). If one or more option-value pairs are speci- fied, then the command modifies the given option(s) to have the given value(s) in tagName; in this case the com- mand returns an empty string. Note, the special -margin option, if used, must immediately follow tagName. It is used to create and configure tags used within the margin area. See "configure options" for more details <I>pathName</I> <B>tag</B> <B>delete</B> <I>tagName</I> <I>?tagName</I> <I>...?</I> Deletes all tag information for each of the tagName argu- ments. The command removes the tags from all characters in the file and also deletes any other information asso- ciated with the tags, such as bindings and display infor- mation. The command returns an empty string. <I>pathName</I> <B>tag</B> <B>lower</B> <I>tagName</I> This has NOT BEEN IMPLEMENTED because Scintilla core functionality regarding "markers" (which is how the Scin- tillaTk tag functionality has been implemented) does not support drawing priority for markers that overlap. <I>pathName</I> <B>tag</B> <B>names</B> <I>?index?</I> Returns a list whose elements are the names of all the tags that are active at the character position given by index. If index is omitted, then the return value will describe all of the tags that exist for the widget. <I>pathName</I> <B>tag</B> <B>nextrange</B> <I>tagName</I> <I>index1</I> <I>?index2?</I> This command searches the text for a range of characters tagged with tagName where the first character of the range is no earlier than the character at index1 and no later than the character just before index2 (a range starting at index2 will not be considered). The command's return value is a list containing two elements, which are the index of the first character of the range and the index of the character just after the last one in the range. If no matching range is found then the return value is an empty string. If index2 is not given then it defaults to the end of the text. <I>pathName</I> <B>tag</B> <B>prevrange</B> <I>tagName</I> <I>index1</I> <I>?index2?</I> This command searches the text for a range of characters tagged with tagName where the first character of the range is before the character at index1 and no earlier than the character at index2 (a range starting at index2 will be considered). The command's return value is a list containing two elements, which are the index of the first character of the range and the index of the character just after the last one in the range. If no matching range is found then the return value is an empty string. The first element of each pair contains the index of the first character of the range, and the second element of the pair contains the index of the character just after the last one in the range. If there are no characters tagged with tag then an empty string is returned. <I>pathName</I> <B>tag</B> <B>remove</B> <I>tagName</I> <I>index1</I> <I>?index2</I> <I>index1</I> <I>index2</I> <I>...?</I> Remove the tag tagName from all of the characters start- ing at index1 and ending just before index2 (the charac- ter at index2 is not affected). A single command may con- tain any number of index1-index2 pairs. If the last index2 is omitted then the tag is removed from the single character at index1. If there are no characters in the specified range (e.g. index1 is past the end of the file or index2 is less than or equal to index1) then the com- mand has no effect. This command returns an empty string. <B>Tag</B> <B>Types</B> +----------------------------------------------------------------------------------+ |<B>Type</B> <B>ID</B> <B>Description</B> | |plain 0 Underlined with a single, straight line. | |squiggle 1 A squiggly underline, 3 pixels in height | |tt 2 A line of small "T" shapes | |diagonal 3 Diagonal hatching | |strike 4 A solid "strike through" line draw at the vertical mid-point | |hidden 5 No visual effect | |box 6 A rectangular box around the text | |roundbox 7 A rectangle with rounded corners around the text, using | | translucent drawing for the interior (NOT SUPPORTED YET) | |squarebox 8 A rectangle around the text, using translucent drawing for | | the interior (NOT SUPPORTED YET) | |dash 9 A dashed underline | |dots 10 A dotted underline | |squigglelow 11 Similar to squiggle but only 2 pixels in height | |dotbox 12 A dotted rectangle around the text, using translucent draw- | | ing for the interior (NOT SUPPORTED YET) | +----------------------------------------------------------------------------------+ For the above types, use the -foreground configuration option for the tag to control the color. For types that use a filled interior, use the -background option to set the interior color. The following lists the supported configuration options, though not all are supported for each type of tag (exceptions are noted): <B>-background|-bg</B> <I>color</I> Color specifies the color used for tags that have a filled inte- rior. <B>-bold</B> <I>boolean</I> (ONLY FOR MARGIN TAGS) Specifies if margins showing text will use a bold font <B>-foreground|-fg</B> <I>color</I> current version of the widget. The fields of the list are: ver- sion : identifies the Tcl package version date : the date the package was created core_rls: this identifies the release of the Scintilla core widget </PRE> <H2>KNOWN BUGS</H2><PRE> Patterns including newline (0 may not work correctly in all cases. This limitation is due to how Scintilla stores document text; the end of line characters are stripped from the document making the search chal- lenging. The pathName search -regexp sub-command attempts to perform sophisti- cated regexp matching across multiple lines in an efficient fashion. Under certain conditions the search result might differ from that obtained by applying the same regexp to the entire text from the widget in one go. Whenever one possible match is fully enclosed in another, the search command will attempt to ensure only the larger match is returned. When performing backwards regexp searches it is possible that Tcl will not always achieve this. Tk 0.25 scintilla(n) </PRE> <HR> <ADDRESS> Man(1) output converted with <a href="http://www.oac.uci.edu/indiv/ehood/man2html.html">man2html</a> </ADDRESS> </BODY> </HTML> |
Added tk/doc/scintillatk.n.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 |
'\" .\" .\" .DE .\" End of indented unfilled display. .\" .\" .SO ?manpage? .\" Start of list of standard options for a Tk widget. The manpage .\" argument defines where to look up the standard options; if .\" omitted, defaults to "options". The options follow on successive .\" lines, in three columns separated by tabs. .\" .\" .SE .\" End of list of standard options for a Tk widget. .\" .\" .OP cmdName dbName dbClass .\" Start of description of a specific option. cmdName gives the .\" option's name as specified in the class command, dbName gives .\" the option's name in the option database, and dbClass gives .\" the option's class in the option database. .\" .\" .UL arg1 arg2 .\" Print arg1 underlined, then print arg2 normally. .\" .\" .QW arg1 ?arg2? .\" Print arg1 in quotes, then arg2 normally (for trailing punctuation). .\" .\" .PQ arg1 ?arg2? .\" Print an open parenthesis, arg1 in quotes, then arg2 normally .\" (for trailing punctuation) and then a closing parenthesis. .\" .\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages. .if t .wh -1.3i ^B .nr ^l \n(.l .ad b .\" # Start an argument description .de AP .ie !"\\$4"" .TP \\$4 .el \{\ . ie !"\\$2"" .TP \\n()Cu . el .TP 15 .\} .ta \\n()Au \\n()Bu .ie !"\\$3"" \{\ \&\\$1 \\fI\\$2\\fP (\\$3) .\".b .\} .el \{\ .br .ie !"\\$2"" \{\ \&\\$1 \\fI\\$2\\fP .\} .el \{\ \&\\fI\\$1\\fP .\} .\} .. .\" # define tabbing values for .AP .de AS .nr )A 10n .if !"\\$1"" .nr )A \\w'\\$1'u+3n .nr )B \\n()Au+15n .\" .if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n .nr )C \\n()Bu+\\w'(in/out)'u+2n .. .AS Tcl_Interp Tcl_CreateInterp in/out .\" # BS - start boxed text .\" # ^y = starting y location .\" # ^b = 1 .de BS .br .mk ^y .nr ^b 1u .if n .nf .if n .ti 0 .if n \l'\\n(.lu\(ul' .if n .fi .. .\" # BE - end boxed text (draw box now) .de BE .nf .ti 0 .mk ^t .ie n \l'\\n(^lu\(ul' .el \{\ .\" Draw four-sided box normally, but don't draw top of .\" box if the box started on an earlier page. .ie !\\n(^b-1 \{\ \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' .\} .el \}\ \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' .\} .\} .fi .br .nr ^b 0 .. .\" # VS - start vertical sidebar .\" # ^Y = starting y location .\" # ^v = 1 (for troff; for nroff this doesn't matter) .de VS .if !"\\$2"" .br .mk ^Y .ie n 'mc \s12\(br\s0 .el .nr ^v 1u .. .\" # VE - end of vertical sidebar .de VE .ie n 'mc .el \{\ .ev 2 .nf .ti 0 .mk ^t \h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n' .sp -1 .fi .ev .\} .nr ^v 0 .. .\" # Special macro to handle page bottom: finish off current .\" # box/sidebar if in box/sidebar mode, then invoked standard .\" # page bottom macro. .de ^B .ev 2 'ti 0 'nf .mk ^t .if \\n(^b \{\ .\" Draw three-sided box if this is the box's first page, .\" draw two sides but no top otherwise. .ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c .el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c .\} .if \\n(^v \{\ .nr ^x \\n(^tu+1v-\\n(^Yu \kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c .\} .bp 'fi .ev .if \\n(^b \{\ .mk ^y .nr ^b 2 .\} .if \\n(^v \{\ .mk ^Y .\} .. .\" # DS - begin display .de DS .RS .nf .sp .. .\" # DE - end display .de DE .fi .RE .sp .. .\" # SO - start of list of standard options .de SO 'ie '\\$1'' .ds So \\fBoptions\\fR 'el .ds So \\fB\\$1\\fR .SH "STANDARD OPTIONS" .LP .nf .ta 5.5c 11c .ft B .. .\" # SE - end of list of standard options .de SE .fi .ft R .LP See the \\*(So manual entry for details on the standard options. .. .\" # OP - start of full description for a single option .de OP .LP .nf .ta 4c Command-Line Name: \\fB\\$1\\fR Database Name: \\fB\\$2\\fR Database Class: \\fB\\$3\\fR .fi .IP .. .\" # CS - begin code excerpt .de CS .RS .nf .ta .25i .5i .75i 1i .. .\" # CE - end code excerpt .de CE .fi .RE .. .\" # UL - underline word .de UL \\$1\l'|0\(ul'\\$2 .. .\" # QW - apply quotation marks to word .de QW .ie '\\*(lq'"' ``\\$1''\\$2 .\"" fix emacs highlighting .el \\*(lq\\$1\\*(rq\\$2 .. .\" # PQ - apply parens and quotation marks to word .de PQ .ie '\\*(lq'"' (``\\$1''\\$2)\\$3 .\"" fix emacs highlighting .el (\\*(lq\\$1\\*(rq\\$2)\\$3 .. .\" # QR - quoted range .de QR .ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3 .\"" fix emacs highlighting .el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3 .. .\" # MT - "empty" string .de MT .QW "" .. .TH scintilla n 0.25 Tk "ScintillaTK Text Widget" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME scintilla \- Scintilla text widget .SH SYNOPSIS \fBpackage require scintillatk\fR ?\fB0.25\fR? .sp \fBscintilla\fR \fIpathName \fR?\fIoptions\fR? .SO \-autoseparators \-highlight \-moveupdatecommand \-background \-highlightthickness \-relief \-blink \-highlightbackground \-showws \-borderwidth \-language \-state \-busycursor \-linesaddedcommand \-tabwidth \-cursor \-marginbackground \-takefocus \-foldstyle \-marginbg \-xscrollcommand \-font \-marginforeground \-yscrollcommand \-foreground \-marginfg \-undo \-height \-marginwidthcommand \-width .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-autoseparators autoSeparators AutoSeparators Specifies a boolean that says whether separators are automatically inserted in the undo stack. Only meaningful when the \fB\-undo\fR option is true. .OP \-height height Height Specifies the desired height for the window, in units of characters in the font given by the \fB\-font\fR option. Must be at least one. .OP \-state state State Specifies one of two states for the text: \fBnormal\fR or \fBdisabled\fR. If the text is disabled then characters may not be inserted or deleted and no insertion cursor will be displayed, even if the input focus is in the widget. .OP \-width width Width Specifies the desired width for the window in units of characters in the font given by the \fB\-font\fR option. If the font does not have a uniform width then the width of the character .QW 0 is used in translating from character units to screen units. .OP \-busycursor cursor Cursor Cursor to display when text widget is computationally busy. .OP \-foldstyle foldstyle FoldStyle See Scintilla documentation for style values. .OP \-language language Language Specifies which programming language lexer to use for syntax highlighting. .OP \-linesaddedcommand lindesAddedCommand LinesAddedCommand Callback command when new lines are inserted in the document. This function can be used to update margin indicators if necessary. .OP \-marginbackground marginBackground MarginBackground The backgound color of the margin columns. .OP \-marginforeground marginForeground MarginForeground The foregound (font) color of the margin columns. .OP \-marginwidthcommand Callback command used when margin width changes. .OP \-moveupdatecommand moveUpdateCommand MoveUpdateCommand Callback command when margin changes. .OP \-showws showws ShowWs Show the ws??? .BE .SH DESCRIPTION .PP The \fBscintilla\fR command creates a new window (given by the \fIpathName\fR arg) and makes it into a Scintilla text widget. Additional options, described above, may be specified on the command line or in the option database to configure aspects of the text such as its default background color and relief. The \fBtext\fR command returns the path name of the new window. .PP .SH "WIDGET COMMAND" .PP .TP \fIpathName \fBannotate \fIoption ?arg arg ...?\fR Text annotations are separate strings that can be assigned to the lines within the document. The annotation is displayed without any line numbers and appears in extra space which is created by the widget for its display. There are various options available: .RS .TP \fBclearall\fR removes annotation strings for all lines .TP \fBget \fIline\fR Returns the annotation text for the specified line. .TP \fBset \fIline text ?tagName text tagName ...?\fR Assigns the specified text string to the specified line. If no tagName option is specified, the annotation text will use the default text styling. If a single tagName option is used it will control the appearance for all of the annotation text. By using multiple text and tagName options it's possible to have different appearances for different subranges of the text. .TP \fBshow \fI0|1|2\fR Used to control the display of annotations where 0 - hiding, 1 - showing or 2 - showing with a bounding box. Note, this affects all lines with annotations. .RE .TP \fIpathName \fBbbox \fIindex\fR Returns a list of four elements describing the screen area of the character given by index. The first two elements of the list give the x and y coordinates of the upper\-left corner of the area occupied by the character, and the last two elements give the width and height of the area. If the character is not visible on the screen then the return value is an empty list. .TP \fIpathName \fBcget \fIoption\fR Returns the current value of the configuration option given by option. Option may have any of the values accepted by the scintilla command. .TP \fIpathName \fBcompare \fIindex1 op index2\fR Compares the indices given by index1 and index2 according to the relational operator given by op, and returns 1 if the relationship is satisfied and 0 if it is not. Op must be one of the operators <, <=, =, >, >, or !. If op is == then 1 is returned if the two indices refer to the same character, if op is < then 1 is returned if index1 refers to an earlier character in the text than index2, and so on. .TP \fIpathName \fBconfigure \fI?option? ?value option value ...?\fR Query or modify the configuration options of the widget. If no option is specified, returns a list describing all of the available options for pathName. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). If one or more option\-value pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. Option may have any of the values accepted by the scintilla command. .TP \fIpathName \fBcount \fI?options? index1 index2\fR Counts the number of relevant things between the two indices. If index1 is after index2, the result will be a negative number (and this holds for each of the possible options). The actual items which are counted depend on the options given. The result is a list of integers, one for the result of each counting option given. Valid counting options are \-chars, \-displaylines and \-lines. The default value, if no option is specified, is \-chars. The count options are interpreted as follows: .RS .IP \fB\-chars\fR count all characters, whether elided or not. Do not count embedded windows or images. .IP \fB\-displaylines\fR count all display lines (i.e. ignore lines which are folded) from the line of the first index up to, but not including the display line of the second index. Therefore if they are both on the same display line, zero will be returned. By definition displaylines are visible and therefore this only counts portions of actual visible lines. .IP \fB\-lines\fR count all lines (irrespective of folding) from the line of the first index up to, but not including the line of the second index. Therefore if they are both on the same line, zero will be returned. Lines are counted whether they are currently visible (non\-folded) or not. .RE .TP \fIpathName \fBdelete \fIindex1 ?index2?\fR Delete a range of characters from the text. If both index1 and index2 are specified, then delete all the characters starting with the one given by index1 and stopping just before index2 (i.e. the character at index2 is not deleted). If index2 doesn't specify a position later in the text than index1 then no characters are deleted. If index2 isn't specified then the single character at index1 is deleted. It is not allowable to delete characters in a way that would leave the text without a newline as the last character. The command returns an empty string. .TP \fIpathName \fBdump \fI?switches? index1 ?index2?_\fR Return the contents of the text widget from index1 up to, but not including index2, including the text and information about marks, tags, and embedded windows. If index2 is not specified, then it defaults to one character past index1. The information is returned in the following format:: key1 value1 index1 key2 value2 index2 ... The possible key values are indicatoron, indicatoroff, text, mark, styleon, styleoff, tagon, tagoff, image, and window. The corresponding value is the indicator type, text, mark name, style number, tag name, image name, or window name. The index information is the index of the start of the indicator transition, style transition, text, mark, tag transition, image or window. The image and window options are not supported and will return nothing. One or more of the following switches (or abbreviations thereof) may be specified to control the dump: .RS .IP \fB\-all\fR Return information about all elements: indicator, style, text, marks, tags, images and windows. This is the default. .TP \fB\-command \fIcommand\fR Instead of returning the information as the result of the dump operation, invoke the command on each element of the text widget within the range. The command has three arguments appended to it before it is evaluated: the key, value, and index. .TP \fB\-image\fR Include information about images in the dump results. This option is unsupported in Scintilla. .TP \fB\-indicator\fR Include information about indicator transitions in the dump results. Indicator information is returned as indicatoron and indicatoroff elements that indicate the begin and end of each range of each indicator, respectively. .TP \fB\-mark\fR Include information about marks in the dump results. .TP \fB\-style\fR Include information about style transitions in the dump results. Style information is returned as styleon and styleoff elements that indicate the begin and end of each range of each style, respectively. .TP \fB\-tag\fR Include information about tag transitions in the dump results. Tag information is returned as tagon and tagoff elements that indicate the begin and end of each range of each tag, respectively. .TP \fB\-text\fR Include information about text in the dump results. The value is the text up to the next element or the end of range indicated by index2. A text element does not span newlines. A multi\-line block of text that contains no marks or tag transitions will still be dumped as a set of text segments that each end with a newline. The newline is part of the value. .TP \fB\-window\fR Include information about embedded windows in the dump results. This option is unsupported in Scintilla. .RE .TP \fIpathName \fBedit \fIoption ?arg arg ...?\fR This command controls the undo mechanism and the modified flag. The exact behavior of the command depends on the option argument that follows the edit argument. The following forms of the command are currently supported: .RS .TP \fIpathName \fBedit canredo\fR Returns true if the redo stack is not empty. .TP \fIpathName \fBedit canundo\fR Returns true if the undo stack is not empty. .TP \fIpathName \fBedit Imodified \fI?boolean?\fR If boolean is not specified, returns the modified flag of the widget. The insert, delete, edit undo and edit redo commands or the user can set or clear the modified flag. If boolean is specified, sets the modified flag of the widget to boolean. .TP \fIpathName \fBedit redo\fR When the \-undo option is true, reapplies the last undone edits provided no other edits were done since then. Generates an error when the redo stack is empty. Does nothing when the \-undo option is false. .TP \fIpathName \fBedit reset\fR Clears the undo and redo stacks. .TP \fIpathName \fBedit separator\fR Inserts a separator (boundary) on the undo stack. Does nothing when the \-undo option is false. .TP \fIpathName \fBedit undo\fR Undoes the last edit action when the \-undo option is true. An edit action is defined as all the insert and delete commands that are recorded on the undo stack in between two separators. Generates an error when the undo stack is empty. Does nothing when the \-undo option is false. .RE .TP \fIpathName \fBfold \fIcommand ?line?\fR The fold command provides various capabilities related to Scintilla's folding functionality. Some operations are simple queries while others will impact the fold structure within the document. The following commands are supported: .RS .TP \fBfoldall\fR folds all lines within the document .TP \fBfoldbelow \fIline\fR folds all lines which are after(below) line number line .TP \fBfoldparent \fIline\fR returns the line containing the immediate fold parent of line .TP \fBfoldroot \fIline\fR returns the line containing topmost fold parent of the specified line . This is at the top of the fold hierarchy containing line . .TP \fBisfolded \fIline\fR return 1 if line contained in a folded parent, and 0 if it isn't .TP \fBshow \fIline\fR fully expand the containing fold hierarchy such that line is visible .TP \fBtoggle \fIline\fR toggle the fold state of line (ie if collapsed, expand it; if expanded, collapse it) .TP \fBtopunfolded \fIline\fR return the line of the highest fold parent for line which is currently expanded .TP \fBunfoldall\fR unfold all lines .TP \fBunfoldbelow \fIline\fR unfold all lines which are after(below) line number line .RE .TP \fIpathName \fBindex \fIindex ?\-textonly?\fR Returns the position corresponding to index in the form line.char where line is the line number and char is the character number. See the documentation for the Tk Text widget for a description of the formats used to specify indices. NOTE: Specifying an X/Y location that corresponds to a line of annotation text will return the index for the end of the line associated with the annotation. If the \-textonly option is used, then an empty string is returned if the X/Y location is over an annotation. .TP \fIpathName \fBinsert \fIindex chars\fR Inserts all of the chars argument just before the character at index. If index refers to the end of the text (the character after the last newline) then the new text is inserted just before the last newline instead. .RE .TP \fIpathName \fBmargin \fIoption ?arg arg ...?\fR This command is used to manage the widget's various margins (aka columns). The exact behavior of the command depends on the option argument that follows the margin argument. In most of the subcommands below, there is an argument which identifies the margin. It is labeled "marginID" in the following descriptions. The format of this argument can be any of the following: 1) the numeric index of the margin, where "0" is the leftmost margin, and "4" is rightmost, 2) the name of the margin, which will match the margin's type (eg "text", "symbol", etc), or 3) the alias name defined for the margin. The following forms of the command are currently supported: .RS .TP \fIpathName \fBmargin bbox \fImarginID line\fR Returns a list of four elements describing the screen area of the margin identified by marginID, at the line specified by line. The first two elements of the list give the x and y coordinates of the upper\-left corner of the area occupied by the character, and the last two elements give the width and height of the area. If the character is not visible on the screen then the return value is an empty list. .TP \fIpathName \fBmargin cget \fImarginID option\fR This command returns the current value of the option named option associated with the margin given by marginID. Option may have any of the values accepted by the pathName margin configure widget command. .TP \fIpathName \fBmargin configure \fImarginID ?option? ?value? ?option value ...?\fR This command is similar to the pathName configure widget command except that it modifies options associated with the margin given by marginID instead of modifying options for the overall text widget. If no option is specified, the command returns a list describing all of the available options for marginID. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). If one or more option\-value pairs are specified, then the command modifies the given option(s) to have the given value(s) in marginID; in this case the command returns an empty string. .TP \fIpathName \fBmargin count\fR Returns the number of margins .TP \fIpathName \fBmargin dump \fImarginID ?option? Index1 ?Index2?\fR Return the contents of the text widget from index1 up to, but not including index2, including the text and information about marks, tags, and embedded windows. If index2 is not specified, then it defaults to one character past index1. The information is returned in the following format:: key1 value1 index1 key2 value2 index2 ... The possible key values are indicatoron, indicatoroff, text, mark, styleon, styleoff, tagon, and tagoff. The corresponding value is the indicator type, text, mark name, style number, or tag name. The index information is the index within the margin of the start of the indicator transition, style transition, text, mark, tag transition, image or window. One or more of the following switches (or abbreviations thereof) may be specified to control the dump: .TP \fB\-all\fR Return information about all elements: indicator, style, text, marks, and tags. This is the default. .TP \fB\-command \fIcommand\fR Instead of returning the information as the result of the dump operation, invoke the command on each element of the text widget within the range. The command has three arguments appended to it before it is evaluated: the key, value, and index. .TP \fB\-indicator\fR Include information about indicator transitions in the dump results. Indicator information is returned as indicatoron and indicatoroff elements that indicate the begin and end of each range of each indicator, respectively. .TP \fB\-mark\fR Include information about marks in the dump results. .TP \fB\-style\fR Include information about style transitions in the dump results. Style information is returned as styleon and styleoff elements that indicate the begin and end of each range of each style, respectively. .TP \fB\-tag\fR Include information about tag transitions in the dump results. Tag information is returned as tagon and tagoff elements that indicate the begin and end of each range of each tag, respectively. .TP \fB\-text\fR Include information about text in the dump results. The value is the text up to the next element or the end of range indicated by index2. A text element does not span newlines. A multi\-line block of text that contains no marks or tag transitions will still be dumped as a set of text segments that each end with a newline. The newline is part of the value. .TP \fIpathName \fBmargin fillnumbers \fImarginID start count ?tagName {line ...}?\fR This would be used to manually managing filling a margin with line numbers. This is really only used for cases when control over the appearance of the line numbers is needed. The fillnumbers command would be called within the \-linesaddedcommand callback function in a margin whose type was set to "lnums_alt". Setting the margin type to "lnums" would result in the Scintilla core code handling filling of the line numbers. The start option identifies where the line numbering should begin. The count option controls how many lines will be numbers. A value of <= 0 will number all lines from start until the end of the document. To apply custom styling to one or more line numbers, first configure a tag named tagName and then identify the list of line numbers as the argument following tagName. For example, to fill the line numbers from 1 to 10 where only the odd numbers are styled in red, first create a tag (ex: $sci tag config red \-margin \-fg red) and then execute $sci margin fillnumbers 1 10 red {1 3 5 7 9}. .TP \fIpathName \fBmargin hide \fImarginID\fR Hides the margin specified by marginID. The margin's configuration information is maintained while hidden. .TP \fIpathName \fBmargin index \fI@X,Y\fR Returns a list of three elements to identify the margin at the location indicated by the X and Y window location (where "@0,0" corresponds to the upperleft corner of the window). If a margin exists at the location, then the three values returned are: 1) the margin id, 2) the line number, and 3) the margin's alias (or an empty string if it an alias hasn't been defined). If the X/Y location isn't over a margin then an empty string is returned. .TP \fIpathName \fBmargin marker \fImarginID command markerName lines\fR This command is used to add or remove the marker named markerName to the margin specified by marginID. The operation performed is controlled by the command argument, which would either be "add" or "clear". The lines option identifies which lines to add or remove the marker for. When removing, if the lines list is empty, then the specified marker would be removed from all lines. Also, when removing, if the markerName is set to "*", then all markers present for the specified lines would be removed. .TP \fIpathName \fBmargin marker \fImarginID list markerName ?line?\fR This command returns a list of the lines containing the specified marker. If markerName is specified as "*" the line argument is required. When this done, the all markers present on the specified line will be returned. .TP \fIpathName \fBmargin names\fR Returns information about each of the margins. Each margin is identified by a three element list containing the following: 1) the ID value of the margin (where "0" is the leftmost margin), 2) the type of the margin, and 3) the alias name, or an empty string if one hasn't been defined. .TP \fIpathName \fBmargin show \fImarginID\fR Shows the margin specified by marginID. For margins that have not yet had a width set (ie their width is zero), the show operation will report an error unless the margin's type is set for linenumbers or the special fold margin. For those margins, the widget will automatically determine the appropriate width to use in order to allow the margin to be made visible. .TP \fIpathName \fBmargin tag \fI{line ...} ?tagName \-clear?\fR This command will either add or remove a tag that was previously configured for use in the margin area (see here for more details). The margin tag will affect only text\-based margins (ie not those holding symbols). The tag named tagName will be added to the list of lines unless the \-clear option is specified, in which case the tag will be removed. When removing a tag, it can be removed from all lines by specifying an empty list for the lines. To remove all margin tags from all lines, the tagName option should not be specified (ie $sci margin tag {} \-clear). .TP \fIpathName \fBmargin text \fImarginID command arglist\fR This command is used to manipulate the margin text within the margin specified by marginID. The margin specified by marginID must be of type text or rtext. The operation performed is controlled by the command argument, which would either be one of "clear", "get", or "set". If command is "clear", and there is no arglist, then the margin text for all lines in the document is removed. If arglist is provided, it is a list of one or more lines to clear. If the command argument is "get", the arglist must specify the line number of the margin text to return. If the command argument is "set", the arglist consists of a string value to set in the margin followed by one or more line numbers that should be modified. .TP \fIpathName \fBmargin visible \fImarginID\fR Returns if the margin specified by marginID is currently being shown. This is different from checking if the margin's configuration value for the \-width option is zero, because when a margin is hidden its width value is retained so that it can be shown with the intended width. .TP \fIpathName \fBmargin width\fR Return the total width in pixels of the visible margins. .RE .TP \fIpathName \fBmark \fIoption ?arg arg ...?\fR This command is used to manipulate marks. The exact behavior of the command depends on the option argument that follows the mark argument. The following forms of the command are currently supported: .RS .TP \fIpathName \fBmark exists \fImarkName\fR If markName exists, the command will return 1; otherwise 0 is returned. .TP \fIpathName \fBmark gravity \fImarkName ?direction?\fR If direction is not specified, returns left or right to indicate which of its adjacent characters markName is attached to. If direction is specified, it must be left or right; the gravity of markName is set to the given value. .TP \fIpathName \fBmark names\fR Returns a list whose elements are the names of all the marks that are currently set. .TP \fIpathName \fBmark next \fIindex\fR Returns the name of the next mark at or after index. If index is specified in numerical form, then the search for the next mark begins at that index. If index is the name of a mark, then the search for the next mark begins immediately after that mark. This can still return a mark at the same position if there are multiple marks at the same index. These semantics mean that the mark next operation can be used to step through all the marks in a text widget. An empty string is returned if there are no marks after index. .TP \fIpathName \fBmark previous \fIindex\fR Returns the name of the mark at or before index. If index is specified in numerical form, then the search for the previous mark begins with the character just before that index. If index is the name of a mark, then the search for the next mark begins immediately before that mark. This can still return a mark at the same position if there are multiple marks at the same index. These semantics mean that the mark previous operation can be used to step through all the marks in a text widget. An empty string is returned if there are no marks before index. .TP \fIpathName \fBmark set \fImarkName index\fR Sets the mark named markName to a position just before the character at index. If markName already exists, it is moved from its old position; if it does not exist, a new mark is created. This command returns an empty string. .TP \fIpathName \fBmark unset \fImarkName ?markName ...?\fR Remove the mark corresponding to each of the markName arguments. The removed marks will not be usable in indices and will not be returned by future calls to pathName mark names. This command returns an empty string. .RE .TP \fIpathName \fBmarker \fI?option? ?arg arg ...?\fR Markers are used to apply visual attributes to locations within one or more margins at specific line locations. The types of markers include simple shapes, like circles or arrows, as well as arbitrary images. For text\-based margins, the foreground and background colors can be specified. The following forms of the command are currently supported: .RS .TP \fIpathName \fBmarker configure \fImarkerName ?option? ?value option value ...?\fR This command is similar to the pathName configure widget command except that it modifies options associated with the marker given by markName instead of modifying options for the overall widget. If no option is specified, the command returns a list describing all of the available options for markerName. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). If one or more option\-value pairs are specified, then the command modifies the given option(s) to have the given value(s) in markerName; in this case the command returns an empty string. .TP \fIpathName \fBmarker delete \fImarkerName ?markerName ...?\fR Deletes the named markers .TP \fIpathName \fBmarker exists \fImarkerName line\fR Checks if the marker specified by markerName exists for line. Returns 1 if it does, 0 otherwise. .TP \fIpathName \fBmarker names\fR Returns a sorted list of all currently defined markers (created by using the marker configure command). .TP \fIpathName \fBmarker types\fR Returns the list of type names which can be used with the \-type option to the configure command. .RE .TP \fIpathName \fBsearch \fI?switches? pattern index ?stopIndex?\fR Searches the text in pathName starting at index for a range of characters that matches pattern. If a match is found, the index of the first character in the match is returned as result; otherwise an empty string is returned. One or more of the following switches (or abbreviations thereof) may be specified to control the search: .RS .TP \fB\-forwards\fR The search will proceed forward through the text, finding the first matching range starting at or after the position given by index. This is the default. .TP \fB\-backwards\fR The search will proceed backward through the text, finding the matching range closest to index whose first character is before index (it is not allowed to be at index). Note that, for a variety of reasons, backwards searches can be substantially slower than forwards searches (particularly when using \-regexp), so it is recommended that performance\-critical code use forward searches. .TP \fB\-exact\fR Use exact matching: the characters in the matching range must be identical to those in pattern. This is the default. .TP \fB\-regexp\fR Treat pattern as a regular expression and match it against the text using the rules for regular expressions (see the regexp command for details). The default matching automatically passes both the \-lineanchor and \-linestop options to the regexp engine (unless \-nolinestop is used), so that ^$ match beginning and end of line, and ., [^ sequences will never match the newline character \n. .TP \fB\-nolinestop\fR This allows . and [^ sequences to match the newline character \n, which they will otherwise not do (see the regexp command for details). This option is only meaningful if \-regexp is also given, and an error will be thrown otherwise. For example, to match the entire text, use pathName search \-nolinestop \-regexp ".*" 1.0. .TP \fB\-nocase\fR Ignore case differences between the pattern and the text. .TP \fB\-count \fIvarName\fR The argument following \-count gives the name of a variable; if a match is found, the number of index positions between beginning and end of the matching range will be stored in the variable. If there are no embedded images or windows in the matching range (and there are no elided characters if \-elide is not given), this is equivalent to the number of characters matched. In either case, the range matchIdx to matchIdx + $count chars will return the entire matched text. .TP \fB\-all\fR Find all matches in the given range and return a list of the indices of the first character of each match. If a \-count varName switch is given, then varName is also set to a list containing one element for each successful match. Note that, even for exact searches, the elements of this list may be different, if there are embedded images, windows or hidden text. Searches with \-all behave very similarly to the Tcl command regexp \-all, in that overlapping matches are not normally returned. For example, applying an \-all search of the pattern \w+ against hello there will just match twice, once for each word, and matching Z[a\-z]+Z against ZooZooZoo will just match once. .TP \fB\-overlap\fR When performing \-all searches, the normal behaviour is that matches which overlap an already\-found match will not be returned. This switch changes that behaviour so that all matches which are not totally enclosed within another match are returned. For example, applying an \-overlap search of the pattern \w+ against hello there will just match twice (i.e. no different to just \-all), but matching Z[a\-z]+Z against ZooZooZoo will now match twice. An error will be thrown if this switch is used without \-all. .TP \fB\-strictlimits\fR When performing any search, the normal behaviour is that the start and stop limits are checked with respect to the start of the matching text. With the \-strictlimits flag, the entire matching range must lie inside the start and stop limits specified for the match to be valid. .TP \fB\-elide \fIcurrently not supported\fR Find elided (hidden) text as well. By default only displayed text is searched. .TP \fB\-\-\fR This switch has no effect except to terminate the list of switches: the next argument will be treated as pattern even if it starts with \-. .RE .PP The matching range may be within a single line of text, or run across multiple lines (if parts of the pattern can match a new\-line). For regular expression matching one can use the various newline\-matching features such as $ to match the end of a line, ^ to match the beginning of a line, and to control whether . is allowed to match a new\-line. If stopIndex is specified, the search stops at that index: for forward searches, no match at or after stopIndex will be considered; for backward searches, no match earlier in the text than stopIndex will be considered. If stopIndex is omitted, the entire text will be searched: when the beginning or end of the text is reached, the search continues at the other end until the starting location is reached again; if stopIndex is specified, no wrap\-around will occur. This means that, for example, if the search is \-forwards but stopIndex is earlier in the text than startIndex, nothing will ever be found. See the Tk Text widget man page for more information. .RE .TP \fIpathName \fBscisearch \fI?switches? pattern index ?stopIndex?\fR Scintilla Search searches the text in pathName starting at index for a range of characters that matches pattern. If a match is found, the index of the first character in the match is returned as result; otherwise an empty string is returned. One or more of the following switches (or abbreviations thereof) may be specified to control the search: .RS .TP \fB\-forwards\fR The search will proceed forward through the text, finding the first matching range starting at or after the position given by index. This is the default. .TP \fB\-backwards\fR The search will proceed backward through the text, finding the matching range closest to index whose first character is before index (it is not allowed to be at index). .TP \fB\-count \fIvarName\fR The argument following \-count gives the name of a variable; if a match is found, the number of index positions between beginning and end of the matching range will be stored in the variable. .TP \fB\-exact\fR Use exact matching: the characters in the matching range must be identical to those in pattern. This is the default. .TP \fB\-nocase\fR Ignore case differences between the pattern and the text. .TP \fB\-regexp\fR Treat pattern as a regular expression. In a regular expression, special characters interpreted are: .RS .TP \fB.\fR Matches any character. .TP \fB\\(\fR This marks the start of a region for tagging a match. .TP \fB\\)\fR This marks the end of a tagged region. .TP \fB\\n\fR Where n is 1 through 9 refers to the first through ninth tagged region when replacing. For example, if the search string was Fred\\([1-9]\\)XXX and the replace string was Sam\1YYY, when applied to Fred2XXX this would generate Sam2YYY. \0 refers to all of the matching text. .TP \fB\\<\fR This matches the start of a word using Scintilla's definitions of words. .TP \fB\\>\fR This matches the end of a word using Scintilla's definition of words. .TP \fB\\x\fR This allows you to use a character x that would otherwise have a special meaning. For example, \\[ would be interpreted as [ and not as the start of a character set. .TP \fB[...]\fR This indicates a set of characters, for example, [abc] means any of the characters a, b or c. You can also use ranges, for example [a\-z] for any lower case character. .TP \fB[^...]\fR The complement of the characters in the set. For example, [^A\-Za\-z] means any character except an alphabetic character. .TP \fB^\fR This matches the start of a line (unless used inside a set, see above). .TP \fB$\fR This matches the end of a line. .TP \fB*\fR This matches 0 or more times. For example, Sa*m matches Sm, Sam, Saam, Saaam and so on. .TP \fB+\fR This matches 1 or more times. For example, Sa+m matches Sam, Saam, Saaam and so on. .RE Regular expressions will only match ranges within a single line, never matching over multiple lines. .TP \fB\-word\fR A match only occurs if the characters before and after are not word characters. .TP \fB--\fR This switch has no effect except to terminate the list of switches: the next argument will be treated as pattern even if it starts with \-. .RE The matching range must be within a single line of text. For regular expression matching one can use the various newline\-matching features such as $ to match the end of a line, ^ to match the beginning of a line. If stopIndex is specified, the search stops at that index: for forward searches, no match at or after stopIndex will be considered; for backward searches, no match earlier in the text than stopIndex will be considered. If stopIndex is omitted, the entire text will be searched. .TP \fIpathName \fBsee \fIindex ?\-center?\fR Adjusts the view in the window so that the character given by index is completely visible. If index is already visible then the command does nothing. If index is a short distance out of view, the command adjusts the view just enough to make index visible at the edge of the window. If index is far out of view, then the command centers index in the window. The \-center option can be used to force index to be centered in the window. .TP \fIpathName \fBtag \fI?option? ?arg arg ...?\fR A tag is a textual string that is associated with some of the characters in the widget. Tags may contain arbitrary characters, but it is probably best to avoid using the characters (space), +, or \-: these characters have special meaning in indices, so tags containing them cannot be used as indices. There may be any number of tags associated with characters in a text. Each tag may refer to a single character, a range of characters, or several ranges of characters. An individual character may have any number of tags associated with it. The order that overlapping tags are displayed is controlled by the logical identifier associated with each of the tag types below(higher ID numbers are drawn last). See the table below for descriptions of the supported types. The following forms of the command are currently supported: .RS .TP \fIpathName \fBtag add \fItagName index1 ?index2?\fR Associate the tag tagName (one will be created if it doesn't already exist) with all of the characters starting with index1 and ending just before index2 (the character at index2 is not tagged). If index2 is omitted then the single character at index1 is tagged. If there are no characters in the specified range (e.g. index1 is past the end of the file or index2 is less than or equal to index1) then the command has no effect. EXCEPTION: If tagName is the predefined selection tag (i.e. "sel"), then specifying index2 to be less than index1 will have the effect of positioning the insertion point at the start of the selection. .TP \fIpathName \fBtag bind \fItagName ?sequence? ?script?\fR This command associates script with the tag given by tagName. Whenever the event sequence given by sequence occurs for a character that has been tagged with tagName, the script will be invoked. This widget command is similar to the bind command except that it operates on characters in a text rather than entire widgets. See the bind manual entry for complete details on the syntax of sequence and the substitutions performed on script before invoking it. If all arguments are specified then a new binding is created, replacing any existing binding for the same sequence and tagName (if the first character of script is + then script augments an existing binding rather than replacing it). In this case the return value is an empty string. If script is omitted then the command returns the script associated with tagName and sequence (an error occurs if there is no such binding). If both script and sequence are omitted then the command returns a list of all the sequences for which bindings have been defined for tagName. The only events for which bindings may be specified are those related to the mouse and keyboard (such as Enter, Leave, ButtonPress, Motion, and KeyPress) or virtual events. Event bindings for a text widget use the current mark. An Enter event triggers for a tag when the tag first becomes present on the current character, and a Leave event triggers for a tag when it ceases to be present on the current character. Enter and Leave events can happen either because the current mark moved or because the character at that position changed. Note that these events are different than Enter and Leave events for windows. Mouse and keyboard events are directed to the current character. If a virtual event is used in a binding, that binding can trigger only if the virtual event is defined by an underlying mouse\-related or keyboard\-related event. .TP \fIpathName \fBtag cget \fItagName option\fR This command returns the current value of the option named option associated with the tag given by tagName. Option may have any of the values accepted by the pathName tag configure widget command. .TP \fIpathName \fBtag configure \fItagName ?\-margin? ?option? ?value? ?option value ...?\fR This command is similar to the pathName configure widget command except that it modifies options associated with the tag given by tagName instead of modifying options for the overall text widget. If no option is specified, the command returns a list describing all of the available options for tagName. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). If one or more option\-value pairs are specified, then the command modifies the given option(s) to have the given value(s) in tagName; in this case the command returns an empty string. Note, the special \-margin option, if used, must immediately follow tagName. It is used to create and configure tags used within the margin area. See "configure options" for more details .TP \fIpathName \fBtag delete \fItagName ?tagName ...?\fR Deletes all tag information for each of the tagName arguments. The command removes the tags from all characters in the file and also deletes any other information associated with the tags, such as bindings and display information. The command returns an empty string. .TP \fIpathName \fBtag lower \fItagName\fR This has NOT BEEN IMPLEMENTED because Scintilla core functionality regarding "markers" (which is how the ScintillaTk tag functionality has been implemented) does not support drawing priority for markers that overlap. .TP \fIpathName \fBtag names \fI?index?\fR Returns a list whose elements are the names of all the tags that are active at the character position given by index. If index is omitted, then the return value will describe all of the tags that exist for the widget. .TP \fIpathName \fBtag nextrange \fItagName index1 ?index2?\fR This command searches the text for a range of characters tagged with tagName where the first character of the range is no earlier than the character at index1 and no later than the character just before index2 (a range starting at index2 will not be considered). The command's return value is a list containing two elements, which are the index of the first character of the range and the index of the character just after the last one in the range. If no matching range is found then the return value is an empty string. If index2 is not given then it defaults to the end of the text. .TP \fIpathName \fBtag prevrange \fItagName index1 ?index2?\fR This command searches the text for a range of characters tagged with tagName where the first character of the range is before the character at index1 and no earlier than the character at index2 (a range starting at index2 will be considered). The command's return value is a list containing two elements, which are the index of the first character of the range and the index of the character just after the last one in the range. If no matching range is found then the return value is an empty string. If index2 is not given then it defaults to the beginning of the text. .TP \fIpathName \fBtag raise \fItagName\fR This has NOT BEEN IMPLEMENTED because Scintilla core functionality regarding "markers" (which is how the ScintillaTk tag functionality has been implemented) does not support drawing priority for markers that overlap. .TP \fIpathName \fBtag ranges \fItagName\fR Returns a list describing all of the ranges of text that have been tagged with tagName. The first two elements of the list describe the first tagged range in the text, the next two elements describe the second range, and so on. The first element of each pair contains the index of the first character of the range, and the second element of the pair contains the index of the character just after the last one in the range. If there are no characters tagged with tag then an empty string is returned. .TP \fIpathName \fBtag remove \fItagName index1 ?index2 index1 index2 ...?\fR Remove the tag tagName from all of the characters starting at index1 and ending just before index2 (the character at index2 is not affected). A single command may contain any number of index1\-index2 pairs. If the last index2 is omitted then the tag is removed from the single character at index1. If there are no characters in the specified range (e.g. index1 is past the end of the file or index2 is less than or equal to index1) then the command has no effect. This command returns an empty string. .RE \fBTag Types\fR .TS box; lfB lfB lfB l np1 ap9. Type ID Description plain 0 Underlined with a single, straight line. squiggle 1 A squiggly underline, 3 pixels in height tt 2 A line of small "T" shapes diagonal 3 Diagonal hatching strike 4 A solid "strike through" line draw at the vertical mid\-point hidden 5 No visual effect box 6 A rectangular box around the text roundbox 7 T{ A rectangle with rounded corners around the text, using translucent drawing for the interior (NOT SUPPORTED YET) T} squarebox 8 T{ A rectangle around the text, using translucent drawing for the interior (NOT SUPPORTED YET) T} dash 9 A dashed underline dots 10 A dotted underline squigglelow 11 Similar to squiggle but only 2 pixels in height dotbox 12 T{ A dotted rectangle around the text, using translucent drawing for the interior (NOT SUPPORTED YET) T} .TE .PP .PP For the above types, use the \-foreground configuration option for the tag to control the color. For types that use a filled interior, use the \-background option to set the interior color. The following lists the supported configuration options, though not all are supported for each type of tag (exceptions are noted): .TP \fB\-background|\-bg \fIcolor\fR Color specifies the color used for tags that have a filled interior. .TP \fB\-bold \fIboolean \fR(ONLY FOR MARGIN TAGS) Specifies if margins showing text will use a bold font .TP \fB\-foreground|\-fg \fIcolor\fR Color specifies the color used for tags, and for tags will filled interiors color is for the outline. .TP \fB\-indicatortype \fItype \fR(NOT FOR MARGIN TAGS) The type value matches the names in the above table .TP \fB\-italic \fIboolean \fR(ONLY FOR MARGIN TAGS) Specifies if margins showing text will use an italicized font There is a special tag used to control the appearance (foreground and background colors only) of the widget's selection. The name of this tag is sel, and it cannot be deleted. .TP \fIpathName \fBversion\fR Returns a 3\-element list containing information identifying the current version of the widget. The fields of the list are:\fR version : identifies the Tcl package version date : the date the package was created core_rls: this identifies the release of the Scintilla core widget .PP .SH "KNOWN BUGS" Patterns including newline (\n) may not work correctly in all cases. This limitation is due to how Scintilla stores document text; the end of line characters are stripped from the document making the search challenging. .PP The pathName search \-regexp sub\-command attempts to perform sophisticated regexp matching across multiple lines in an efficient fashion. Under certain conditions the search result might differ from that obtained by applying the same regexp to the entire text from the widget in one go. .PP Whenever one possible match is fully enclosed in another, the search command will attempt to ensure only the larger match is returned. When performing backwards regexp searches it is possible that Tcl will not always achieve this. .RE .RE '\" Local Variables: '\" mode: nroff '\" fill-column: 78 '\" End: |
Added tk/doc/scintillatk.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 |
scintilla(n) ScintillaTK Text Widget scintilla(n) ______________________________________________________________________________ NNAAMMEE scintilla - Scintilla text widget SSYYNNOOPPSSIISS ppaacckkaaggee rreeqquuiirree sscciinnttiillllaattkk ?00..2255? sscciinnttiillllaa _p_a_t_h_N_a_m_e ?_o_p_t_i_o_n_s? SSTTAANNDDAARRDD OOPPTTIIOONNSS --aauuttoosseeppaarraattoorrss --hhiigghhlliigghhtt --mmoovveeuuppddaatteeccoommmmaanndd --bbaacckkggrroouunndd --hhiigghhlliigghhtttthhiicckknneessss --rreelliieeff --bblliinnkk --hhiigghhlliigghhttbbaacckkggrroouunndd --sshhoowwwwss --bboorrddeerrwwiiddtthh --llaanngguuaaggee --ssttaattee --bbuussyyccuurrssoorr --lliinneessaaddddeeddccoommmmaanndd --ttaabbwwiiddtthh --ccuurrssoorr --mmaarrggiinnbbaacckkggrroouunndd --ttaakkeeffooccuuss --ffoollddssttyyllee --mmaarrggiinnbbgg --xxssccrroollllccoommmmaanndd --ffoonntt --mmaarrggiinnffoorreeggrroouunndd --yyssccrroollllccoommmmaanndd --ffoorreeggrroouunndd --mmaarrggiinnffgg --uunnddoo --hheeiigghhtt --mmaarrggiinnwwiiddtthhccoommmmaanndd --wwiiddtthh See the ooppttiioonnss manual entry for details on the standard options. WWIIDDGGEETT--SSPPEECCIIFFIICC OOPPTTIIOONNSS Command-Line Name:--aauuttoosseeppaarraattoorrss Database Name: aauuttooSSeeppaarraattoorrss Database Class: AAuuttooSSeeppaarraattoorrss Specifies a boolean that says whether separators are automati- cally inserted in the undo stack. Only meaningful when the --uunnddoo option is true. Command-Line Name:--hheeiigghhtt Database Name: hheeiigghhtt Database Class: HHeeiigghhtt Specifies the desired height for the window, in units of charac- ters in the font given by the --ffoonntt option. Must be at least one. Command-Line Name:--ssttaattee Database Name: ssttaattee Database Class: SSttaattee Specifies one of two states for the text: nnoorrmmaall or ddiissaabblleedd. If the text is disabled then characters may not be inserted or deleted and no insertion cursor will be displayed, even if the input focus is in the widget. Command-Line Name:--wwiiddtthh Database Name: wwiiddtthh Database Class: WWiiddtthh Specifies the desired width for the window in units of charac- ters in the font given by the --ffoonntt option. If the font does not have a uniform width then the width of the character "0" is used in translating from character units to screen units. Command-Line Name:--bbuussyyccuurrssoorr Database Name: ccuurrssoorr Database Class: CCuurrssoorr Cursor to display when text widget is computationally busy. Command-Line Name:--ffoollddssttyyllee Database Name: ffoollddssttyyllee Database Class: FFoollddSSttyyllee See Scintilla documentation for style values. Command-Line Name:--llaanngguuaaggee Database Name: llaanngguuaaggee Database Class: LLaanngguuaaggee Specifies which programming language lexer to use for syntax highlighting. Command-Line Name:--lliinneessaaddddeeddccoommmmaanndd Database Name: lliinnddeessAAddddeeddCCoommmmaanndd Database Class: LLiinneessAAddddeeddCCoommmmaanndd Callback command when new lines are inserted in the document. This function can be used to update margin indicators if neces- sary. Command-Line Name:--mmaarrggiinnbbaacckkggrroouunndd Database Name: mmaarrggiinnBBaacckkggrroouunndd Database Class: MMaarrggiinnBBaacckkggrroouunndd The backgound color of the margin columns. Command-Line Name:--mmaarrggiinnffoorreeggrroouunndd Database Name: mmaarrggiinnFFoorreeggrroouunndd Database Class: MMaarrggiinnFFoorreeggrroouunndd The foregound (font) color of the margin columns. Command-Line Name:--mmaarrggiinnwwiiddtthhccoommmmaanndd Database Name: Database Class: Callback command used when margin width changes. Command-Line Name:--mmoovveeuuppddaatteeccoommmmaanndd Database Name: mmoovveeUUppddaatteeCCoommmmaanndd Database Class: MMoovveeUUppddaatteeCCoommmmaanndd Callback command when margin changes. Command-Line Name:--sshhoowwwwss Database Name: sshhoowwwwss Database Class: SShhoowwWWss Show the ws??? _________________________________________________________________ DDEESSCCRRIIPPTTIIOONN The sscciinnttiillllaa command creates a new window (given by the _p_a_t_h_N_a_m_e arg) and makes it into a Scintilla text widget. Additional options, described above, may be specified on the command line or in the option database to configure aspects of the text such as its default back- ground color and relief. The tteexxtt command returns the path name of the new window. WWIIDDGGEETT CCOOMMMMAANNDD _p_a_t_h_N_a_m_e aannnnoottaattee _o_p_t_i_o_n _?_a_r_g _a_r_g _._._._? Text annotations are separate strings that can be assigned to the lines within the document. The annotation is displayed without any line numbers and appears in extra space which is created by the widget for its display. There are various options available: cclleeaarraallll removes annotation strings for all lines ggeett _l_i_n_e Returns the annotation text for the specified line. sseett _l_i_n_e _t_e_x_t _?_t_a_g_N_a_m_e _t_e_x_t _t_a_g_N_a_m_e _._._._? Assigns the specified text string to the specified line. If no tagName option is specified, the annotation text will use the default text styling. If a single tagName option is used it will control the appearance for all of the annotation text. By using multiple text and tagName options it's possible to have different appearances for different subranges of the text. sshhooww _0_|_1_|_2 Used to control the display of annotations where 0 - hid- ing, 1 - showing or 2 - showing with a bounding box. Note, this affects all lines with annotations. _p_a_t_h_N_a_m_e bbbbooxx _i_n_d_e_x Returns a list of four elements describing the screen area of the character given by index. The first two elements of the list give the x and y coordinates of the upper-left corner of the area occupied by the character, and the last two elements give the width and height of the area. If the character is not visi- ble on the screen then the return value is an empty list. _p_a_t_h_N_a_m_e ccggeett _o_p_t_i_o_n Returns the current value of the configuration option given by option. Option may have any of the values accepted by the scin- tilla command. _p_a_t_h_N_a_m_e ccoommppaarree _i_n_d_e_x_1 _o_p _i_n_d_e_x_2 Compares the indices given by index1 and index2 according to the relational operator given by op, and returns 1 if the relation- ship is satisfied and 0 if it is not. Op must be one of the operators <, <=, =, >, >, or !. If op is == then 1 is returned if the two indices refer to the same character, if op is < then 1 is returned if index1 refers to an earlier character in the text than index2, and so on. _p_a_t_h_N_a_m_e ccoonnffiigguurree _?_o_p_t_i_o_n_? _?_v_a_l_u_e _o_p_t_i_o_n _v_a_l_u_e _._._._? Query or modify the configuration options of the widget. If no option is specified, returns a list describing all of the avail- able options for pathName. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). If one or more option-value pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. Option may have any of the values accepted by the scintilla command. _p_a_t_h_N_a_m_e ccoouunntt _?_o_p_t_i_o_n_s_? _i_n_d_e_x_1 _i_n_d_e_x_2 Counts the number of relevant things between the two indices. If index1 is after index2, the result will be a negative number (and this holds for each of the possible options). The actual items which are counted depend on the options given. The result is a list of integers, one for the result of each counting option given. Valid counting options are -chars, -displaylines and -lines. The default value, if no option is specified, is -chars. The count options are interpreted as follows: --cchhaarrss count all characters, whether elided or not. Do not count embedded windows or images. --ddiissppllaayylliinneess count all display lines (i.e. ignore lines which are folded) from the line of the first index up to, but not including the display line of the second index. Therefore if they are both on the same display line, zero will be returned. By definition displaylines are visible and therefore this only counts portions of actual visible lines. --lliinneess count all lines (irrespective of folding) from the line of the first index up to, but not including the line of the second index. Therefore if they are both on the same line, zero will be returned. Lines are counted whether they are currently visible (non-folded) or not. _p_a_t_h_N_a_m_e ddeelleettee _i_n_d_e_x_1 _?_i_n_d_e_x_2_? Delete a range of characters from the text. If both index1 and index2 are specified, then delete all the characters starting with the one given by index1 and stopping just before index2 (i.e. the character at index2 is not deleted). If index2 doesn't specify a position later in the text than index1 then no charac- ters are deleted. If index2 isn't specified then the single character at index1 is deleted. It is not allowable to delete characters in a way that would leave the text without a newline as the last character. The command returns an empty string. _p_a_t_h_N_a_m_e dduummpp _?_s_w_i_t_c_h_e_s_? _i_n_d_e_x_1 _?_i_n_d_e_x_2_?__ Return the contents of the text widget from index1 up to, but not including index2, including the text and information about marks, tags, and embedded windows. If index2 is not specified, then it defaults to one character past index1. The information is returned in the following format:: key1 value1 index1 key2 value2 index2 ... The possible key values are indicatoron, indicatoroff, text, mark, styleon, styleoff, tagon, tagoff, image, and window. The corresponding value is the indicator type, text, mark name, style number, tag name, image name, or window name. The index information is the index of the start of the indicator transition, style transition, text, mark, tag transition, image or window. The image and window options are not supported and will return nothing. One or more of the fol- lowing switches (or abbreviations thereof) may be specified to control the dump: --aallll Return information about all elements: indicator, style, text, marks, tags, images and windows. This is the default. --ccoommmmaanndd _c_o_m_m_a_n_d Instead of returning the information as the result of the dump operation, invoke the command on each element of the text widget within the range. The command has three argu- ments appended to it before it is evaluated: the key, value, and index. --iimmaaggee Include information about images in the dump results. This option is unsupported in Scintilla. --iinnddiiccaattoorr Include information about indicator transitions in the dump results. Indicator information is returned as indi- catoron and indicatoroff elements that indicate the begin and end of each range of each indicator, respectively. --mmaarrkk Include information about marks in the dump results. --ssttyyllee Include information about style transitions in the dump results. Style information is returned as styleon and styleoff elements that indicate the begin and end of each range of each style, respectively. --ttaagg Include information about tag transitions in the dump results. Tag information is returned as tagon and tagoff elements that indicate the begin and end of each range of each tag, respectively. --tteexxtt Include information about text in the dump results. The value is the text up to the next element or the end of range indicated by index2. A text element does not span newlines. A multi-line block of text that contains no marks or tag transitions will still be dumped as a set of text segments that each end with a newline. The newline is part of the value. --wwiinnddooww Include information about embedded windows in the dump results. This option is unsupported in Scintilla. _p_a_t_h_N_a_m_e eeddiitt _o_p_t_i_o_n _?_a_r_g _a_r_g _._._._? This command controls the undo mechanism and the modified flag. The exact behavior of the command depends on the option argument that follows the edit argument. The following forms of the com- mand are currently supported: _p_a_t_h_N_a_m_e eeddiitt ccaannrreeddoo Returns true if the redo stack is not empty. _p_a_t_h_N_a_m_e eeddiitt ccaannuunnddoo Returns true if the undo stack is not empty. _p_a_t_h_N_a_m_e eeddiitt IImmooddiiffiieedd _?_b_o_o_l_e_a_n_? If boolean is not specified, returns the modified flag of the widget. The insert, delete, edit undo and edit redo commands or the user can set or clear the modified flag. If boolean is specified, sets the modified flag of the widget to boolean. _p_a_t_h_N_a_m_e eeddiitt rreeddoo When the -undo option is true, reapplies the last undone edits provided no other edits were done since then. Gen- erates an error when the redo stack is empty. Does noth- ing when the -undo option is false. _p_a_t_h_N_a_m_e eeddiitt rreesseett Clears the undo and redo stacks. _p_a_t_h_N_a_m_e eeddiitt sseeppaarraattoorr Inserts a separator (boundary) on the undo stack. Does nothing when the -undo option is false. _p_a_t_h_N_a_m_e eeddiitt uunnddoo Undoes the last edit action when the -undo option is true. An edit action is defined as all the insert and delete commands that are recorded on the undo stack in between two separators. Generates an error when the undo stack is empty. Does nothing when the -undo option is false. _p_a_t_h_N_a_m_e ffoolldd _c_o_m_m_a_n_d _?_l_i_n_e_? The fold command provides various capabilities related to Scin- tilla's folding functionality. Some operations are simple queries while others will impact the fold structure within the document. The following commands are supported: ffoollddaallll folds all lines within the document ffoollddbbeellooww _l_i_n_e folds all lines which are after(below) line number line ffoollddppaarreenntt _l_i_n_e returns the line containing the immediate fold parent of line ffoollddrroooott _l_i_n_e returns the line containing topmost fold parent of the specified line . This is at the top of the fold hierarchy containing line . iissffoollddeedd _l_i_n_e return 1 if line contained in a folded parent, and 0 if it isn't sshhooww _l_i_n_e fully expand the containing fold hierarchy such that line is visible ttooggggllee _l_i_n_e toggle the fold state of line (ie if collapsed, expand it; if expanded, collapse it) ttooppuunnffoollddeedd _l_i_n_e return the line of the highest fold parent for line which is currently expanded uunnffoollddaallll unfold all lines uunnffoollddbbeellooww _l_i_n_e unfold all lines which are after(below) line number line _p_a_t_h_N_a_m_e iinnddeexx _i_n_d_e_x _?_-_t_e_x_t_o_n_l_y_? Returns the position corresponding to index in the form line.char where line is the line number and char is the charac- ter number. See the documentation for the Tk Text widget for a description of the formats used to specify indices. NOTE: Speci- fying an X/Y location that corresponds to a line of annotation text will return the index for the end of the line associated with the annotation. If the -textonly option is used, then an empty string is returned if the X/Y location is over an annota- tion. _p_a_t_h_N_a_m_e iinnsseerrtt _i_n_d_e_x _c_h_a_r_s Inserts all of the chars argument just before the character at index. If index refers to the end of the text (the character after the last newline) then the new text is inserted just before the last newline instead. _p_a_t_h_N_a_m_e mmaarrggiinn _o_p_t_i_o_n _?_a_r_g _a_r_g _._._._? This command is used to manage the widget's various margins (aka columns). The exact behavior of the command depends on the option argument that follows the margin argument. In most of the subcommands below, there is an argument which identifies the margin. It is labeled "marginID" in the following descriptions. The format of this argument can be any of the following: 1) the numeric index of the margin, where "0" is the leftmost margin, and "4" is rightmost, 2) the name of the margin, which will match the margin's type (eg "text", "symbol", etc), or 3) the alias name defined for the margin. The following forms of the command are currently supported: _p_a_t_h_N_a_m_e mmaarrggiinn bbbbooxx _m_a_r_g_i_n_I_D _l_i_n_e Returns a list of four elements describing the screen area of the margin identified by marginID, at the line specified by line. The first two elements of the list give the x and y coordinates of the upper-left corner of the area occupied by the character, and the last two ele- ments give the width and height of the area. If the char- acter is not visible on the screen then the return value is an empty list. _p_a_t_h_N_a_m_e mmaarrggiinn ccggeett _m_a_r_g_i_n_I_D _o_p_t_i_o_n This command returns the current value of the option named option associated with the margin given by marginID. Option may have any of the values accepted by the pathName margin configure widget command. _p_a_t_h_N_a_m_e mmaarrggiinn ccoonnffiigguurree _m_a_r_g_i_n_I_D _?_o_p_t_i_o_n_? _?_v_a_l_u_e_? _?_o_p_t_i_o_n _v_a_l_u_e _._._._? This command is similar to the pathName configure widget command except that it modifies options associated with the margin given by marginID instead of modifying options for the overall text widget. If no option is specified, the command returns a list describing all of the avail- able options for marginID. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corre- sponding sublist of the value returned if no option is specified). If one or more option-value pairs are speci- fied, then the command modifies the given option(s) to have the given value(s) in marginID; in this case the command returns an empty string. _p_a_t_h_N_a_m_e mmaarrggiinn ccoouunntt Returns the number of margins _p_a_t_h_N_a_m_e mmaarrggiinn dduummpp _m_a_r_g_i_n_I_D _?_o_p_t_i_o_n_? _I_n_d_e_x_1 _?_I_n_d_e_x_2_? Return the contents of the text widget from index1 up to, but not including index2, including the text and informa- tion about marks, tags, and embedded windows. If index2 is not specified, then it defaults to one character past index1. The information is returned in the following for- mat:: key1 value1 index1 key2 value2 index2 ... The pos- sible key values are indicatoron, indicatoroff, text, mark, styleon, styleoff, tagon, and tagoff. The corre- sponding value is the indicator type, text, mark name, style number, or tag name. The index information is the index within the margin of the start of the indicator transition, style transition, text, mark, tag transition, image or window. One or more of the following switches (or abbreviations thereof) may be specified to control the dump: --aallll Return information about all elements: indicator, style, text, marks, and tags. This is the default. --ccoommmmaanndd _c_o_m_m_a_n_d Instead of returning the information as the result of the dump operation, invoke the command on each element of the text widget within the range. The command has three argu- ments appended to it before it is evaluated: the key, value, and index. --iinnddiiccaattoorr Include information about indicator transitions in the dump results. Indicator information is returned as indi- catoron and indicatoroff elements that indicate the begin and end of each range of each indicator, respectively. --mmaarrkk Include information about marks in the dump results. --ssttyyllee Include information about style transitions in the dump results. Style information is returned as styleon and styleoff elements that indicate the begin and end of each range of each style, respectively. --ttaagg Include information about tag transitions in the dump results. Tag information is returned as tagon and tagoff elements that indicate the begin and end of each range of each tag, respectively. --tteexxtt Include information about text in the dump results. The value is the text up to the next element or the end of range indicated by index2. A text element does not span newlines. A multi-line block of text that contains no marks or tag transitions will still be dumped as a set of text segments that each end with a newline. The newline is part of the value. _p_a_t_h_N_a_m_e mmaarrggiinn ffiillllnnuummbbeerrss _m_a_r_g_i_n_I_D _s_t_a_r_t _c_o_u_n_t _?_t_a_g_N_a_m_e _{_l_i_n_e _._._._}_? This would be used to manually managing filling a margin with line numbers. This is really only used for cases when control over the appearance of the line numbers is needed. The fillnumbers command would be called within the -linesaddedcommand callback function in a margin whose type was set to "lnums_alt". Setting the margin type to "lnums" would result in the Scintilla core code handling filling of the line numbers. The start option identifies where the line numbering should begin. The count option controls how many lines will be numbers. A value of <= 0 will number all lines from start until the end of the document. To apply custom styling to one or more line numbers, first configure a tag named tagName and then identify the list of line numbers as the argu- ment following tagName. For example, to fill the line numbers from 1 to 10 where only the odd numbers are styled in red, first create a tag (ex: $sci tag config red -margin -fg red) and then execute $sci margin fill- numbers 1 10 red {1 3 5 7 9}. _p_a_t_h_N_a_m_e mmaarrggiinn hhiiddee _m_a_r_g_i_n_I_D Hides the margin specified by marginID. The margin's con- figuration information is maintained while hidden. _p_a_t_h_N_a_m_e mmaarrggiinn iinnddeexx _@_X_,_Y Returns a list of three elements to identify the margin at the location indicated by the X and Y window location (where "@0,0" corresponds to the upperleft corner of the window). If a margin exists at the location, then the three values returned are: 1) the margin id, 2) the line number, and 3) the margin's alias (or an empty string if it an alias hasn't been defined). If the X/Y location isn't over a margin then an empty string is returned. _p_a_t_h_N_a_m_e mmaarrggiinn mmaarrkkeerr _m_a_r_g_i_n_I_D _c_o_m_m_a_n_d _m_a_r_k_e_r_N_a_m_e _l_i_n_e_s This command is used to add or remove the marker named markerName to the margin specified by marginID. The oper- ation performed is controlled by the command argument, which would either be "add" or "clear". The lines option identifies which lines to add or remove the marker for. When removing, if the lines list is empty, then the spec- ified marker would be removed from all lines. Also, when removing, if the markerName is set to "*", then all mark- ers present for the specified lines would be removed. _p_a_t_h_N_a_m_e mmaarrggiinn mmaarrkkeerr _m_a_r_g_i_n_I_D _l_i_s_t _m_a_r_k_e_r_N_a_m_e _?_l_i_n_e_? This command returns a list of the lines containing the specified marker. If markerName is specified as "*" the line argument is required. When this done, the all mark- ers present on the specified line will be returned. _p_a_t_h_N_a_m_e mmaarrggiinn nnaammeess Returns information about each of the margins. Each mar- gin is identified by a three element list containing the following: 1) the ID value of the margin (where "0" is the leftmost margin), 2) the type of the margin, and 3) the alias name, or an empty string if one hasn't been defined. _p_a_t_h_N_a_m_e mmaarrggiinn sshhooww _m_a_r_g_i_n_I_D Shows the margin specified by marginID. For margins that have not yet had a width set (ie their width is zero), the show operation will report an error unless the mar- gin's type is set for linenumbers or the special fold margin. For those margins, the widget will automatically determine the appropriate width to use in order to allow the margin to be made visible. _p_a_t_h_N_a_m_e mmaarrggiinn ttaagg _{_l_i_n_e _._._._} _?_t_a_g_N_a_m_e _-_c_l_e_a_r_? This command will either add or remove a tag that was previously configured for use in the margin area (see here for more details). The margin tag will affect only text-based margins (ie not those holding symbols). The tag named tagName will be added to the list of lines unless the -clear option is specified, in which case the tag will be removed. When removing a tag, it can be removed from all lines by specifying an empty list for the lines. To remove all margin tags from all lines, the tagName option should not be specified (ie $sci margin tag {} -clear). _p_a_t_h_N_a_m_e mmaarrggiinn tteexxtt _m_a_r_g_i_n_I_D _c_o_m_m_a_n_d _a_r_g_l_i_s_t This command is used to manipulate the margin text within the margin specified by marginID. The margin specified by marginID must be of type text or rtext. The operation performed is controlled by the command argument, which would either be one of "clear", "get", or "set". If com- mand is "clear", and there is no arglist, then the margin text for all lines in the document is removed. If arglist is provided, it is a list of one or more lines to clear. If the command argument is "get", the arglist must spec- ify the line number of the margin text to return. If the command argument is "set", the arglist consists of a string value to set in the margin followed by one or more line numbers that should be modified. _p_a_t_h_N_a_m_e mmaarrggiinn vviissiibbllee _m_a_r_g_i_n_I_D Returns if the margin specified by marginID is currently being shown. This is different from checking if the mar- gin's configuration value for the -width option is zero, because when a margin is hidden its width value is retained so that it can be shown with the intended width. _p_a_t_h_N_a_m_e mmaarrggiinn wwiiddtthh Return the total width in pixels of the visible margins. _p_a_t_h_N_a_m_e mmaarrkk _o_p_t_i_o_n _?_a_r_g _a_r_g _._._._? This command is used to manipulate marks. The exact behavior of the command depends on the option argument that follows the mark argument. The following forms of the command are currently sup- ported: _p_a_t_h_N_a_m_e mmaarrkk eexxiissttss _m_a_r_k_N_a_m_e If markName exists, the command will return 1; otherwise 0 is returned. _p_a_t_h_N_a_m_e mmaarrkk ggrraavviittyy _m_a_r_k_N_a_m_e _?_d_i_r_e_c_t_i_o_n_? If direction is not specified, returns left or right to indicate which of its adjacent characters markName is attached to. If direction is specified, it must be left or right; the gravity of markName is set to the given value. _p_a_t_h_N_a_m_e mmaarrkk nnaammeess Returns a list whose elements are the names of all the marks that are currently set. _p_a_t_h_N_a_m_e mmaarrkk nneexxtt _i_n_d_e_x Returns the name of the next mark at or after index. If index is specified in numerical form, then the search for the next mark begins at that index. If index is the name of a mark, then the search for the next mark begins imme- diately after that mark. This can still return a mark at the same position if there are multiple marks at the same index. These semantics mean that the mark next operation can be used to step through all the marks in a text wid- get. An empty string is returned if there are no marks after index. _p_a_t_h_N_a_m_e mmaarrkk pprreevviioouuss _i_n_d_e_x Returns the name of the mark at or before index. If index is specified in numerical form, then the search for the previous mark begins with the character just before that index. If index is the name of a mark, then the search for the next mark begins immediately before that mark. This can still return a mark at the same position if there are multiple marks at the same index. These seman- tics mean that the mark previous operation can be used to step through all the marks in a text widget. An empty string is returned if there are no marks before index. _p_a_t_h_N_a_m_e mmaarrkk sseett _m_a_r_k_N_a_m_e _i_n_d_e_x Sets the mark named markName to a position just before the character at index. If markName already exists, it is moved from its old position; if it does not exist, a new mark is created. This command returns an empty string. _p_a_t_h_N_a_m_e mmaarrkk uunnsseett _m_a_r_k_N_a_m_e _?_m_a_r_k_N_a_m_e _._._._? Remove the mark corresponding to each of the markName arguments. The removed marks will not be usable in indices and will not be returned by future calls to path- Name mark names. This command returns an empty string. _p_a_t_h_N_a_m_e mmaarrkkeerr _?_o_p_t_i_o_n_? _?_a_r_g _a_r_g _._._._? Markers are used to apply visual attributes to locations within one or more margins at specific line locations. The types of markers include simple shapes, like circles or arrows, as well as arbitrary images. For text-based margins, the foreground and background colors can be specified. The following forms of the command are currently supported: _p_a_t_h_N_a_m_e mmaarrkkeerr ccoonnffiigguurree _m_a_r_k_e_r_N_a_m_e _?_o_p_t_i_o_n_? _?_v_a_l_u_e _o_p_t_i_o_n _v_a_l_u_e _._._._? This command is similar to the pathName configure widget command except that it modifies options associated with the marker given by markName instead of modifying options for the overall widget. If no option is specified, the command returns a list describing all of the available options for markerName. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corre- sponding sublist of the value returned if no option is specified). If one or more option-value pairs are speci- fied, then the command modifies the given option(s) to have the given value(s) in markerName; in this case the command returns an empty string. _p_a_t_h_N_a_m_e mmaarrkkeerr ddeelleettee _m_a_r_k_e_r_N_a_m_e _?_m_a_r_k_e_r_N_a_m_e _._._._? Deletes the named markers _p_a_t_h_N_a_m_e mmaarrkkeerr eexxiissttss _m_a_r_k_e_r_N_a_m_e _l_i_n_e Checks if the marker specified by markerName exists for line. Returns 1 if it does, 0 otherwise. _p_a_t_h_N_a_m_e mmaarrkkeerr nnaammeess Returns a sorted list of all currently defined markers (created by using the marker configure command). _p_a_t_h_N_a_m_e mmaarrkkeerr ttyyppeess Returns the list of type names which can be used with the -type option to the configure command. _p_a_t_h_N_a_m_e sseeaarrcchh _?_s_w_i_t_c_h_e_s_? _p_a_t_t_e_r_n _i_n_d_e_x _?_s_t_o_p_I_n_d_e_x_? Searches the text in pathName starting at index for a range of characters that matches pattern. If a match is found, the index of the first character in the match is returned as result; oth- erwise an empty string is returned. One or more of the following switches (or abbreviations thereof) may be specified to control the search: --ffoorrwwaarrddss The search will proceed forward through the text, finding the first matching range starting at or after the posi- tion given by index. This is the default. --bbaacckkwwaarrddss The search will proceed backward through the text, find- ing the matching range closest to index whose first char- acter is before index (it is not allowed to be at index). Note that, for a variety of reasons, backwards searches can be substantially slower than forwards searches (par- ticularly when using -regexp), so it is recommended that performance-critical code use forward searches. --eexxaacctt Use exact matching: the characters in the matching range must be identical to those in pattern. This is the default. --rreeggeexxpp Treat pattern as a regular expression and match it against the text using the rules for regular expressions (see the regexp command for details). The default match- ing automatically passes both the -lineanchor and -linestop options to the regexp engine (unless -nolinestop is used), so that ^$ match beginning and end of line, and ., [^ sequences will never match the newline character 0 --nnoolliinneessttoopp This allows . and [^ sequences to match the newline char- acter 0 which they will otherwise not do (see the regexp command for details). This option is only meaningful if -regexp is also given, and an error will be thrown other- wise. For example, to match the entire text, use pathName search -nolinestop -regexp ".*" 1.0. --nnooccaassee Ignore case differences between the pattern and the text. --ccoouunntt _v_a_r_N_a_m_e The argument following -count gives the name of a vari- able; if a match is found, the number of index positions between beginning and end of the matching range will be stored in the variable. If there are no embedded images or windows in the matching range (and there are no elided characters if -elide is not given), this is equivalent to the number of characters matched. In either case, the range matchIdx to matchIdx + $count chars will return the entire matched text. --aallll Find all matches in the given range and return a list of the indices of the first character of each match. If a -count varName switch is given, then varName is also set to a list containing one element for each successful match. Note that, even for exact searches, the elements of this list may be different, if there are embedded images, windows or hidden text. Searches with -all behave very similarly to the Tcl command regexp -all, in that overlapping matches are not normally returned. For exam- ple, applying an -all search of the pattern 1992Z against ZooZooZoo will just match once. --oovveerrllaapp When performing -all searches, the normal behaviour is that matches which overlap an already-found match will not be returned. This switch changes that behaviour so that all matches which are not totally enclosed within another match are returned. For example, applying an -overlap search of the pattern 2304Z against ZooZooZoo will now match twice. An error will be thrown if this switch is used without -all. --ssttrriiccttlliimmiittss When performing any search, the normal behaviour is that the start and stop limits are checked with respect to the start of the matching text. With the -strictlimits flag, the entire matching range must lie inside the start and stop limits specified for the match to be valid. --eelliiddee _c_u_r_r_e_n_t_l_y _n_o_t _s_u_p_p_o_r_t_e_d Find elided (hidden) text as well. By default only dis- played text is searched. ---- This switch has no effect except to terminate the list of switches: the next argument will be treated as pattern even if it starts with -. The matching range may be within a single line of text, or run across multiple lines (if parts of the pattern can match a new-line). For reg- ular expression matching one can use the various newline-matching fea- tures such as $ to match the end of a line, ^ to match the beginning of a line, and to control whether . is allowed to match a new-line. If stopIndex is specified, the search stops at that index: for forward searches, no match at or after stopIndex will be considered; for back- ward searches, no match earlier in the text than stopIndex will be con- sidered. If stopIndex is omitted, the entire text will be searched: when the beginning or end of the text is reached, the search continues at the other end until the starting location is reached again; if stopIndex is specified, no wrap-around will occur. This means that, for example, if the search is -forwards but stopIndex is earlier in the text than startIndex, nothing will ever be found. See the Tk Text wid- get man page for more information. _p_a_t_h_N_a_m_e sscciisseeaarrcchh _?_s_w_i_t_c_h_e_s_? _p_a_t_t_e_r_n _i_n_d_e_x _?_s_t_o_p_I_n_d_e_x_? Scintilla Search searches the text in pathName starting at index for a range of characters that matches pattern. If a match is found, the index of the first character in the match is returned as result; otherwise an empty string is returned. One or more of the following switches (or abbreviations thereof) may be speci- fied to control the search: --ffoorrwwaarrddss The search will proceed forward through the text, finding the first matching range starting at or after the posi- tion given by index. This is the default. --bbaacckkwwaarrddss The search will proceed backward through the text, find- ing the matching range closest to index whose first char- acter is before index (it is not allowed to be at index). --ccoouunntt _v_a_r_N_a_m_e The argument following -count gives the name of a vari- able; if a match is found, the number of index positions between beginning and end of the matching range will be stored in the variable. --eexxaacctt Use exact matching: the characters in the matching range must be identical to those in pattern. This is the default. --nnooccaassee Ignore case differences between the pattern and the text. --rreeggeexxpp Treat pattern as a regular expression. In a regular expression, special characters interpreted are: Matches any character. \\(( This marks the start of a region for tagging a match. \\)) This marks the end of a tagged region. \\nn Where n is 1 through 9 refers to the first through ninth tagged region when replacing. For example, if the search string was Fred\([1-9]\)XXX and the replace string was Sam1YYY, when applied to Fred2XXX this would gen- erate Sam2YYY. refers to all of the matching text. \\<< This matches the start of a word using Scin- tilla's definitions of words. \\>> This matches the end of a word using Scintilla's definition of words. \\xx This allows you to use a character x that would otherwise have a special meaning. For example, \[ would be interpreted as [ and not as the start of a character set. [[......]] This indicates a set of characters, for example, [abc] means any of the characters a, b or c. You can also use ranges, for example [a-z] for any lower case character. [[^^......]] The complement of the characters in the set. For example, [^A-Za-z] means any character except an alphabetic character. ^^ This matches the start of a line (unless used inside a set, see above). $$ This matches the end of a line. ** This matches 0 or more times. For example, Sa*m matches Sm, Sam, Saam, Saaam and so on. ++ This matches 1 or more times. For example, Sa+m matches Sam, Saam, Saaam and so on. Regular expressions will only match ranges within a single line, never matching over multiple lines. --wwoorrdd A match only occurs if the characters before and after are not word characters. ---- This switch has no effect except to terminate the list of switches: the next argument will be treated as pattern even if it starts with -. The matching range must be within a single line of text. For regular expression matching one can use the various newline-matching features such as $ to match the end of a line, ^ to match the beginning of a line. If stopIndex is specified, the search stops at that index: for forward searches, no match at or after stopIndex will be considered; for backward searches, no match earlier in the text than stopIndex will be considered. If stopIndex is omitted, the entire text will be searched. _p_a_t_h_N_a_m_e sseeee _i_n_d_e_x _?_-_c_e_n_t_e_r_? Adjusts the view in the window so that the character given by index is completely visible. If index is already visible then the command does nothing. If index is a short distance out of view, the command adjusts the view just enough to make index visible at the edge of the window. If index is far out of view, then the command centers index in the window. The -center option can be used to force index to be centered in the window. _p_a_t_h_N_a_m_e ttaagg _?_o_p_t_i_o_n_? _?_a_r_g _a_r_g _._._._? A tag is a textual string that is associated with some of the characters in the widget. Tags may contain arbitrary characters, but it is probably best to avoid using the characters (space), +, or -: these characters have special meaning in indices, so tags containing them cannot be used as indices. There may be any number of tags associated with characters in a text. Each tag may refer to a single character, a range of characters, or sev- eral ranges of characters. An individual character may have any number of tags associated with it. The order that overlapping tags are displayed is controlled by the logical identifier asso- ciated with each of the tag types below(higher ID numbers are drawn last). See the table below for descriptions of the sup- ported types. The following forms of the command are currently supported: _p_a_t_h_N_a_m_e ttaagg aadddd _t_a_g_N_a_m_e _i_n_d_e_x_1 _?_i_n_d_e_x_2_? Associate the tag tagName (one will be created if it doesn't already exist) with all of the characters start- ing with index1 and ending just before index2 (the char- acter at index2 is not tagged). If index2 is omitted then the single character at index1 is tagged. If there are no characters in the specified range (e.g. index1 is past the end of the file or index2 is less than or equal to index1) then the command has no effect. EXCEPTION: If tagName is the predefined selection tag (i.e. "sel"), then specifying index2 to be less than index1 will have the effect of positioning the insertion point at the start of the selection. _p_a_t_h_N_a_m_e ttaagg bbiinndd _t_a_g_N_a_m_e _?_s_e_q_u_e_n_c_e_? _?_s_c_r_i_p_t_? This command associates script with the tag given by tag- Name. Whenever the event sequence given by sequence occurs for a character that has been tagged with tagName, the script will be invoked. This widget command is simi- lar to the bind command except that it operates on char- acters in a text rather than entire widgets. See the bind manual entry for complete details on the syntax of sequence and the substitutions performed on script before invoking it. If all arguments are specified then a new binding is created, replacing any existing binding for the same sequence and tagName (if the first character of script is + then script augments an existing binding rather than replacing it). In this case the return value is an empty string. If script is omitted then the command returns the script associated with tagName and sequence (an error occurs if there is no such binding). If both script and sequence are omitted then the command returns a list of all the sequences for which bindings have been defined for tagName. The only events for which bindings may be specified are those related to the mouse and key- board (such as Enter, Leave, ButtonPress, Motion, and KeyPress) or virtual events. Event bindings for a text widget use the current mark. An Enter event triggers for a tag when the tag first becomes present on the current character, and a Leave event triggers for a tag when it ceases to be present on the current character. Enter and Leave events can happen either because the current mark moved or because the character at that position changed. Note that these events are different than Enter and Leave events for windows. Mouse and keyboard events are directed to the current character. If a virtual event is used in a binding, that binding can trigger only if the virtual event is defined by an underlying mouse-related or keyboard-related event. _p_a_t_h_N_a_m_e ttaagg ccggeett _t_a_g_N_a_m_e _o_p_t_i_o_n This command returns the current value of the option named option associated with the tag given by tagName. Option may have any of the values accepted by the path- Name tag configure widget command. _p_a_t_h_N_a_m_e ttaagg ccoonnffiigguurree _t_a_g_N_a_m_e _?_-_m_a_r_g_i_n_? _?_o_p_t_i_o_n_? _?_v_a_l_u_e_? _?_o_p_t_i_o_n _v_a_l_u_e _._._._? This command is similar to the pathName configure widget command except that it modifies options associated with the tag given by tagName instead of modifying options for the overall text widget. If no option is specified, the command returns a list describing all of the available options for tagName. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corre- sponding sublist of the value returned if no option is specified). If one or more option-value pairs are speci- fied, then the command modifies the given option(s) to have the given value(s) in tagName; in this case the com- mand returns an empty string. Note, the special -margin option, if used, must immediately follow tagName. It is used to create and configure tags used within the margin area. See "configure options" for more details _p_a_t_h_N_a_m_e ttaagg ddeelleettee _t_a_g_N_a_m_e _?_t_a_g_N_a_m_e _._._._? Deletes all tag information for each of the tagName argu- ments. The command removes the tags from all characters in the file and also deletes any other information asso- ciated with the tags, such as bindings and display infor- mation. The command returns an empty string. _p_a_t_h_N_a_m_e ttaagg lloowweerr _t_a_g_N_a_m_e This has NOT BEEN IMPLEMENTED because Scintilla core functionality regarding "markers" (which is how the Scin- tillaTk tag functionality has been implemented) does not support drawing priority for markers that overlap. _p_a_t_h_N_a_m_e ttaagg nnaammeess _?_i_n_d_e_x_? Returns a list whose elements are the names of all the tags that are active at the character position given by index. If index is omitted, then the return value will describe all of the tags that exist for the widget. _p_a_t_h_N_a_m_e ttaagg nneexxttrraannggee _t_a_g_N_a_m_e _i_n_d_e_x_1 _?_i_n_d_e_x_2_? This command searches the text for a range of characters tagged with tagName where the first character of the range is no earlier than the character at index1 and no later than the character just before index2 (a range starting at index2 will not be considered). The command's return value is a list containing two elements, which are the index of the first character of the range and the index of the character just after the last one in the range. If no matching range is found then the return value is an empty string. If index2 is not given then it defaults to the end of the text. _p_a_t_h_N_a_m_e ttaagg pprreevvrraannggee _t_a_g_N_a_m_e _i_n_d_e_x_1 _?_i_n_d_e_x_2_? This command searches the text for a range of characters tagged with tagName where the first character of the range is before the character at index1 and no earlier than the character at index2 (a range starting at index2 will be considered). The command's return value is a list containing two elements, which are the index of the first character of the range and the index of the character just after the last one in the range. If no matching range is found then the return value is an empty string. If index2 is not given then it defaults to the beginning of the text. _p_a_t_h_N_a_m_e ttaagg rraaiissee _t_a_g_N_a_m_e This has NOT BEEN IMPLEMENTED because Scintilla core functionality regarding "markers" (which is how the Scin- tillaTk tag functionality has been implemented) does not support drawing priority for markers that overlap. _p_a_t_h_N_a_m_e ttaagg rraannggeess _t_a_g_N_a_m_e Returns a list describing all of the ranges of text that have been tagged with tagName. The first two elements of the list describe the first tagged range in the text, the next two elements describe the second range, and so on. The first element of each pair contains the index of the first character of the range, and the second element of the pair contains the index of the character just after the last one in the range. If there are no characters tagged with tag then an empty string is returned. _p_a_t_h_N_a_m_e ttaagg rreemmoovvee _t_a_g_N_a_m_e _i_n_d_e_x_1 _?_i_n_d_e_x_2 _i_n_d_e_x_1 _i_n_d_e_x_2 _._._._? Remove the tag tagName from all of the characters start- ing at index1 and ending just before index2 (the charac- ter at index2 is not affected). A single command may con- tain any number of index1-index2 pairs. If the last index2 is omitted then the tag is removed from the single character at index1. If there are no characters in the specified range (e.g. index1 is past the end of the file or index2 is less than or equal to index1) then the com- mand has no effect. This command returns an empty string. TTaagg TTyyppeess +----------------------------------------------------------------------------------+ |TTyyppee IIDD DDeessccrriippttiioonn | |plain 0 Underlined with a single, straight line. | |squiggle 1 A squiggly underline, 3 pixels in height | |tt 2 A line of small "T" shapes | |diagonal 3 Diagonal hatching | |strike 4 A solid "strike through" line draw at the vertical mid-point | |hidden 5 No visual effect | |box 6 A rectangular box around the text | |roundbox 7 A rectangle with rounded corners around the text, using | | translucent drawing for the interior (NOT SUPPORTED YET) | |squarebox 8 A rectangle around the text, using translucent drawing for | | the interior (NOT SUPPORTED YET) | |dash 9 A dashed underline | |dots 10 A dotted underline | |squigglelow 11 Similar to squiggle but only 2 pixels in height | |dotbox 12 A dotted rectangle around the text, using translucent draw- | | ing for the interior (NOT SUPPORTED YET) | +----------------------------------------------------------------------------------+ For the above types, use the -foreground configuration option for the tag to control the color. For types that use a filled interior, use the -background option to set the interior color. The following lists the supported configuration options, though not all are supported for each type of tag (exceptions are noted): --bbaacckkggrroouunndd||--bbgg _c_o_l_o_r Color specifies the color used for tags that have a filled inte- rior. --bboolldd _b_o_o_l_e_a_n (ONLY FOR MARGIN TAGS) Specifies if margins showing text will use a bold font --ffoorreeggrroouunndd||--ffgg _c_o_l_o_r Color specifies the color used for tags, and for tags will filled interiors color is for the outline. --iinnddiiccaattoorrttyyppee _t_y_p_e (NOT FOR MARGIN TAGS) The type value matches the names in the above table --iittaalliicc _b_o_o_l_e_a_n (ONLY FOR MARGIN TAGS) Specifies if margins showing text will use an italicized font There is a special tag used to control the appearance (fore- ground and background colors only) of the widget's selection. The name of this tag is sel, and it cannot be deleted. _p_a_t_h_N_a_m_e vveerrssiioonn Returns a 3-element list containing information identifying the current version of the widget. The fields of the list are: ver- sion : identifies the Tcl package version date : the date the package was created core_rls: this identifies the release of the Scintilla core widget KKNNOOWWNN BBUUGGSS Patterns including newline (0 may not work correctly in all cases. This limitation is due to how Scintilla stores document text; the end of line characters are stripped from the document making the search chal- lenging. The pathName search -regexp sub-command attempts to perform sophisti- cated regexp matching across multiple lines in an efficient fashion. Under certain conditions the search result might differ from that obtained by applying the same regexp to the entire text from the widget in one go. Whenever one possible match is fully enclosed in another, the search command will attempt to ensure only the larger match is returned. When performing backwards regexp searches it is possible that Tcl will not always achieve this. Tk 0.25 scintilla(n) |
Added tk/license.terms.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
Copyright (c) 2013 Mentor Graphics Corporation All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----- Portions of the code here came from Tcl 8.5 under the following license terms: This software is copyrighted by the Regents of the University of California, Sun Microsystems, Inc., and other parties. The following terms apply to all files associated with the software unless explicitly disclaimed in individual files. The authors hereby grant permission to use, copy, modify, distribute, and license this software and its documentation for any purpose, provided that existing copyright notices are retained in all copies and that this notice is included verbatim in any distributions. No written agreement, license, or royalty fee is required for any of the authorized uses. Modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated on the first page of each file where they apply. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. GOVERNMENT USE: If you are acquiring this software on behalf of the U.S. government, the Government shall have only "Restricted Rights" in the software and related documentation as defined in the Federal Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you are acquiring the software on behalf of the Department of Defense, the software shall be classified as "Commercial Computer Software" and the Government shall have only "Restricted Rights" as defined in Clause 252.227-7013 (b) (3) of DFARs. Notwithstanding the foregoing, the authors grant the U.S. Government and others acting in its behalf permission to use and distribute the software in accordance with the terms specified in this license. |
Added tk/makefile.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
# Make file for Scintilla on Linux or compatible OS # Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> # The License.txt file describes the conditions under which this software may be distributed. # This makefile assumes GCC 4.3 is used and changes will be needed to use other compilers. # GNU make does not like \r\n line endings so should be saved to CVS in binary form. # Builds for GTK+ 2 and no longer supports GTK+ 1. # Also works with ming32-make on Windows. # Environment variable WINDIR always defined on Win32 # NOTES: # 1) To enable a debug build : define PROFILE -OR- DEBUG # 2) To enable a 32-bit build : define BIT32 ifdef PROFILE DEBUG=1 endif ifdef WINDIR OBJSUFFIX = .obj SHLIBSUFFIX = .dll else OBJSUFFIX = .o SHLIBSUFFIX = .so endif .SUFFIXES: .cxx .c $(OBJSUFFIX) .h .a ######################################################### # Tools/commands ######################################################### ifdef WINDIR CC = cl CCOMP = cl LINK = link ifndef PRODDIR PROD = //prod/prod else PROD = $(PRODDIR) endif else CC = g++ CCOMP = gcc PROD = /u/prod FPIC = -fPIC MMFLAG = -MM LINK = g++ endif AR = ar COPY = cp RANLIB = touch DEL = rm -f COMPLIB=../bin/scintilla.a MKDIR = mkdir vpath %.h ../src ../include ../lexlib vpath %.cxx ../src ../lexlib ../lexers ######################################################### # Variables # # NOTE: use 8.5 to match Modelsim mainline #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # The current TCL version used by Modelsim can be found # by searching for "TCLN" in src/misc/platform.mk # ######################################################### TCLVER=tcl8513-20130313 ifdef DEBUG TCLDIR=$(PROD)/tcltk/$(TCLVER)/debug else TCLDIR=$(PROD)/tcltk/$(TCLVER)/opt endif # Retrieve the Scintilla core version (stored in the version.txt file) SCI_CORE_VER = $(shell cat ../version.txt) PACKAGE_VERSION = "\"0.25\"" PACKAGE_DATE = \"$(shell date "+%Y-%m-%d (beta)")\" ifdef WINDIR #-------------- #-- WINDOWS #-------------- ifdef DEBUG DBGLIB=g endif ifdef BIT32 TCLSH=$(shell /usr/bin/cygpath -m $(TCLDIR)/win32/usr/bin/tclsh85$(DBGLIB).exe) TCL85INCLUDE=$(shell /usr/bin/cygpath -m $(TCLDIR)/win32/usr/include) TCL85LIBLOC=$(shell /usr/bin/cygpath -m $(TCLDIR)/win32/usr/lib) else TCLSH=$(shell /usr/bin/cygpath -m $(TCLDIR)/win64/usr/bin/tclsh85$(DBGLIB).exe) TCL85INCLUDE=$(shell /usr/bin/cygpath -m $(TCLDIR)/win64/usr/include) TCL85LIBLOC=$(shell /usr/bin/cygpath -m $(TCLDIR)/win64/usr/lib) endif else #-------------- #-- LINUX #-------------- TCLSH=$(TCLDIR)/linux/usr/bin/tclsh8.5 TCL85INCLUDE=$(TCLDIR)/linux_x86_64/usr/include endif # Name of the primary shared library SHAREDLIB := libscintilla$(SHLIBSUFFIX) SHAREDDBGLIB := libscintilla$(DBGLIB)$(SHLIBSUFFIX) INCLUDEDIRS=-I $(TCL85INCLUDE) -I ../include -I ../src -I ../lexlib ifdef WINDIR CXXBASEFLAGS := -Od /EHsc else # Using -Wno-write-strings to avoid warnings about calls like this: # warning: deprecated conversion from string constant to 'char*' # # These occur from code like this: # Tcl_SetResult(interp, "some message text", TCL_STATIC) CXXBASEFLAGS := $(FPIC) -Wno-write-strings -Wall -Wno-missing-braces -Wno-char-subscripts -Wno-long-long -pedantic endif CXXBASEFLAGS += -DTK -DSCI_LEXER $(INCLUDEDIRS) -DSCI_CORE_VERSION=\"$(SCI_CORE_VER)\" ifdef NOTHREADS THREADFLAGS=-DG_THREADS_IMPL_NONE else THREADFLAGS= endif ifdef DEBUG ifdef WINDIR LINKFLAGS=/DEBUG else LINKFLAGS=-g endif endif # Package support definitions PKGNAME := ScintillaTk PKGDIR := $(PKGNAME) PKGINDEX:=$(PKGDIR)/pkgIndex.tcl WIDGETTCL:=scintillatk.tcl ifdef DEBUG PKGOBJS:=$(WIDGETTCL) $(SHAREDDBGLIB) else PKGOBJS:=$(WIDGETTCL) $(SHAREDLIB) endif ifdef WINDIR ifdef DEBUG #include the debug file PKGOBJS += libscintilla$(DBGLIB).pdb endif endif ifdef WINDIR LINKOBJS:= widget.obj ScintillaTK.obj ../bin/scintilla.a tcl85$(DBGLIB).lib tk85$(DBGLIB).lib LINKCMD = $(LINK) $(LINKFLAGS) /DLL /OUT:libscintilla$(DBGLIB).dll /LIBPATH:$(TCL85LIBLOC) $(LINKOBJS) else LINKCMD = $(LINK) $(LINKFLAGS) -shared -Wl,-soname,libscintilla.so -o libscintilla.so widget.o ScintillaTK.o ../bin/scintilla.a endif ifdef WINDIR #-------------- #--- WINDOWS #-------------- CXXFLAGS := -DWIN32 -D_WIN32 -D__CYGWIN__ -D__MWERKS__ $(CXXBASEFLAGS) $(THREADFLAGS) ifdef DEBUG CXXFLAGS := $(CXXFLAGS) -Z7 -DDEBUG endif else #-------------- #-- LINUX #-------------- ifdef DEBUG CXXFLAGS=-DDEBUG -g $(CXXBASEFLAGS) $(THREADFLAGS) else CXXFLAGS=-DNDEBUG -Os $(CXXBASEFLAGS) $(THREADFLAGS) endif endif ifdef BIT32 CXXFLAGS += -m32 LINKFLAGS += -m32 endif CXXFLAGS += -DPACKAGE_VERSION=$(PACKAGE_VERSION) -DPACKAGE_DATE="$(PACKAGE_DATE)" CFLAGS:=$(CXXFLAGS) OPTIONS=-DSCI_NAMESPACE .cxx$(OBJSUFFIX): $(CC) $(OPTIONS) $(CXXFLAGS) -c $< .c$(OBJSUFFIX): $(CCOMP) $(OPTIONS) $(CFLAGS) -w -c $< LEXOBJS:=$(addsuffix $(OBJSUFFIX),$(basename $(notdir $(wildcard ../lexers/Lex*.cxx)))) SRCOBJS:=$(addsuffix $(OBJSUFFIX),$(basename $(notdir $(wildcard ../lexlib/*cxx ../src/*.cxx *cxx)))) ################################################## # Build Targets ################################################## all: $(COMPLIB) $(SHAREDLIB) $(PKGINDEX) clean: $(DEL) -r *.o *.obj $(COMPLIB) libscintilla* $(PKGDIR) ../bin/* localclean: $(DEL) -r $(PKGDIR) ScintillaTK$(OBJSUFFIX) PlatTK$(OBJSUFFIX) widget*$(OBJSUFFIX) sciwrappers$(OBJSUFFIX) libscintilla* deps: $(CC) $(MMFLAG) $(CXXFLAGS) *.h *.cxx ../src/*.cxx | sed -e 's/\/usr.* //' | grep '[a-zA-Z]' >deps.mak ifdef WINDIR ifndef BIT32 # win64 doesn't like ar output, use lib instead $(COMPLIB): $(SRCOBJS) \ $(LEXOBJS) lib /OUT:$@ $^ else $(COMPLIB): $(SRCOBJS) \ $(LEXOBJS) $(AR) rc $@ $^ $(RANLIB) $@ endif else $(COMPLIB): $(SRCOBJS) \ $(LEXOBJS) $(AR) rc $@ $^ $(RANLIB) $@ endif $(SHAREDLIB): $(COMPLIB) $(LINKCMD) # target to get a Tcl package created, which is what client code would load # support for auto-versioning the package WIDGET_SRC := widget.cxx # NOTE: we want to use an explicit package name with the "load" command to prevent # Tcl from deriving the "init" C function name based on the name of the library $(PKGINDEX): widget$(OBJSUFFIX) $(PKGOBJS) $(DEL) -r $(PKGDIR) $(MKDIR) $(PKGDIR) $(COPY) $(PKGOBJS) $(PKGDIR) @echo "*** Creating pkgIndex.tcl file using VERSION $(PACKAGE_VERSION)" @echo "package ifneeded $(PKGNAME) $(PACKAGE_VERSION) \"\\" >>$(PKGINDEX) @echo " load [file join \$$dir $(SHAREDDBGLIB)] $(PKGNAME);\\" >>$(PKGINDEX) @echo " source [file join \$$dir $(WIDGETTCL)]\"" >>$(PKGINDEX) ifndef WINDIR # Automatically generate header dependencies with "make deps" include deps.mak endif |
Added tk/man/mann.
> |
1 |
../doc
|
Added tk/pkgIndex.tcl.in.
> > > > > > > > > |
1 2 3 4 5 6 7 8 9 |
# Tcl package index file - handcrafted # NOTE: keep version string in sync with the line # containing Tcl_PkgProvide in widget.cxx package ifneeded @PACKAGE_NAME@ @PACKAGE_VERSION@ "\ load [file join $dir @PKG_LIB_FILE@] @PACKAGE_NAME@;\ source [file join $dir iface.tcl];\ source [file join $dir scintillatk.tcl]" |
Added tk/scintilla-cmd.cxx.
more than 10,000 changes
Added tk/scintilla-cmd.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 |
// // scintilla-cmd.h -- // // Declarations shared among the files that implement the Tk-flavor // of the Scintilla editor widget. // // Copyright (c) 2013 Mentor Graphics Corporation // The license.terms file describes the conditions under which this software may be distributed. #ifndef _SCINTILLA_CMD #define _SCINTILLA_CMD #include <string.h> // NOTE: Because the Scintilla code is C++, we need for this Tcl widget // to use a C++ compiler #include "Scintilla.h" #include <SciLexer.h> #include "ScintillaWidget.h" #include <bitset> #include "Platform.h" // for access to PRectangle using namespace Scintilla; // create a namespace for ourselves namespace TkSci { //---------------------------------------------------------------- // We do _NOT_ want the following within the TkSci namespace. // next one needs C access because it's called as an idle task extern "C" void SciWidgetDisplay (ClientData clientData); #ifdef _WIN32 extern "C" __declspec(dllexport) int Scintillatk_Init(Tcl_Interp *interp); #endif //---------------------------------------------------------------- // define mapping macros to go between Tk's 1-based line number // and Scintilla's 0-based line numbers #define LINE2TK(ln) ((ln < 0) ? ln : (ln + 1)) #define LINE2SCI(ln) ((ln < 0) ? ln : (ln - 1)) // Flag bit definitions. // #define REDRAW_PENDING 0x1 #define GOT_FOCUS 0x2 #define REDRAW_YSCROLL 0x4 #define REDRAW_XSCROLL 0x8 #define REDRAW_EXPOSE 0x10 #define INIT_CFG_DONE 0x20 #define BUSY_MODE 0x40 #define BUTTON_DOWN 0x80 #define DESTROYED 0x100 #define RESIZE 0x120 // data structure describing a change in the // number of lines within the widget typedef struct { int line; // the line location of the add/delete int added; // >0 to indicate an addition, <0 indicates a deletion } SciWidgetLinesAdded; // forward decl class MarginMgr; class TagMgr; class MarkerMgr; class MarkMgr; // data structure for widget typedef struct { ScintillaObject *editor; Tcl_Interp *interp; Tcl_Command widgetCmd; Tk_Window tkwin; Display *display; GC copyGC; Pixmap mainPixmap; int width; int height; Tk_OptionTable optionTable; Tk_BindingTable bindingTable; /* widget-specific options */ Tk_Font tkfont; Tk_Cursor cursor; Tk_Cursor busycursor; Tk_3DBorder background; XColor *foreground; XColor *highlight; XColor *highlightBg; XColor *marginBg; XColor *marginFg; int relief; int highlightWidth; int borderWidth; int reqWidth; int reqHeight; char *showws; char *takefocus; int tabwidth; int state; bool readonly; char *language; int langType; int foldstyle; char undo; char autoseps; // only provided to be compatible w/ Tk Text widget char inUndoAction; // keeps track of undo collection state when "edit separator" used char *blinkcaret; /* callback commands */ char *linesAddedCmd; char *marginWidthCmd; char *moveUpdateCmd; char *yScrollCmd; char *xScrollCmd; /* other stuff */ int padX; int padY; int yscrollDelta; int flags; MarginMgr *marginMgr; MarkerMgr *markerMgr; MarkMgr *markMgr; TagMgr *tagMgr; SciWidgetLinesAdded *added_data; int styleBits; // number of bits in styleId devoted to style, remainder of 8 bits are indicator bits /* data used for expose repaints */ int expose_x; int expose_y; int expose_w; int expose_h; } SciWidget; // provide a callback mechanism for code on the Scintilla side #define SCIW_SYNC_XSCROLL 100 #define SCIW_SYNC_YSCROLL 101 #define SCIW_MOVE_UPDATE 102 #define SCIW_LINESADDED_UPDATE 103 #define SCIW_MODIFIED 104 extern void MessageFromScintilla(ClientData clientData, int msg_id, uptr_t data); extern void MessageFromScintilla(ClientData clientData, int msg_id); //////////////////////////////////////////////////////////////////// // Margin management // enum MarginType { NONE, LINE_NUMS, LINE_NUMS_ALT, TEXT, RTEXT, SYMBOL, FOLD }; static const char *MarginTypeNames[] = { "none", "lnums", "lnums_alt", "text", "rtext", "symbol", "fold" }; #define IS_LINE_NUMS(t) (t == LINE_NUMS || t == LINE_NUMS_ALT) #define IS_TEXT_TYPE(t) (IS_LINE_NUMS(t) || t == TEXT || t == RTEXT) // data structure to hold configuration options used by each margin typedef struct { char *alias; //(STRING) an alternate name(ie alias) for identifying the margin char *clickcmd; //(STRING) command to callback for clicks (null = clicks disabled) int type; //(STRING_TABLE) index of margin type in MarginTypeNames int width; //(INT) margin's width(in pixels) - value of "0" will hide the margin Tk_Cursor cursor; //(CURSOR) margin's cursor } MarginOptions; //------------------------------------- // CLASS MarginData //------------------------------------- class MarginData { public: MarginData(MarginMgr *, int, int); ~MarginData(); // these can't be changed by client going thru the // options interface, so we keep them as class data // int col_id; // Scintilla uses columns 0 - 4 int viswidth; // holds width when margin is visible // other info MarginMgr *mgr; MarginOptions *mopts; Tk_OptionTable optionTable; // functions int Configure(int, Tcl_Obj *CONST[]); // accessor calls for options data const char *GetAlias() { return mopts->alias; } const char *GetClickCmd() { return mopts->clickcmd; } const char *GetTypeStr() { return MarginTypeNames[mopts->type]; } MarginType GetType() { return static_cast<MarginType>(mopts->type); } Tk_Cursor GetCursor() { return mopts->cursor; } const char *GetCursorStr(); int GetWidth() { return mopts->width; } int GetVisibleWidth() { return viswidth; } void SetWidth(int w) { mopts->width = w; viswidth = w;} }; //------------------------------------- // CLASS MarginMgr //------------------------------------- class MarginMgr { public: MarginMgr(SciWidget *); ~MarginMgr(); // these support the command interface to the widget int CmdBbox (int objc, Tcl_Obj *CONST objv[]); int CmdCget (int objc, Tcl_Obj *CONST objv[]); int CmdConfig (int objc, Tcl_Obj *CONST objv[]); int CmdDump (int objc, Tcl_Obj *CONST objv[]); int CmdFillNums(int objc, Tcl_Obj *CONST objv[]); int CmdIndex (int objc, Tcl_Obj *CONST objv[]); int CmdMarker (int objc, Tcl_Obj *CONST objv[]); int CmdShow (int objc, Tcl_Obj *CONST objv[], bool); int CmdTag (int objc, Tcl_Obj *CONST objv[]); int CmdText (int objc, Tcl_Obj *CONST objv[]); int CmdVisible (int objc, Tcl_Obj *CONST objv[]); int InstanceCmd(int objc, Tcl_Obj *CONST objv[]); void Click(XButtonEvent be); void DumpText(Tcl_DString *dstr, int line1, int idx1, int line2, int idx2, const char* command); int Get(Tcl_Obj *, int *); int GetLineNWidth(int ndigits = 0); void RemoveMarker(int id); void RemoveMarker(int marginID, int id); void RemoveAllMarkers(int marginID); bool SetCursor(int x, int y); void UpdateMargin(int); int ValidateTypeChange(int); int Width(); void ZoomPre(); void ZoomPost(); private: //--- VARIABLES static const int MAXM = 5; // largest margin id MarginData *margins[MAXM]; SciWidget *sciwidgetPtr; // note: required var name for use by SSM macro public: // give easy access to MarginData Tcl_Interp *interp; Display *display; Tk_Window tkwin; private: // linenumber and fold columns are special. make it easy to find them int currLnum; int currFold; int preZoomWidth; // holds char width prior to a zoom //--- FUNCTIONS int _atX(int x); void _click(int, int, int, int, int, bool, bool, bool); bool _hasMarker(int, int); int _get(Tcl_Obj *, int *); void _reportError(const char *); void _reportError(Tcl_Obj *); int _show(int id, bool show); int _validAlias(const char *); int _validId(int); int _validName(const char *, int *); int _validType(const char *, MarginType *); }; //////////////////////////////////////////////////////////////////// // Tag management typedef enum { TT_TEXT = 1, TT_MARG = 2, TT_INDIC = 4 } TagType; // tags can be associated with an indicator style (they match those // defined by Scintilla, but aren't hardwired to their constant values) typedef enum { indicNONE, indicPlain, // solid 1-pixel underline indicSquiggle, // squiggly 3-pixel high underline indicTt, // small "T" shapes drawn under text indicDiag, // diaganol hatching indicStrike, // strike-through drawn at midpoint of text indicHidden, // an indicator that has no visual attributes indicBox, // rectangle drawn around text using solid 1-pixel line indicRoundBox, // rectange w/ rounded corners drawn around text - uses transparent interior indicSquareBox, // same as above but with square corners indicDash, // dashed underline indicDots, // dotted underline indicSquiggleLow, // same as indicSquiggle but only using 2 pixels indicDotBox // dotted rectangle around text - uses transparent interior } IndicTypeID; // data structure to hold configuration options used by each tag typedef struct { const char *name; // symbolic name of the tag int style_id; // Scintilla style id int indic_id; // Scintilla id used for indicators XColor *fgColor; // foreground color of text XColor *bgColor; // background color of text int bold; // boolean to indicate if text is bold int italic ; // boolean to indicate if text is italicized int underline; // boolean to indicate if text is underlined int tagType; // mask intended to identify the owning area (text or margin) IndicTypeID indicType; // indicator type (if any) Tk_OptionTable optionTable;// table to hold config options const char *Name() { return name; } int Bold() { return bold; } int Italic() { return italic; } int Underline() { return underline; } XColor *BG() { return bgColor; } XColor *FG() { return fgColor; } int StyleID() { return style_id; } int IndicID() { return indic_id; } int Type() { return tagType; } IndicTypeID IndicType() { return indicType; } } TagData; //------------------------------------- // CLASS TagMgr //------------------------------------- class TagMgr { public: TagMgr(SciWidget *); ~TagMgr(); // these support the command interface to the widget int CmdAdd (int objc, Tcl_Obj *CONST objv[]); int CmdBind (int objc, Tcl_Obj *CONST objv[]); int CmdCget (int objc, Tcl_Obj *CONST objv[]); int CmdConfig (int objc, Tcl_Obj *CONST objv[]); int CmdDelete (int objc, Tcl_Obj *CONST objv[]); int CmdNames (int objc, Tcl_Obj *CONST objv[]); int CmdNPRange (int objc, Tcl_Obj *CONST objv[], bool next); int CmdRanges (int objc, Tcl_Obj *CONST objv[]); int CmdRemove (int objc, Tcl_Obj *CONST objv[]); int InstanceCmd(int objc, Tcl_Obj *CONST objv[]); void HandleBindEvent(XEvent *eventPtr); void BindEvent(XEvent *eventPtr, int nTags, TagData **tagArrayPtr); void DumpText(int mask, Tcl_DString *dstr, int pos1, int pos2, const char *command); void DumpMargin(int mask, Tcl_DString *dstr, int line1, int pos1, int line2, int pos2, const char *command); TagData *FindTag(const char *tagname); TagData *FindTag(int style_id); void FireSelectionVirtual(); TagData *GetMarginTag() { return marginTag; } TagData *GetSelectTag() { return selTag; } void PickCurrent(XEvent *); void SaveRestore(bool save); void UpdateMarginColor(bool bg, bool fg); TagData *ValidateForMargin(const char *tagname); bool IsIndicator(TagData *tagPtr) { return (tagPtr->IndicType() != indicNONE); } // return list of all margin tags Tcl_Obj *GetMarginTags(Tcl_Interp *interp); private: int _configIndicator(TagData *, int mask = -1); TagData *_createTag(int ttMask, const char *tagname, int *newTag = NULL); void _deleteTag(const char *tagname); void _deleteTag(TagData *tagPtr, bool force = false); TagData **_getTagsAtPos(int pos, int *num); bool _isTagAtPos(TagData *tagPtr, int pos, const char *tagName = NULL); int _nextStyleID(int *, int ttMask); int _nextIndicID(int *); void _setIndicStyle(TagData *, int); // for testing purposes void _dump (TagData *tagPtr = NULL); void _dumpIt(TagData *tagPtr); const char *TAG_SEL; bool IS_SEL(const char *tagname) { return (strcmp(tagname, TAG_SEL) == 0); } const char *TAG_MARGIN; bool IS_MARGIN(const char *tagname) { return (strcmp(tagname, TAG_MARGIN) == 0); } SciWidget *sciwidgetPtr; Tcl_Interp *interp; Tk_Window tkwin; Tcl_HashTable tagTable; TagData *selTag; // special built-in tag for selection TagData *marginTag; // special built-in tag for the margins int freeIndic; // bit mask of available indicators (max 32) std::bitset<255> freeTextStyles; std::bitset<255> freeMarginStyles; int numTags; // total number of defined tags // info used for event bindings associated with tags XEvent pickEvent; /* The event used to determine "current" character */ int numCurTags; /* Number of tags associated with character at * current mark. */ TagData **curTagArrayPtr; /* Pointer to array of tags for current mark, * or NULL if none. */ }; //////////////////////////////////////////////////////////////////// // Marker management // data structure for marker configuration options typedef struct { XColor *bgColor; //(COLOR) bgd color of marker XColor *fgColor; //(COLOR) fgd color char *imgName; //(STRING) name of Tk image - only used w/ -image option int type; //(STRING_TABLE) index of marker type in MarkerTypeNames char *xpmData; //(STRING) char array containing XPM data - only used w/ -xpm option } MarkerOptions; //------------------------------------- // CLASS MarkerData //------------------------------------- class MarkerData { public: MarkerData(MarkerMgr *); ~MarkerData(); // these can't be changed by client going thru the // options interface, so we keep them as class data // char *name; // name to identify the marker int id; // logical ID identifying bit-mask position int handle; // Scintilla handle created when this marker is assigned int typeID; // Scintilla constant (eg SC_MARK_xxx) int margin; // ID of margin holding this marker int cloned_n; // the count of how many cloned copies there are MarkerData *cloned_from; // is cloned, this will be the marker it was cloned from // other info MarkerMgr *mgr; MarkerOptions *mopts; Tk_OptionTable optionTable; void UpdateType(); void Copy(MarkerData *src); int CloneCount() { return cloned_n; } bool IsClone() { return (cloned_from != NULL); } bool MatchName(const char *src_name); }; //------------------------------------- // CLASS MarkerMgr //------------------------------------- typedef enum { cloneCopy, // 0 cloneDelete // 1 } CloneOpId; class MarkerMgr { public: MarkerMgr(SciWidget *); ~MarkerMgr(); // these support the command interface to the widget int CmdConfig (int objc, Tcl_Obj *CONST objv[]); int CmdDelete (int objc, Tcl_Obj *CONST objv[]); int CmdExists (int objc, Tcl_Obj *CONST objv[]); int CmdNames (int objc, Tcl_Obj *CONST objv[], bool include_clones = false); int InstanceCmd(int objc, Tcl_Obj *CONST objv[]); int AddMarker(int marginID, MarkerData *mPtr, int line); MarkerData *FindMarker(const char *); MarkerData *FindMarker(int marker_id); MarkerData *FindMarker(int marginID, const char *, bool ok_to_clone = true); int GetMaxId(); private: MarkerData *_cloneOp(CloneOpId, MarkerData *); MarkerData *_cloneMarker(const char *, MarkerData *); MarkerData *_createMarker(const char *, int *); void _deleteMarker(MarkerData *); void _deleteMarkerImpl(MarkerData *); int _getNextId(); int _validateImage(MarkerData *, bool check_xpm); // for testing purposes void _dump (MarkerData *mPtr = NULL); void _dumpIt(MarkerData *mPtr); Tcl_HashTable markerTable; int ids; public: // for easy access by MarkerData SciWidget *sciwidgetPtr; Tcl_Interp *interp; Tk_Window tkwin; }; //////////////////////////////////////////////////////////////////// // Mark management (this is the same as Tk Text widget "marks") typedef struct { const char *name; int pos; bool gravityLeft; // TRUE = left, FALSE = right } MarkData; //------------------------------------- // CLASS MarkMgr //------------------------------------- class MarkMgr { public: MarkMgr(SciWidget *); ~MarkMgr(); // these support the command interface to the widget int CmdGravity (int objc, Tcl_Obj *CONST objv[]); int CmdSet (int objc, Tcl_Obj *CONST objv[]); int InstanceCmd(int objc, Tcl_Obj *CONST objv[]); MarkData *AddMark(const char *name, int pos); MarkData *FindMark(const char *, int *offset = NULL); int GetCurrentPos() { return currentMark->pos; } // dump marks in selected margin from line1 to line2 void Dump(Tcl_DString *dstr, int margin_id, int line1, int line2, const char *command); private: MarkData *_createMark(const char *name, int *newMark = NULL); void _deleteMark(MarkData *); // for testing purposes void _dump(MarkData *mPtr = NULL); SciWidget *sciwidgetPtr; MarkData *insertMark; // special built-in mark MarkData *currentMark; // special built-in mark Tcl_HashTable markTable; Tcl_Interp *interp; Tk_Window tkwin; }; } // end of "using namespace TkSci" #endif |
Added tk/scintilla-ext.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
// Scintilla source code edit control // scintilla-ext.cxx - This file provides access to the widget services required by // code outside(aka "EXTernal") of the widget implementation // Copyright (c) 2013 Mentor Graphics Corporation // The license.terms file describes the conditions under which this software may be distributed. #include "scintilla-ext.h" #include "scintilla-cmd.h" using namespace TkSci; namespace TkSciExt { //================================================== // Return the current width of the visible margins //================================================== int GetMarginWidth(ClientData d) { SciWidget *sciw = (SciWidget *)d; return sciw->marginMgr->Width(); } //================================================== // Store the main pixmap that we get from the // platform code //================================================== void SetPixmap(ClientData d, Pixmap p) { SciWidget *sciw = (SciWidget *)d; sciw->mainPixmap = p; } //================================================== // Add the specified Y delta to the current value // being maintained in the widget //================================================== void SetYScrollDelta(ClientData d, int delta) { SciWidget *sciw = (SciWidget *)d; sciw->yscrollDelta += delta; } //================================================== // Schedule an update to redraw following a // scroll change initiated by the user //================================================== void UpdateForScroll(ClientData d) { SciWidget *sciw = (SciWidget *)d; if ( !(sciw->flags & REDRAW_PENDING) ) { //printf("ScrollText -- QUEUING DISPLAY\n"); Tk_DoWhenIdle(SciWidgetDisplay, d); } else { //printf("ScrollText -- SKIPPING REDRAW...\n"); } sciw->flags |= REDRAW_PENDING|REDRAW_YSCROLL; } //================================================== // Callback from Scintilla that lines were added. // Note, if the "added" value is <0 it means that // lines were removed instead of added. //================================================== void MSG_LinesAdded(ClientData d, int line, int added) { SciWidget *sciw = (SciWidget *)d; sciw->added_data->line = LINE2TK(line); sciw->added_data->added = added; MessageFromScintilla(sciw, SCIW_LINESADDED_UPDATE); } //================================================== // Callback from Scintilla to change mouse cursor //================================================== void MSG_SetCursor(ClientData d, int cursor_id) { SciWidget *sciw = (SciWidget *)d; //TODO: this needs a better way to indicate what //cursor is being request MessageFromScintilla(sciw, static_cast<int>(cursor_id)); } //================================================== // Callback from Scintilla that we use to notify // client so it can respond to a change // to the current document contents. //================================================== void MSG_Modified(ClientData d) { SciWidget *sciw = (SciWidget *)d; MessageFromScintilla(sciw, SCIW_MODIFIED); } //================================================== // Callback from Scintilla that we use to notify // client so it can respond to a possible change // to the current document position. //================================================== void MSG_MoveUpdate(ClientData d) { SciWidget *sciw = (SciWidget *)d; MessageFromScintilla(sciw, SCIW_MOVE_UPDATE); } //================================================== // Sync the widget's scroll position data based on // a programmatic change from Scintilla //================================================== void MSG_SyncXScroll(ClientData d) { SciWidget *sciw = (SciWidget *)d; MessageFromScintilla(sciw, SCIW_SYNC_XSCROLL); } void MSG_SyncYScroll(ClientData d) { SciWidget *sciw = (SciWidget *)d; MessageFromScintilla(sciw, SCIW_SYNC_YSCROLL); } }//--- end of TkSciExt namespace |
Added tk/scintilla-ext.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
// Scintilla source code edit control // scintilla-ext.cxx - This file provides access to the widget services required by // code outside(aka "EXTernal") of the widget implementation // Copyright (c) 2013 Mentor Graphics Corporation // The license.terms file describes the conditions under which this software may be distributed. #ifndef _SCINTILLA_EXT #define _SCINTILLA_EXT #include <tcl.h> #include <tk.h> #include "Scintilla.h" // the following constant is used to allow the widget code to preserve // point sizes set by Tk which use a negative value(to indicate pixels) #define MAGIC_FONT_OFFSET 1000 #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // create out namespace namespace TkSciExt { int GetMarginWidth (ClientData d); void SetPixmap (ClientData d, Pixmap p); void SetYScrollDelta(ClientData d, int delta); void UpdateForScroll(ClientData d); void MSG_SetCursor (ClientData d, int cursor_id); void MSG_LinesAdded (ClientData d, int line, int added); void MSG_Modified (ClientData d); void MSG_MoveUpdate (ClientData d); void MSG_SyncXScroll(ClientData d); void MSG_SyncYScroll(ClientData d); }//--- end of TkSciExt namespace #endif |
Added tk/scintillatk.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# ScintillaTK class bindings option add *Scintilla.textbackground white # We won't assume clients want a default selection action when a multi-click # event occurs in the margin area - we'll leave that up to the client bind Scintilla <Double-1> { if {[%W margin index @%x,%y] == ""} { set tk::Priv(selectMode) word tk::TextSelectTo %W %x %y catch {%W mark set insert sel.first} } } bind Scintilla <Triple-1> { if {[%W margin index @%x,%y] == ""} { set tk::Priv(selectMode) line tk::TextSelectTo %W %x %y catch {%W mark set insert sel.first} } } # Mimic some of the button bindings from Tk Text widget set btns { 1 B1-Motion B1-Enter B1-Leave ButtonRelease-1 } foreach e $btns { bind Scintilla <$e> [bind Text <$e>] } #OVERLOAD: we have to overload this one because of the -state value check where # the Tk code looks for "== normal". Since our Scintilla widget implementation # allows a state value of "readonly" and we still want to be able to receive # focus upon a click, we change the check to "!= disabled". proc ::tk::TextButton1 {w x y} { variable ::tk::Priv set Priv(selectMode) char set Priv(mouseMoved) 0 set Priv(pressX) $x set anchorname [tk::TextAnchor $w] $w mark set insert [TextClosestGap $w $x $y] $w mark set $anchorname insert # Set the anchor mark's gravity depending on the click position # relative to the gap set bbox [$w bbox [$w index $anchorname]] if {$x > [lindex $bbox 0]} { $w mark gravity $anchorname right } else { $w mark gravity $anchorname left } # Allow focus in any case on Windows, because that will let the # selection be displayed even for state disabled text widgets. if {$::tcl_platform(platform) eq "windows" \ || [$w cget -state] ne "disabled"} { focus $w } } # Note: this is an overload of the function called by the Text class # binding for B1-Leave. We're using the pre-8.5 implementation because # beginning in 8.5 the scrolling was pixel-based, which isn't supported # in Scintilla. proc ::tk::TextAutoScan {w} { variable ::tk::Priv if {![winfo exists $w]} return if {$Priv(y) >= [winfo height $w]} { $w yview scroll 2 units } elseif {$Priv(y) < 0} { $w yview scroll -2 units } elseif {$Priv(x) >= [winfo width $w]} { $w xview scroll 2 units } elseif {$Priv(x) < 0} { $w xview scroll -2 units } else { return } TextSelectTo $w $Priv(x) $Priv(y) set Priv(afterId) [after 50 [list tk::TextAutoScan $w]] } #OVERLOAD: see below proc ::tk::TextKeySelect {w new} { set anchorname [tk::TextAnchor $w] if {[$w tag nextrange sel 1.0 end] eq ""} { set insert_ix [$w index insert] if {[$w compare $new < insert]} { $w tag add sel $new insert } else { $w tag add sel insert $new } #---------------------------------------------------------------------- # This differs from the code in text.tcl because of a fundamental # difference between Scintilla selection behavior and Tk Text. # The latter allows independent positioning of the insert location # relative to the selection; whereas Scintilla requires it to be # one of the extents of the selection region. So the problem we face, # which is the reason for this overload, is the above call to add # the selection: "tag add sel insert $new" will actually cause a change # in the location of the insertion point with Scintilla. Since the # intent of the next command is to move the anchor to where the insert # point was at the start of this function, we get that location first # and then reuse it via "$insert_ix" #---------------------------------------------------------------------- $w mark set $anchorname $insert_ix } else { if {[$w compare $new < $anchorname]} { set first $new set last $anchorname } else { set first $anchorname set last $new } $w tag remove sel 1.0 $first $w tag add sel $first $last $w tag remove sel $last end } $w mark set insert $new $w see insert update idletasks } # define the class key bindings bind Scintilla <Left> { %W mark set insert "charleft" } bind Scintilla <Right> { %W mark set insert "charright" } bind Scintilla <Up> { %W mark set insert "lineup" } bind Scintilla <Down> { %W mark set insert "linedown" } bind Scintilla <Home> { %W mark set insert "linehome" } bind Scintilla <End> { %W mark set insert "lineend" } bind Scintilla <Control-Home> { %W mark set insert "top" } bind Scintilla <Control-End> { %W mark set insert "bottom" } # Mimic some of the key bindings from Tk Text widget set keys { Shift-Left Shift-Right Shift-Up Shift-Down Shift-Home Shift-End } foreach e $keys { bind Scintilla <$e> [bind Text <$e>] } bind Scintilla <Next> { %W yview scroll 1 pages } bind Scintilla <Prior> { %W yview scroll -1 pages } bind Scintilla <Return> { ::tk::ScintillaInsert %W \n } bind Scintilla <Delete> { if {[%W tag nextrange sel 1.0 end] ne ""} { %W delete sel.first sel.last } else { %W delete insert %W see insert } } bind Scintilla <BackSpace> { if {[%W tag nextrange sel 1.0 end] ne ""} { %W delete sel.first sel.last } elseif {[%W compare insert != 1.0]} { %W delete insert-1c %W see insert } } bind Scintilla <Control-KP_Add> {%W zoomin} bind Scintilla <Control-KP_Subtract> {%W zoomout} if { [tk windowingsystem] eq "win32" } { bind Scintilla <Control-Key-plus> {%W zoomin} bind Scintilla <Control-Key-minus> {%W zoomout} } # This next group of bindings mimics what is used for the Tk Text widget. #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Ignore all Alt, Meta, and Control keypresses unless explicitly bound. # Otherwise, if a widget binding for one of these is defined, the # <KeyPress> class binding will also fire and insert the character, # which is wrong. Ditto for <Escape>. bind Scintilla <Alt-KeyPress> {# nothing } bind Scintilla <Meta-KeyPress> {# nothing} bind Scintilla <Control-KeyPress> {# nothing} bind Scintilla <Escape> {# nothing} bind Scintilla <KP_Enter> {# nothing} bind Scintilla <KeyPress> { ::tk::ScintillaInsert %W %A } # MOUSE WHEEL bind Scintilla <Button-4> { %W yview scroll -5 units } bind Scintilla <Button-5> { %W yview scroll 5 units } if { [tk windowingsystem] eq "win32" } { # NOTE: match Tk 8.4 behavior, since 8.5 uses pixel-level scrolling bind Scintilla <MouseWheel> { %W yview scroll [expr {- (%D / 120) * 4}] units } } ############################################################################# # define the functions tied to the bindings proc ::tk::ScintillaInsert {w s} { # prevent insert if state is disabled or readonly if {$s eq "" || [$w cget -state] ne "normal"} { return } #puts "INSERT $w --> (($s))" if {[$w tag nextrange sel 1.0 end] ne ""} { $w delete sel.first sel.last } $w insert insert $s $w see insert } |
Added tk/sciwrappers.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 |
// Scintilla source code edit control // sciwrappers.cxx - Wrapper functions around Scintilla msg api. // Copyright (c) 2013 Mentor Graphics Corporation // The license.terms file describes the conditions under which this software may be distributed. #include <string.h> #include "sciwrappers.h" #define _UNUSED_ 0 // macro to simplify calling scintilla message API #define SSM(sci, m, w, l) scintilla_send_message(sci, m, w, l) // macro to convert an XColor value for scintilla #define _XRGB_(c) (c->red & 0xff) | (c->green & 0xff)<<8 | (c->blue & 0xff)<<16 sptr_t sci_cmd(ScintillaObject *sci, int msg, uptr_t wparam, sptr_t lparam) { return SSM(sci, msg, wparam, lparam); } //############################################################################# // ACTIONs //############################################################################# //============================================================================= // sci_add_text // // Add new text at the specified document position //----------------------------------------------------------------------------- void sci_add_text(ScintillaObject *sci, int pos, const char *s) { // check if the add is being done at the insertion point, and if it // is then we want the add to cause the insertion point to be moved // to the end of the added text. int currpos = sci_get_current_pos(sci); //fprintf(stderr,"add: currpos %d pos %d\n", currpos, pos); // inserting text clears the current selection, remember what the selection was int sel_beg = sci_cmd(sci, SCI_GETSELECTIONSTART, _UNUSED_, _UNUSED_); int sel_end = sci_cmd(sci, SCI_GETSELECTIONEND, _UNUSED_, _UNUSED_); if (pos == currpos) { SSM(sci, SCI_ADDTEXT, strlen(s), (sptr_t)s); // moves insert pt after the add } else { SSM(sci, SCI_INSERTTEXT, pos, (sptr_t)s); } if (sel_beg != sel_end) { // restore selection if one existed before insert int len = strlen(s); if (pos < sel_beg) { // text inserted before selection // adjust selection offsets so they remain on same text sel_beg += len; sel_end += len; } else if ((pos >= sel_beg) && (pos <= sel_end)) { // text inserted within selection // "grow" selection by the added text sel_end += len; } sci_cmd(sci, SCI_SETSELECTIONSTART, sel_beg, _UNUSED_); sci_cmd(sci, SCI_SETSELECTIONEND, sel_end, _UNUSED_); } } //============================================================================= // sci_delete_text // // Deletes text between two positions //----------------------------------------------------------------------------- void sci_delete_text(ScintillaObject *sci, int pos1, int pos2) { if (pos1 == pos2) return; if (pos1 > pos2) { int tmp = pos2; pos2 = pos1; pos1 = tmp; } SSM(sci, SCI_SETTARGETSTART, pos1, 0); SSM(sci, SCI_SETTARGETEND, pos2, 0); SSM(sci, SCI_REPLACETARGET, 0, (sptr_t)""); } //============================================================================= // sci_enable_margin_click // // Set a margin to receive (or disable) click notifications //----------------------------------------------------------------------------- void sci_enable_margin_click(ScintillaObject *sci, int m, bool enable) { SSM(sci, SCI_SETMARGINSENSITIVEN, m, (sptr_t)enable); } //============================================================================= // sci_goto_pos // // Change current position and scroll(if needed) to see it //----------------------------------------------------------------------------- void sci_goto_pos(ScintillaObject *sci, int pos) { int sel_beg = sci_cmd(sci, SCI_GETSELECTIONSTART, _UNUSED_, _UNUSED_); int sel_end = sci_cmd(sci, SCI_GETSELECTIONEND, _UNUSED_, _UNUSED_); int end = sci_get_length(sci); if (pos && pos == end) pos--; //fprintf(stderr,"sci_goto_pos %d\n", pos); SSM(sci, SCI_GOTOPOS, pos, 0); // this will clear the selection!!! if (sel_beg != sel_end) { // restore selection SSM(sci, SCI_SETSELECTIONSTART, sel_beg, _UNUSED_); SSM(sci, SCI_SETSELECTIONEND, sel_end, _UNUSED_); } } //============================================================================= // sci_has_selection // // Return whether any text is selected //----------------------------------------------------------------------------- bool sci_has_selection(ScintillaObject *sci) { int pos1 = SSM(sci, SCI_GETSELECTIONSTART, 0, 0); int pos2 = SSM(sci, SCI_GETSELECTIONEND, 0, 0); return (pos1 != pos2); } //============================================================================= // sci_redo //----------------------------------------------------------------------------- void sci_redo(ScintillaObject *sci) { SSM(sci, SCI_REDO, 0, 0); } //============================================================================= // sci_reset_undo_history // // Clears the undo/redo history buffers //----------------------------------------------------------------------------- void sci_reset_undo_history(ScintillaObject *sci) { SSM(sci, SCI_EMPTYUNDOBUFFER, 0, 0); } //============================================================================= // sci_select // // Selects a range of text. If additive is TRUE then a "alternate" // selection is created (preserving the "main" selection) //----------------------------------------------------------------------------- void sci_select(ScintillaObject *sci, int pos1, int pos2, bool additive) { int end = sci_get_length(sci); if ((pos2 == end) && (pos2 > 0)) { int lastChar = SSM(sci, SCI_GETCHARAT, pos2-1, 0); // don't include final end of line at end of document if (lastChar == '\n') --pos2; } if (additive) { // Need special handling to do additive tagging for the selection // tag since Scintilla will by default remove an existing selection // before setting a new one. SSM(sci, SCI_ADDSELECTION, pos1, pos2); } else { SSM(sci, SCI_SETANCHOR, pos1, 0); SSM(sci, SCI_SETCURRENTPOS, pos2, 0); } } //============================================================================= // sci_show_ws // // Control display of whitespace indicators //----------------------------------------------------------------------------- void sci_show_ws(ScintillaObject *sci, bool show) { if (show) SSM(sci, SCI_SETVIEWWS, SCWS_VISIBLEALWAYS, 0); else SSM(sci, SCI_SETVIEWWS, SCWS_INVISIBLE, 0); } //============================================================================= // sci_toggle_fold // // Toggle the fold level for the specfied line // // NOTE: LINE NUMBER IS 0-BASED //----------------------------------------------------------------------------- void sci_toggle_fold(ScintillaObject *sci, int line) { SSM(sci, SCI_TOGGLEFOLD, line, 0); } //============================================================================= // sci_undo //----------------------------------------------------------------------------- void sci_undo(ScintillaObject *sci) { SSM(sci, SCI_UNDO, 0, 0); } //============================================================================= // sci_zoom_in/sci_zoom_out // // Causes the document font size to be increased/decreased by a set amount //----------------------------------------------------------------------------- void sci_zoom_in(ScintillaObject *sci) { SSM(sci, SCI_ZOOMIN, 0, 0); } void sci_zoom_out(ScintillaObject *sci) { SSM(sci, SCI_ZOOMOUT, 0, 0); } //############################################################################# // GETs //############################################################################# //============================================================================= // sci_get_column // // Return the column position from a document position //----------------------------------------------------------------------------- int sci_get_column(ScintillaObject *sci, int pos) { int end = sci_get_length(sci); if (end && pos == end) pos--; return SSM(sci, SCI_GETCOLUMN, pos, 0); } //============================================================================= // sci_get_current_pos // // Returns the current document position(ie where insertion point is) //----------------------------------------------------------------------------- int sci_get_current_pos(ScintillaObject *sci) { return SSM(sci, SCI_GETCURRENTPOS, 0, 0); } //============================================================================= // sci_get_foldlevel // // Return the fold level for the specified line number // // NOTE: LINE NUMBER IS 0-BASED //----------------------------------------------------------------------------- int sci_get_foldlevel(ScintillaObject *sci, int line) { return SSM(sci, SCI_GETFOLDLEVEL, line, 0); } //============================================================================= // sci_get_is_modified // // Return if the document is currently modified(1) or not(0) //----------------------------------------------------------------------------- int sci_get_is_modified(ScintillaObject *sci) { return SSM(sci, SCI_GETMODIFY, 0, 0); } //============================================================================= // sci_get_length // // Return the number of characters in the document //----------------------------------------------------------------------------- int sci_get_length(ScintillaObject *sci) { return SSM(sci, SCI_GETLENGTH, 0, 0); } //============================================================================= // sci_get_line // // Return line number for a document position // // NOTE: LINE NUMBER IS 0-BASED //----------------------------------------------------------------------------- int sci_get_line(ScintillaObject *sci, int pos) { return SSM(sci, SCI_LINEFROMPOSITION, pos, 0); } //============================================================================= // sci_get_line_count // // Return the number of lines in the document //----------------------------------------------------------------------------- int sci_get_line_count(ScintillaObject *sci) { return SSM(sci, SCI_GETLINECOUNT, 0, 0); } //============================================================================= // sci_get_line_length // // Return length(in characters) of a line //----------------------------------------------------------------------------- int sci_get_line_length(ScintillaObject *sci, int line) { return SSM(sci, SCI_LINELENGTH, line, 0); } //============================================================================= // sci_get_line_markers // // Return mask indicating which markers exist on the specified line //----------------------------------------------------------------------------- int sci_get_line_markers(ScintillaObject *sci, int line) { return SSM(sci, SCI_MARKERGET, line, 0); } //============================================================================= // sci_get_lineend_pos // // Return the document position for a line // // NOTE: LINE NUMBER IS 0-BASED //----------------------------------------------------------------------------- int sci_get_lineend_pos(ScintillaObject *sci, int line) { return SSM(sci, SCI_GETLINEENDPOSITION, line, 0); } //============================================================================= // sci_get_margin_mask // // Return the margin mask for a specific margin //----------------------------------------------------------------------------- int sci_get_margin_mask(ScintillaObject *sci, int m) { return SSM(sci, SCI_GETMARGINMASKN, m, 0); } //============================================================================= // sci_get_margin_width // // Get the width(in pixels) of the specified margin //----------------------------------------------------------------------------- int sci_get_margin_width(ScintillaObject *sci, int m) { return SSM(sci, SCI_GETMARGINWIDTHN, m, 0); } //============================================================================= // sci_get_pos // // Return document position for specified line number // // NOTE: LINE NUMBER IS 0-BASED //----------------------------------------------------------------------------- int sci_get_pos(ScintillaObject *sci, int line) { return SSM(sci, SCI_POSITIONFROMLINE, line, 0); } //============================================================================= // sci_get_pos_from_xy // // Return document position for specified X/Y screen position // If "close" is true, then will only match if X/Y is actually determined // to be "close enough" to a character. //----------------------------------------------------------------------------- int sci_get_pos_from_xy(ScintillaObject *sci, int x, int y, bool close) { if (close) return SSM(sci, SCI_POSITIONFROMPOINTCLOSE, x, y); return SSM(sci, SCI_POSITIONFROMPOINT, x, y); } //============================================================================= // sci_get_text_height // // Return the height(in pixels) of the specified line // // NOTE: LINE NUMBER IS 0-BASED //----------------------------------------------------------------------------- int sci_get_text_height(ScintillaObject *sci, int line) { return SSM(sci, SCI_TEXTHEIGHT, line, 0); } //============================================================================= // sci_get_text_width // // Return the text width, using current default style, of an arbitrary string //----------------------------------------------------------------------------- int sci_get_text_width(ScintillaObject *sci, const char *str) { return (int)SSM(sci, SCI_TEXTWIDTH, STYLE_DEFAULT, (sptr_t)str); } //============================================================================= // sci_get_x_from_pos // // Return the screen X location corresponding to a document position //----------------------------------------------------------------------------- int sci_get_x_from_pos(ScintillaObject *sci, int pos) { return SSM(sci, SCI_POINTXFROMPOSITION, 0/*unused*/, pos); } //============================================================================= // sci_get_y_from_pos // // Return the screen Y location corresponding to a document position //----------------------------------------------------------------------------- int sci_get_y_from_pos(ScintillaObject *sci, int pos) { return SSM(sci, SCI_POINTYFROMPOSITION, 0/*unused*/, pos); } //============================================================================= // sci_get_zoom // // Return the current zoom level //----------------------------------------------------------------------------- int sci_get_zoom(ScintillaObject *sci) { return SSM(sci, SCI_GETZOOM, 0, 0); } //############################################################################# // SETs //############################################################################# //============================================================================= // sci_set_focus //----------------------------------------------------------------------------- void sci_set_focus(ScintillaObject *sci, bool turn_on) { SSM(sci, SCI_SETFOCUS, turn_on, 0); } //============================================================================= // sci_set_fold_flags // // The "flags" arg represents a bit-mask of various folding options //----------------------------------------------------------------------------- void sci_set_fold_flags(ScintillaObject *sci, int flags) { SSM(sci, SCI_SETFOLDFLAGS, flags, 0); } //============================================================================= // sci_set_font // // Propagate a font change to all known styles //----------------------------------------------------------------------------- void sci_set_font(ScintillaObject *sci, const char *family, int ptsize, bool bold, bool italic) { for (int i=0; i < STYLE_MAX; i++) { SSM(sci, SCI_STYLESETFONT, i, (sptr_t)family); SSM(sci, SCI_STYLESETSIZE, i, ptsize); SSM(sci, SCI_STYLESETBOLD, i, bold); SSM(sci, SCI_STYLESETITALIC, i, italic); } } //============================================================================= // sci_set_margin_mask // // Set the mask of which markers a margin is allowed to display //----------------------------------------------------------------------------- void sci_set_margin_mask(ScintillaObject *sci, int m, int mask) { SSM(sci, SCI_SETMARGINMASKN, m, mask); } //============================================================================= // sci_set_margin_width // // Set the width(in pixels) of the specified margin. A value of zero // will hide the margin. //----------------------------------------------------------------------------- void sci_set_margin_width(ScintillaObject *sci, int m, int width) { SSM(sci, SCI_SETMARGINWIDTHN, m, width); } //============================================================================= // sci_set_margin_type // // Set the type of a margin //----------------------------------------------------------------------------- void sci_set_margin_type(ScintillaObject *sci, int m, int type) { SSM(sci, SCI_SETMARGINTYPEN, m, type); } //============================================================================= // sci_set_padding // // Define how many pixels of padding exist between the left and right // edges of the text (the default Scintilla uses is 1). //----------------------------------------------------------------------------- void sci_set_padding(ScintillaObject *sci, int left, int right) { if (right < 0) right = left; SSM(sci, SCI_SETMARGINLEFT, 0/*unused*/, left); SSM(sci, SCI_SETMARGINRIGHT, 0/*unused*/, right); } //============================================================================= // sci_set_readonly //----------------------------------------------------------------------------- void sci_set_readonly(ScintillaObject *sci, bool ro) { SSM(sci, SCI_SETREADONLY, ro, 0); } //============================================================================= // sci_set_style_bg // // Sets the background color for the specified style //----------------------------------------------------------------------------- void sci_set_style_bg(ScintillaObject *sci, int id, XColor *c) { SSM(sci, SCI_STYLESETBACK, id, (c ? _XRGB_(c) : 0)); } //============================================================================= // sci_set_style_fg // // Sets the foreground color for the specified style //----------------------------------------------------------------------------- void sci_set_style_fg(ScintillaObject *sci, int id, XColor *c) { SSM(sci, SCI_STYLESETFORE, id, (c ? _XRGB_(c) : 0)); } //============================================================================= // sci_set_tab_width //----------------------------------------------------------------------------- void sci_set_tab_width(ScintillaObject *sci, int width) { SSM(sci, SCI_SETTABWIDTH, width, 0); } |
Added tk/sciwrappers.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
// Provide wrapper APIs for calling the scintilla // Copyright (c) 2013 Mentor Graphics Corporation // The license.terms file describes the conditions under which this software may be distributed. #ifndef SCIWRAPPERS_H #define SCIWRAPPERS_H #include "Scintilla.h" #include "ScintillaWidget.h" #ifdef __cplusplus extern "C" { #endif // Short-hand command API sptr_t sci_cmd(ScintillaObject *sci, int msg, uptr_t wparam = 0, sptr_t lparam = 0); // ACTIONs void sci_add_text (ScintillaObject *sci, int pos, const char *s); void sci_delete_text (ScintillaObject *sci, int pos1, int pos2); void sci_enable_margin_click(ScintillaObject *sci, int m, bool enable); void sci_goto_pos (ScintillaObject *sci, int pos); bool sci_has_selection (ScintillaObject *sci); void sci_redo (ScintillaObject *sci); void sci_reset_undo_history (ScintillaObject *sci); void sci_select (ScintillaObject *sci, int pos1, int pos2, bool additive=false); void sci_show_ws (ScintillaObject *sci, bool show); void sci_toggle_fold (ScintillaObject *sci, int line); void sci_undo (ScintillaObject *sci); void sci_zoom_in (ScintillaObject *sci); void sci_zoom_out (ScintillaObject *sci); // GETs int sci_get_column (ScintillaObject *sci, int pos); int sci_get_current_pos (ScintillaObject *sci); int sci_get_foldlevel (ScintillaObject *sci, int line); int sci_get_is_modified (ScintillaObject *sci); int sci_get_length (ScintillaObject *sci); int sci_get_line (ScintillaObject *sci, int pos); int sci_get_line_count (ScintillaObject *sci); int sci_get_line_length (ScintillaObject *sci, int line); int sci_get_line_markers (ScintillaObject *sci, int line); int sci_get_lineend_pos (ScintillaObject *sci, int line); int sci_get_margin_mask (ScintillaObject *sci, int m); int sci_get_margin_width (ScintillaObject *sci, int m); int sci_get_pos (ScintillaObject *sci, int line); int sci_get_pos_from_xy (ScintillaObject *sci, int x, int y, bool close = false); int sci_get_text_height (ScintillaObject *sci, int line); int sci_get_text_width (ScintillaObject *sci, const char *str); int sci_get_x_from_pos (ScintillaObject *sci, int pos); int sci_get_y_from_pos (ScintillaObject *sci, int pos); int sci_get_zoom (ScintillaObject *sci); // SETs void sci_set_focus (ScintillaObject *sci, bool turn_on); void sci_set_fold_flags (ScintillaObject *sci, int flags); void sci_set_font (ScintillaObject *sci, const char *family, int ptsize, bool bold, bool italic); void sci_set_margin_mask (ScintillaObject *sci, int m, int mask); void sci_set_margin_width (ScintillaObject *sci, int m, int width); void sci_set_margin_type (ScintillaObject *sci, int m, int type); void sci_set_padding (ScintillaObject *sci, int left, int right = -1); void sci_set_readonly (ScintillaObject *sci, bool ro); void sci_set_style_bg (ScintillaObject *sci, int id, XColor *c); void sci_set_style_fg (ScintillaObject *sci, int id, XColor *c); void sci_set_tab_width (ScintillaObject *sci, int width); #ifdef __cplusplus } #endif #endif |
Added tk/tclconfig/install-sh.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 |
#!/bin/sh # install - install a program, script, or datafile scriptversion=2011-04-20.01; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -S $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -S) stripcmd="$stripprog $2" shift;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names starting with `-'. case $src in -*) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # Protect names starting with `-'. case $dst in -*) dst=./$dst;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; -*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test -z "$d" && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: |
Added tk/tclconfig/tcl.m4.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 |
# tcl.m4 -- # # This file provides a set of autoconf macros to help TEA-enable # a Tcl extension. # # Copyright (c) 1999-2000 Ajuba Solutions. # Copyright (c) 2002-2005 ActiveState Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. AC_PREREQ(2.57) dnl TEA extensions pass us the version of TEA they think they dnl are compatible with (must be set in TEA_INIT below) dnl TEA_VERSION="3.9" # Possible values for key variables defined: # # TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem') # TEA_PLATFORM - windows unix # #------------------------------------------------------------------------ # TEA_PATH_TCLCONFIG -- # # Locate the tclConfig.sh file and perform a sanity check on # the Tcl compile flags # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-tcl=... # # Defines the following vars: # TCL_BIN_DIR Full path to the directory containing # the tclConfig.sh file #------------------------------------------------------------------------ AC_DEFUN([TEA_PATH_TCLCONFIG], [ dnl TEA specific: Make sure we are initialized AC_REQUIRE([TEA_INIT]) # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tcl # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true AC_ARG_WITH(tcl, AC_HELP_STRING([--with-tcl], [directory containing tcl configuration (tclConfig.sh)]), with_tclconfig="${withval}") AC_MSG_CHECKING([for Tcl configuration]) AC_CACHE_VAL(ac_cv_c_tclconfig,[ # First check to see if --with-tcl was specified. if test x"${with_tclconfig}" != x ; then case "${with_tclconfig}" in */tclConfig.sh ) if test -f "${with_tclconfig}"; then AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself]) with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`" fi ;; esac if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`" else AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh]) fi fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do if test "${TEA_PLATFORM}" = "windows" \ -a -f "$i/win/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/win; pwd)`" break fi if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/unix; pwd)`" break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /System/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tcl.framework/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`" break fi done fi # TEA specific: on Windows, check in common installation locations if test "${TEA_PLATFORM}" = "windows" \ -a x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d C:/Tcl/lib 2>/dev/null` \ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i; pwd)`" break fi done fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i; pwd)`" break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do if test "${TEA_PLATFORM}" = "windows" \ -a -f "$i/win/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/win; pwd)`" break fi if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/unix; pwd)`" break fi done fi ]) if test x"${ac_cv_c_tclconfig}" = x ; then TCL_BIN_DIR="# no Tcl configs found" AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh]) else no_tcl= TCL_BIN_DIR="${ac_cv_c_tclconfig}" AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh]) fi fi ]) #------------------------------------------------------------------------ # TEA_PATH_TKCONFIG -- # # Locate the tkConfig.sh file # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-tk=... # # Defines the following vars: # TK_BIN_DIR Full path to the directory containing # the tkConfig.sh file #------------------------------------------------------------------------ AC_DEFUN([TEA_PATH_TKCONFIG], [ # # Ok, lets find the tk configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tk # if test x"${no_tk}" = x ; then # we reset no_tk in case something fails here no_tk=true AC_ARG_WITH(tk, AC_HELP_STRING([--with-tk], [directory containing tk configuration (tkConfig.sh)]), with_tkconfig="${withval}") AC_MSG_CHECKING([for Tk configuration]) AC_CACHE_VAL(ac_cv_c_tkconfig,[ # First check to see if --with-tkconfig was specified. if test x"${with_tkconfig}" != x ; then case "${with_tkconfig}" in */tkConfig.sh ) if test -f "${with_tkconfig}"; then AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself]) with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`" fi ;; esac if test -f "${with_tkconfig}/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`" else AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh]) fi fi # then check for a private Tk library if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ../tk \ `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \ ../../tk \ `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \ ../../../tk \ `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do if test "${TEA_PLATFORM}" = "windows" \ -a -f "$i/win/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/win; pwd)`" break fi if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/unix; pwd)`" break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /System/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tk.framework/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`" break fi done fi # check in a few common install locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i; pwd)`" break fi done fi # TEA specific: on Windows, check in common installation locations if test "${TEA_PLATFORM}" = "windows" \ -a x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d C:/Tcl/lib 2>/dev/null` \ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i; pwd)`" break fi done fi # check in a few other private locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do if test "${TEA_PLATFORM}" = "windows" \ -a -f "$i/win/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/win; pwd)`" break fi if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/unix; pwd)`" break fi done fi ]) if test x"${ac_cv_c_tkconfig}" = x ; then TK_BIN_DIR="# no Tk configs found" AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh]) else no_tk= TK_BIN_DIR="${ac_cv_c_tkconfig}" AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh]) fi fi ]) #------------------------------------------------------------------------ # TEA_LOAD_TCLCONFIG -- # # Load the tclConfig.sh file # # Arguments: # # Requires the following vars to be set: # TCL_BIN_DIR # # Results: # # Substitutes the following vars: # TCL_BIN_DIR # TCL_SRC_DIR # TCL_LIB_FILE #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_TCLCONFIG], [ AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh]) if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then AC_MSG_RESULT([loading]) . "${TCL_BIN_DIR}/tclConfig.sh" else AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh]) fi # eval is required to do the TCL_DBGX substitution eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" # If the TCL_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TCL_LIB_SPEC will be set to the value # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC # instead of TCL_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. if test -f "${TCL_BIN_DIR}/Makefile" ; then TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}" TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}" TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}" elif test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use the libraries # from the framework at the given location so that linking works # against Tcl.framework installed in an arbitrary location. case ${TCL_DEFS} in *TCL_FRAMEWORK*) if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then for i in "`cd "${TCL_BIN_DIR}"; pwd`" \ "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}" break fi done fi if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}" TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}" fi ;; esac fi # eval is required to do the TCL_DBGX substitution eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" AC_SUBST(TCL_VERSION) AC_SUBST(TCL_PATCH_LEVEL) AC_SUBST(TCL_BIN_DIR) AC_SUBST(TCL_SRC_DIR) AC_SUBST(TCL_LIB_FILE) AC_SUBST(TCL_LIB_FLAG) AC_SUBST(TCL_LIB_SPEC) AC_SUBST(TCL_STUB_LIB_FILE) AC_SUBST(TCL_STUB_LIB_FLAG) AC_SUBST(TCL_STUB_LIB_SPEC) AC_MSG_CHECKING([platform]) hold_cc=$CC; CC="$TCL_CC" AC_TRY_COMPILE(,[ #ifdef _WIN32 #error win32 #endif ], TEA_PLATFORM="unix", TEA_PLATFORM="windows" ) CC=$hold_cc AC_MSG_RESULT($TEA_PLATFORM) # The BUILD_$pkg is to define the correct extern storage class # handling when making this package AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}, [], [Building extension source?]) # Do this here as we have fully defined TEA_PLATFORM now if test "${TEA_PLATFORM}" = "windows" ; then EXEEXT=".exe" CLEANFILES="$CLEANFILES *.lib *.dll *.pdb *.exp" fi # TEA specific: AC_SUBST(CLEANFILES) AC_SUBST(TCL_LIBS) AC_SUBST(TCL_DEFS) AC_SUBST(TCL_EXTRA_CFLAGS) AC_SUBST(TCL_LD_FLAGS) AC_SUBST(TCL_SHLIB_LD_LIBS) ]) #------------------------------------------------------------------------ # TEA_LOAD_TKCONFIG -- # # Load the tkConfig.sh file # # Arguments: # # Requires the following vars to be set: # TK_BIN_DIR # # Results: # # Sets the following vars that should be in tkConfig.sh: # TK_BIN_DIR #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_TKCONFIG], [ AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh]) if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then AC_MSG_RESULT([loading]) . "${TK_BIN_DIR}/tkConfig.sh" else AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh]) fi # eval is required to do the TK_DBGX substitution eval "TK_LIB_FILE=\"${TK_LIB_FILE}\"" eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\"" # If the TK_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TK_LIB_SPEC will be set to the value # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC # instead of TK_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. if test -f "${TK_BIN_DIR}/Makefile" ; then TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}" TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}" TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}" elif test "`uname -s`" = "Darwin"; then # If Tk was built as a framework, attempt to use the libraries # from the framework at the given location so that linking works # against Tk.framework installed in an arbitrary location. case ${TK_DEFS} in *TK_FRAMEWORK*) if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then for i in "`cd "${TK_BIN_DIR}"; pwd`" \ "`cd "${TK_BIN_DIR}"/../..; pwd`"; do if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}" break fi done fi if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}" TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}" fi ;; esac fi # eval is required to do the TK_DBGX substitution eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\"" eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\"" eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\"" eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\"" # TEA specific: Ensure windowingsystem is defined if test "${TEA_PLATFORM}" = "unix" ; then case ${TK_DEFS} in *MAC_OSX_TK*) AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?]) TEA_WINDOWINGSYSTEM="aqua" ;; *) TEA_WINDOWINGSYSTEM="x11" ;; esac elif test "${TEA_PLATFORM}" = "windows" ; then TEA_WINDOWINGSYSTEM="win32" fi AC_SUBST(TK_VERSION) AC_SUBST(TK_BIN_DIR) AC_SUBST(TK_SRC_DIR) AC_SUBST(TK_LIB_FILE) AC_SUBST(TK_LIB_FLAG) AC_SUBST(TK_LIB_SPEC) AC_SUBST(TK_STUB_LIB_FILE) AC_SUBST(TK_STUB_LIB_FLAG) AC_SUBST(TK_STUB_LIB_SPEC) # TEA specific: AC_SUBST(TK_LIBS) AC_SUBST(TK_XINCLUDES) ]) #------------------------------------------------------------------------ # TEA_PROG_TCLSH # Determine the fully qualified path name of the tclsh executable # in the Tcl build directory or the tclsh installed in a bin # directory. This macro will correctly determine the name # of the tclsh executable even if tclsh has not yet been # built in the build directory. The tclsh found is always # associated with a tclConfig.sh file. This tclsh should be used # only for running extension test cases. It should never be # or generation of files (like pkgIndex.tcl) at build time. # # Arguments: # none # # Results: # Substitutes the following vars: # TCLSH_PROG #------------------------------------------------------------------------ AC_DEFUN([TEA_PROG_TCLSH], [ AC_MSG_CHECKING([for tclsh]) if test -f "${TCL_BIN_DIR}/Makefile" ; then # tclConfig.sh is in Tcl build directory if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" else TCLSH_PROG="${TCL_BIN_DIR}/tclsh" fi else # tclConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" else TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}" fi list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/.. 2>/dev/null` \ `ls -d ${TCL_PREFIX}/bin 2>/dev/null`" for i in $list ; do if test -f "$i/${TCLSH_PROG}" ; then REAL_TCL_BIN_DIR="`cd "$i"; pwd`/" break fi done TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}" fi AC_MSG_RESULT([${TCLSH_PROG}]) AC_SUBST(TCLSH_PROG) ]) #------------------------------------------------------------------------ # TEA_PROG_WISH # Determine the fully qualified path name of the wish executable # in the Tk build directory or the wish installed in a bin # directory. This macro will correctly determine the name # of the wish executable even if wish has not yet been # built in the build directory. The wish found is always # associated with a tkConfig.sh file. This wish should be used # only for running extension test cases. It should never be # or generation of files (like pkgIndex.tcl) at build time. # # Arguments: # none # # Results: # Substitutes the following vars: # WISH_PROG #------------------------------------------------------------------------ AC_DEFUN([TEA_PROG_WISH], [ AC_MSG_CHECKING([for wish]) if test -f "${TK_BIN_DIR}/Makefile" ; then # tkConfig.sh is in Tk build directory if test "${TEA_PLATFORM}" = "windows"; then WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" else WISH_PROG="${TK_BIN_DIR}/wish" fi else # tkConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" else WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}" fi list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/.. 2>/dev/null` \ `ls -d ${TK_PREFIX}/bin 2>/dev/null`" for i in $list ; do if test -f "$i/${WISH_PROG}" ; then REAL_TK_BIN_DIR="`cd "$i"; pwd`/" break fi done WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}" fi AC_MSG_RESULT([${WISH_PROG}]) AC_SUBST(WISH_PROG) ]) #------------------------------------------------------------------------ # TEA_ENABLE_SHARED -- # # Allows the building of shared libraries # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-shared=yes|no # # Defines the following vars: # STATIC_BUILD Used for building import/export libraries # on Windows. # # Sets the following vars: # SHARED_BUILD Value of 1 or 0 #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_SHARED], [ AC_MSG_CHECKING([how to build libraries]) AC_ARG_ENABLE(shared, AC_HELP_STRING([--enable-shared], [build and link with shared libraries (default: on)]), [tcl_ok=$enableval], [tcl_ok=yes]) if test "${enable_shared+set}" = set; then enableval="$enable_shared" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" ; then AC_MSG_RESULT([shared]) SHARED_BUILD=1 else AC_MSG_RESULT([static]) SHARED_BUILD=0 AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?]) fi AC_SUBST(SHARED_BUILD) ]) #------------------------------------------------------------------------ # TEA_ENABLE_THREADS -- # # Specify if thread support should be enabled. If "yes" is specified # as an arg (optional), threads are enabled by default, "no" means # threads are disabled. "yes" is the default. # # TCL_THREADS is checked so that if you are compiling an extension # against a threaded core, your extension must be compiled threaded # as well. # # Note that it is legal to have a thread enabled extension run in a # threaded or non-threaded Tcl core, but a non-threaded extension may # only run in a non-threaded Tcl core. # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-threads # # Sets the following vars: # THREADS_LIBS Thread library(s) # # Defines the following vars: # TCL_THREADS # _REENTRANT # _THREAD_SAFE #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_THREADS], [ AC_ARG_ENABLE(threads, AC_HELP_STRING([--enable-threads], [build with threads]), [tcl_ok=$enableval], [tcl_ok=yes]) if test "${enable_threads+set}" = set; then enableval="$enable_threads" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then TCL_THREADS=1 if test "${TEA_PLATFORM}" != "windows" ; then # We are always OK on Windows, so check what this platform wants: # USE_THREAD_ALLOC tells us to try the special thread-based # allocator that significantly reduces lock contention AC_DEFINE(USE_THREAD_ALLOC, 1, [Do we want to use the threaded memory allocator?]) AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) if test "`uname -s`" = "SunOS" ; then AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) fi AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?]) AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no) if test "$tcl_ok" = "no"; then # Check a little harder for __pthread_mutex_init in the same # library, as some systems hide it there until pthread.h is # defined. We could alternatively do an AC_TRY_COMPILE with # pthread.h, but that will work with libpthread really doesn't # exist, like AIX 4.2. [Bug: 4359] AC_CHECK_LIB(pthread, __pthread_mutex_init, tcl_ok=yes, tcl_ok=no) fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthread" else AC_CHECK_LIB(pthreads, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthreads" else AC_CHECK_LIB(c, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "no"; then AC_CHECK_LIB(c_r, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -pthread" else TCL_THREADS=0 AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled]) fi fi fi fi fi else TCL_THREADS=0 fi # Do checking message here to not mess up interleaved configure output AC_MSG_CHECKING([for building with threads]) if test "${TCL_THREADS}" = 1; then AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?]) AC_MSG_RESULT([yes (default)]) else AC_MSG_RESULT([no]) fi # TCL_THREADS sanity checking. See if our request for building with # threads is the same as the way Tcl was built. If not, warn the user. case ${TCL_DEFS} in *THREADS=1*) if test "${TCL_THREADS}" = "0"; then AC_MSG_WARN([ Building ${PACKAGE_NAME} without threads enabled, but building against Tcl that IS thread-enabled. It is recommended to use --enable-threads.]) fi ;; *) if test "${TCL_THREADS}" = "1"; then AC_MSG_WARN([ --enable-threads requested, but building against a Tcl that is NOT thread-enabled. This is an OK configuration that will also run in a thread-enabled core.]) fi ;; esac AC_SUBST(TCL_THREADS) ]) #------------------------------------------------------------------------ # TEA_ENABLE_SYMBOLS -- # # Specify if debugging symbols should be used. # Memory (TCL_MEM_DEBUG) debugging can also be enabled. # # Arguments: # none # # TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives # the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted. # Requires the following vars to be set in the Makefile: # CFLAGS_DEFAULT # LDFLAGS_DEFAULT # # Results: # # Adds the following arguments to configure: # --enable-symbols # # Defines the following vars: # CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true # Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false # LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true # Sets to $(LDFLAGS_OPTIMIZE) if false # DBGX Formerly used as debug library extension; # always blank now. #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_SYMBOLS], [ dnl TEA specific: Make sure we are initialized AC_REQUIRE([TEA_CONFIG_CFLAGS]) AC_MSG_CHECKING([for build with symbols]) AC_ARG_ENABLE(symbols, AC_HELP_STRING([--enable-symbols], [build with debugging symbols (default: off)]), [tcl_ok=$enableval], [tcl_ok=no]) DBGX="" if test "$tcl_ok" = "no"; then CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG" LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}" AC_MSG_RESULT([no]) else CFLAGS_DEFAULT="${CFLAGS_DEBUG}" LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}" if test "$tcl_ok" = "yes"; then AC_MSG_RESULT([yes (standard debugging)]) fi fi # TEA specific: if test "${TEA_PLATFORM}" != "windows" ; then LDFLAGS_DEFAULT="${LDFLAGS}" fi AC_SUBST(CFLAGS_DEFAULT) AC_SUBST(LDFLAGS_DEFAULT) AC_SUBST(TCL_DBGX) if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?]) fi if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then if test "$tcl_ok" = "all"; then AC_MSG_RESULT([enabled symbols mem debugging]) else AC_MSG_RESULT([enabled $tcl_ok debugging]) fi fi ]) #------------------------------------------------------------------------ # TEA_ENABLE_LANGINFO -- # # Allows use of modern nl_langinfo check for better l10n. # This is only relevant for Unix. # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-langinfo=yes|no (default is yes) # # Defines the following vars: # HAVE_LANGINFO Triggers use of nl_langinfo if defined. #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_LANGINFO], [ AC_ARG_ENABLE(langinfo, AC_HELP_STRING([--enable-langinfo], [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]), [langinfo_ok=$enableval], [langinfo_ok=yes]) HAVE_LANGINFO=0 if test "$langinfo_ok" = "yes"; then AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no]) fi AC_MSG_CHECKING([whether to use nl_langinfo]) if test "$langinfo_ok" = "yes"; then AC_CACHE_VAL(tcl_cv_langinfo_h, [ AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);], [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])]) AC_MSG_RESULT([$tcl_cv_langinfo_h]) if test $tcl_cv_langinfo_h = yes; then AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?]) fi else AC_MSG_RESULT([$langinfo_ok]) fi ]) #-------------------------------------------------------------------- # TEA_CONFIG_SYSTEM # # Determine what the system is (some things cannot be easily checked # on a feature-driven basis, alas). This can usually be done via the # "uname" command. # # Arguments: # none # # Results: # Defines the following var: # # system - System/platform/version identification code. #-------------------------------------------------------------------- AC_DEFUN([TEA_CONFIG_SYSTEM], [ AC_CACHE_CHECK([system version], tcl_cv_sys_version, [ # TEA specific: if test "${TEA_PLATFORM}" = "windows" ; then tcl_cv_sys_version=windows else tcl_cv_sys_version=`uname -s`-`uname -r` if test "$?" -ne 0 ; then AC_MSG_WARN([can't find uname command]) tcl_cv_sys_version=unknown else if test "`uname -s`" = "AIX" ; then tcl_cv_sys_version=AIX-`uname -v`.`uname -r` fi fi fi ]) system=$tcl_cv_sys_version ]) #-------------------------------------------------------------------- # TEA_CONFIG_CFLAGS # # Try to determine the proper flags to pass to the compiler # for building shared libraries and other such nonsense. # # Arguments: # none # # Results: # # Defines and substitutes the following vars: # # DL_OBJS, DL_LIBS - removed for TEA, only needed by core. # LDFLAGS - Flags to pass to the compiler when linking object # files into an executable application binary such # as tclsh. # LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib", # that tell the run-time dynamic linker where to look # for shared libraries such as libtcl.so. Depends on # the variable LIB_RUNTIME_DIR in the Makefile. Could # be the same as CC_SEARCH_FLAGS if ${CC} is used to link. # CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib", # that tell the run-time dynamic linker where to look # for shared libraries such as libtcl.so. Depends on # the variable LIB_RUNTIME_DIR in the Makefile. # SHLIB_CFLAGS - Flags to pass to cc when compiling the components # of a shared library (may request position-independent # code, among other things). # SHLIB_LD - Base command to use for combining object files # into a shared library. # SHLIB_LD_LIBS - Dependent libraries for the linker to scan when # creating shared libraries. This symbol typically # goes at the end of the "ld" commands that build # shared libraries. The value of the symbol defaults to # "${LIBS}" if all of the dependent libraries should # be specified when creating a shared library. If # dependent libraries should not be specified (as on # SunOS 4.x, where they cause the link to fail, or in # general if Tcl and Tk aren't themselves shared # libraries), then this symbol has an empty string # as its value. # SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable # extensions. An empty string means we don't know how # to use shared libraries on this platform. # LIB_SUFFIX - Specifies everything that comes after the "libfoo" # in a static or shared library name, using the $VERSION variable # to put the version in the right place. This is used # by platforms that need non-standard library names. # Examples: ${VERSION}.so.1.1 on NetBSD, since it needs # to have a version after the .so, and ${VERSION}.a # on AIX, since a shared library needs to have # a .a extension whereas shared objects for loadable # extensions have a .so extension. Defaults to # ${VERSION}${SHLIB_SUFFIX}. # CFLAGS_DEBUG - # Flags used when running the compiler in debug mode # CFLAGS_OPTIMIZE - # Flags used when running the compiler in optimize mode # CFLAGS - Additional CFLAGS added as necessary (usually 64-bit) #-------------------------------------------------------------------- AC_DEFUN([TEA_CONFIG_CFLAGS], [ dnl TEA specific: Make sure we are initialized AC_REQUIRE([TEA_INIT]) # Step 0.a: Enable 64 bit support? AC_MSG_CHECKING([if 64bit support is requested]) AC_ARG_ENABLE(64bit, AC_HELP_STRING([--enable-64bit], [enable 64bit support (default: off)]), [do64bit=$enableval], [do64bit=no]) AC_MSG_RESULT([$do64bit]) # Step 0.b: Enable Solaris 64 bit VIS support? AC_MSG_CHECKING([if 64bit Sparc VIS support is requested]) AC_ARG_ENABLE(64bit-vis, AC_HELP_STRING([--enable-64bit-vis], [enable 64bit Sparc VIS support (default: off)]), [do64bitVIS=$enableval], [do64bitVIS=no]) AC_MSG_RESULT([$do64bitVIS]) # Force 64bit on with VIS AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes]) # Step 0.c: Check if visibility support is available. Do this here so # that platform specific alternatives can be used below if this fails. AC_CACHE_CHECK([if compiler supports visibility "hidden"], tcl_cv_cc_visibility_hidden, [ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror" AC_TRY_LINK([ extern __attribute__((__visibility__("hidden"))) void f(void); void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes, tcl_cv_cc_visibility_hidden=no) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [ AC_DEFINE(MODULE_SCOPE, [extern __attribute__((__visibility__("hidden")))], [Compiler support for module scope symbols]) ]) # Step 0.d: Disable -rpath support? AC_MSG_CHECKING([if rpath support is requested]) AC_ARG_ENABLE(rpath, AC_HELP_STRING([--disable-rpath], [disable rpath support (default: on)]), [doRpath=$enableval], [doRpath=yes]) AC_MSG_RESULT([$doRpath]) # TEA specific: Cross-compiling options for Windows/CE builds? AS_IF([test "${TEA_PLATFORM}" = windows], [ AC_MSG_CHECKING([if Windows/CE build is requested]) AC_ARG_ENABLE(wince, AC_HELP_STRING([--enable-wince], [enable Win/CE support (where applicable)]), [doWince=$enableval], [doWince=no]) AC_MSG_RESULT([$doWince]) ]) # Set the variable "system" to hold the name and version number # for the system. TEA_CONFIG_SYSTEM # Require ranlib early so we can override it in special cases below. AC_REQUIRE([AC_PROG_RANLIB]) # Set configuration options based on system name and version. # This is similar to Tcl's unix/tcl.m4 except that we've added a # "windows" case and removed some core-only vars. do64bit_ok=no # default to '{$LIBS}' and set to "" on per-platform necessary basis SHLIB_LD_LIBS='${LIBS}' # When ld needs options to work in 64-bit mode, put them in # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load] # is disabled by the user. [Bug 1016796] LDFLAGS_ARCH="" UNSHARED_LIB_SUFFIX="" # TEA specific: use PACKAGE_VERSION instead of VERSION TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`' ECHO_VERSION='`echo ${PACKAGE_VERSION}`' TCL_LIB_VERSIONS_OK=ok CFLAGS_DEBUG=-g AS_IF([test "$GCC" = yes], [ CFLAGS_OPTIMIZE=-O2 CFLAGS_WARNING="-Wno-write-strings -Wall -Wno-missing-braces -Wno-char-subscripts -Wno-long-long -pedantic" ], [ CFLAGS_OPTIMIZE=-O CFLAGS_WARNING="" ]) AC_CHECK_TOOL(AR, ar) STLIB_LD='${AR} cr' LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH" AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION="1.0"]) case $system in # TEA specific: windows) # This is a 2-stage check to make sure we have the 64-bit SDK # We have to know where the SDK is installed. # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs # MACHINE is IX86 for LINK, but this is used by the manifest, # which requires x86|amd64|ia64. MACHINE="X86" if test "$do64bit" != "no" ; then if test "x${MSSDK}x" = "xx" ; then MSSDK="C:/Progra~1/Microsoft Platform SDK" fi MSSDK=`echo "$MSSDK" | sed -e 's!\\\!/!g'` PATH64="" case "$do64bit" in amd64|x64|yes) MACHINE="AMD64" ; # default to AMD64 64-bit build PATH64="${MSSDK}/Bin/Win64/x86/AMD64" ;; ia64) MACHINE="IA64" PATH64="${MSSDK}/Bin/Win64" ;; esac if test "$GCC" != "yes" -a ! -d "${PATH64}" ; then AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode]) AC_MSG_WARN([Ensure latest Platform SDK is installed]) do64bit="no" else AC_MSG_RESULT([ Using 64-bit $MACHINE mode]) do64bit_ok="yes" fi fi if test "$doWince" != "no" ; then if test "$do64bit" != "no" ; then AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible]) fi if test "$GCC" = "yes" ; then AC_MSG_ERROR([Windows/CE and GCC builds incompatible]) fi TEA_PATH_CELIB # Set defaults for common evc4/PPC2003 setup # Currently Tcl requires 300+, possibly 420+ for sockets CEVERSION=420; # could be 211 300 301 400 420 ... TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ... ARCH=ARM; # could be ARM MIPS X86EM ... PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002" if test "$doWince" != "yes"; then # If !yes then the user specified something # Reset ARCH to allow user to skip specifying it ARCH= eval `echo $doWince | awk -F, '{ \ if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \ if ([$]1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \ if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \ if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \ if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \ }'` if test "x${ARCH}" = "x" ; then ARCH=$TARGETCPU; fi fi OSVERSION=WCE$CEVERSION; if test "x${WCEROOT}" = "x" ; then WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0" if test ! -d "${WCEROOT}" ; then WCEROOT="C:/Program Files/Microsoft eMbedded Tools" fi fi if test "x${SDKROOT}" = "x" ; then SDKROOT="C:/Program Files/Windows CE Tools" if test ! -d "${SDKROOT}" ; then SDKROOT="C:/Windows CE Tools" fi fi WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'` SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'` if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \ -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]]) doWince="no" else # We could PATH_NOSPACE these, but that's not important, # as long as we quote them when used. CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include" if test -d "${CEINCLUDE}/${TARGETCPU}" ; then CEINCLUDE="${CEINCLUDE}/${TARGETCPU}" fi CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" fi fi if test "$GCC" != "yes" ; then if test "${SHARED_BUILD}" = "0" ; then runtime=-MT else runtime=-MD fi if test "$do64bit" != "no" ; then # All this magic is necessary for the Win64 SDK RC1 - hobbs CC="\"${PATH64}/cl.exe\"" CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\"" RC="\"${MSSDK}/bin/rc.exe\"" lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\"" LINKBIN="\"${PATH64}/link.exe\"" CFLAGS_DEBUG="-nologo -Zi -Od -W2 ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" # Avoid 'unresolved external symbol __security_cookie' # errors, c.f. http://support.microsoft.com/?id=894573 TEA_ADD_LIBS([bufferoverflowU.lib]) elif test "$doWince" != "no" ; then CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin" if test "${TARGETCPU}" = "X86"; then CC="\"${CEBINROOT}/cl.exe\"" else CC="\"${CEBINROOT}/cl${ARCH}.exe\"" fi CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\"" RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\"" arch=`echo ${ARCH} | awk '{print tolower([$]0)}'` defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS" if test "${SHARED_BUILD}" = "1" ; then # Static CE builds require static celib as well defs="${defs} _DLL" fi for i in $defs ; do AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i) done AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version]) AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version]) CFLAGS_DEBUG="-nologo -Zi -Od" CFLAGS_OPTIMIZE="-nologo -Ox" lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'` lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo" LINKBIN="\"${CEBINROOT}/link.exe\"" AC_SUBST(CELIB_DIR) else RC="rc" lflags="-nologo" LINKBIN="link" CFLAGS_DEBUG="-nologo -Z7 -Od -W2 ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" fi fi if test "$GCC" = "yes"; then # mingw gcc mode AC_CHECK_TOOL(RC, windres) CFLAGS_DEBUG="-g" CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" SHLIB_LD='${CXX} -shared' UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}" LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}" AC_CACHE_CHECK(for cross-compile version of gcc, ac_cv_cross, AC_TRY_COMPILE([ #ifdef __WIN32__ #error cross-compiler #endif ], [], ac_cv_cross=yes, ac_cv_cross=no) ) if test "$ac_cv_cross" = "yes"; then case "$do64bit" in amd64|x64|yes) CC="x86_64-w64-mingw32-gcc" LD="x86_64-w64-mingw32-ld" AR="x86_64-w64-mingw32-ar" RANLIB="x86_64-w64-mingw32-ranlib" RC="x86_64-w64-mingw32-windres" ;; *) CC="i686-w64-mingw32-gcc" LD="i686-w64-mingw32-ld" AR="i686-w64-mingw32-ar" RANLIB="i686-w64-mingw32-ranlib" RC="i686-w64-mingw32-windres" ;; esac fi else SHLIB_LD="${LINKBIN} -dll ${lflags}" # link -lib only works when -lib is the first arg STLIB_LD="${LINKBIN} -lib ${lflags}" UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib' PATHTYPE=-w # For information on what debugtype is most useful, see: # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp # and also # http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx # This essentially turns it all on. LDFLAGS_DEBUG="-debug -debugtype:cv" LDFLAGS_OPTIMIZE="-release" if test "$doWince" != "no" ; then LDFLAGS_CONSOLE="-link ${lflags}" LDFLAGS_WINDOW=${LDFLAGS_CONSOLE} else LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}" LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}" fi fi SHLIB_SUFFIX=".dll" SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll' TCL_LIB_VERSIONS_OK=nodots ;; AIX-*) AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [ # AIX requires the _r compiler when gcc isn't being used case "${CC}" in *_r|*_r\ *) # ok ... ;; *) # Make sure only first arg gets _r CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'` ;; esac AC_MSG_RESULT([Using $CC for compiling with threads]) ]) LIBS="$LIBS -lc" SHLIB_CFLAGS="" SHLIB_SUFFIX=".so" LD_LIBRARY_PATH_VAR="LIBPATH" # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = yes], [ AS_IF([test "$GCC" = yes], [ AC_MSG_WARN([64bit mode not supported with GCC on $system]) ], [ do64bit_ok=yes CFLAGS="$CFLAGS -q64" LDFLAGS_ARCH="-q64" RANLIB="${RANLIB} -X64" AR="${AR} -X64" SHLIB_LD_FLAGS="-b64" ]) ]) AS_IF([test "`uname -m`" = ia64], [ # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC SHLIB_LD="/usr/ccs/bin/ld -G -z text" AS_IF([test "$GCC" = yes], [ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' ], [ CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}' ]) LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' ], [ AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CXX} -shared -Wl,-bexpall' ], [ SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry" LDFLAGS="$LDFLAGS -brtl" ]) SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}" CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ]) ;; BeOS*) SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CXX} -nostart' SHLIB_SUFFIX=".so" #----------------------------------------------------------- # Check for inet_ntoa in -lbind, for BeOS (which also needs # -lsocket, even if the network functions are in -lnet which # is always linked to, for compatibility. #----------------------------------------------------------- AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"]) ;; BSD/OS-4.*) SHLIB_CFLAGS="-export-dynamic -fPIC" SHLIB_LD='${CXX} -shared' SHLIB_SUFFIX=".so" LDFLAGS="$LDFLAGS -export-dynamic" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; CYGWIN_*) SHLIB_CFLAGS="" SHLIB_LD='${CXX} -shared' SHLIB_SUFFIX=".dll" EXEEXT=".exe" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; Haiku*) LDFLAGS="$LDFLAGS -Wl,--export-dynamic" SHLIB_CFLAGS="-fPIC" SHLIB_SUFFIX=".so" SHLIB_LD='${CXX} -shared ${CFLAGS} ${LDFLAGS}' AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"]) ;; HP-UX-*.11.*) # Use updated header definitions where possible AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?]) # TEA specific: Needed by Tcl, but not most extensions #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?]) #LIBS="$LIBS -lxnet" # Use the XOPEN network library AS_IF([test "`uname -m`" = ia64], [ SHLIB_SUFFIX=".so" # Use newer C++ library for C++ extensions #if test "$GCC" != "yes" ; then # CPPFLAGS="-AA" #fi ], [ SHLIB_SUFFIX=".sl" ]) AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no) AS_IF([test "$tcl_ok" = yes], [ LDFLAGS="$LDFLAGS -Wl,-E" CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' LD_LIBRARY_PATH_VAR="SHLIB_PATH" ]) AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CXX} -shared' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ], [ CFLAGS="$CFLAGS -z" # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc #CFLAGS="$CFLAGS +DAportable" SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" ]) # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = "yes"], [ AS_IF([test "$GCC" = yes], [ case `${CC} -dumpmachine` in hppa64*) # 64-bit gcc in use. Fix flags for GNU ld. do64bit_ok=yes SHLIB_LD='${CXX} -shared' AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ;; *) AC_MSG_WARN([64bit mode not supported with GCC on $system]) ;; esac ], [ do64bit_ok=yes CFLAGS="$CFLAGS +DD64" LDFLAGS_ARCH="+DD64" ]) ]) ;; IRIX-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_SUFFIX=".so" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) AS_IF([test "$GCC" = yes], [ CFLAGS="$CFLAGS -mabi=n32" LDFLAGS="$LDFLAGS -mabi=n32" ], [ case $system in IRIX-6.3) # Use to build 6.2 compatible binaries on 6.3. CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS" ;; *) CFLAGS="$CFLAGS -n32" ;; esac LDFLAGS="$LDFLAGS -n32" ]) ;; IRIX64-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_SUFFIX=".so" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = yes], [ AS_IF([test "$GCC" = yes], [ AC_MSG_WARN([64bit mode not supported by gcc]) ], [ do64bit_ok=yes SHLIB_LD="ld -64 -shared -rdata_shared" CFLAGS="$CFLAGS -64" LDFLAGS_ARCH="-64" ]) ]) ;; Linux*|GNU*|NetBSD-Debian) SHLIB_CFLAGS="-fPIC" SHLIB_SUFFIX=".so" # TEA specific: CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS SHLIB_LD='${CXX} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}' #LDFLAGS="$LDFLAGS -Wl,--export-dynamic" LDFLAGS="$LDFLAGS -Wl,-soname,libscintilla.so" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"]) AS_IF([test $do64bit = yes], [ AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [ hold_cflags=$CFLAGS CFLAGS="$CFLAGS -m64" AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_m64 = yes], [ CFLAGS="$CFLAGS -m64" do64bit_ok=yes ]) ],[CFLAGS="$CFLAGS -m32"]) # The combo of gcc + glibc has a bug related to inlining of # functions like strtod(). The -fno-builtin flag should address # this problem but it does not work. The -fno-inline flag is kind # of overkill but it works. Disable inlining only when one of the # files in compat/*.c is being linked in. AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"]) ;; Lynx*) SHLIB_CFLAGS="-fPIC" SHLIB_SUFFIX=".so" CFLAGS_OPTIMIZE=-02 SHLIB_LD='${CXX} -shared' LD_FLAGS="-Wl,--export-dynamic" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) ;; OpenBSD-*) arch=`arch -s` case "$arch" in m88k|vax) SHLIB_SUFFIX="" SHARED_LIB_SUFFIX="" ;; *) SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CXX} -shared ${SHLIB_CFLAGS}' SHLIB_SUFFIX=".so" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' ;; esac case "$arch" in m88k|vax) CFLAGS_OPTIMIZE="-O1" ;; *) CFLAGS_OPTIMIZE="-O2" ;; esac AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [ AC_EGREP_CPP(yes, [ #ifdef __ELF__ yes #endif ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)]) AS_IF([test $tcl_cv_ld_elf = yes], [ #LDFLAGS=-Wl,-export-dynamic LDFLAGS=-Wl,-soname,libscintilla.so ], [LDFLAGS=""]) AS_IF([test "${TCL_THREADS}" = "1"], [ # On OpenBSD: Compile with -pthread # Don't link with -lpthread LIBS=`echo $LIBS | sed s/-lpthread//` CFLAGS="$CFLAGS -pthread" ]) # OpenBSD doesn't do version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; NetBSD-*|FreeBSD-[[3-4]].*) # FreeBSD 3.* and greater have ELF. # NetBSD 2.* has ELF and can use 'cc -shared' to build shared libs SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CXX} -shared ${SHLIB_CFLAGS}' SHLIB_SUFFIX=".so" LDFLAGS="$LDFLAGS -export-dynamic" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} AS_IF([test "${TCL_THREADS}" = "1"], [ # The -pthread needs to go in the CFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" ]) case $system in FreeBSD-3.*) # FreeBSD-3 doesn't handle version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' TCL_LIB_VERSIONS_OK=nodots ;; esac ;; FreeBSD-*) # This configuration from FreeBSD Ports. SHLIB_CFLAGS="-fPIC" SHLIB_LD="${CXX} -shared" TCL_SHLIB_LD_EXTRAS="-soname \$[@]" SHLIB_SUFFIX=".so" LDFLAGS="" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) AS_IF([test "${TCL_THREADS}" = "1"], [ # The -pthread needs to go in the LDFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LDFLAGS="$LDFLAGS $PTHREAD_LIBS"]) # Version numbers are dot-stripped by system policy. TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .` UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1' TCL_LIB_VERSIONS_OK=nodots ;; Darwin-*) CFLAGS_OPTIMIZE="-Os" SHLIB_CFLAGS="-fno-common" # To avoid discrepancies between what headers configure sees during # preprocessing tests and compiling tests, move any -isysroot and # -mmacosx-version-min flags from CFLAGS to CPPFLAGS: CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`" CFLAGS="`echo " ${CFLAGS}" | \ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`" AS_IF([test $do64bit = yes], [ case `arch` in ppc) AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag], tcl_cv_cc_arch_ppc64, [ hold_cflags=$CFLAGS CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes, tcl_cv_cc_arch_ppc64=no) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" do64bit_ok=yes ]);; i386) AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag], tcl_cv_cc_arch_x86_64, [ hold_cflags=$CFLAGS CFLAGS="$CFLAGS -arch x86_64" AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes, tcl_cv_cc_arch_x86_64=no) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [ CFLAGS="$CFLAGS -arch x86_64" do64bit_ok=yes ]);; *) AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);; esac ], [ # Check for combined 32-bit and 64-bit fat build AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \ && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [ fat_32_64=yes]) ]) # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS SHLIB_LD='${CXX} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}' AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [ hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module" AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no) LDFLAGS=$hold_ldflags]) AS_IF([test $tcl_cv_ld_single_module = yes], [ SHLIB_LD="${SHLIB_LD} -Wl,-single_module" ]) # TEA specific: link shlib with current and compatibility version flags vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([[0-9]]\{1,5\}\)\(\(\.[[0-9]]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d` SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}" SHLIB_SUFFIX=".dylib" # Don't use -prebind when building for Mac OS X 10.4 or later only: AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \ "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [ LDFLAGS="$LDFLAGS -prebind"]) LDFLAGS="$LDFLAGS -headerpad_max_install_names" AC_CACHE_CHECK([if ld accepts -search_paths_first flag], tcl_cv_ld_search_paths_first, [ hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-search_paths_first" AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes, tcl_cv_ld_search_paths_first=no) LDFLAGS=$hold_ldflags]) AS_IF([test $tcl_cv_ld_search_paths_first = yes], [ LDFLAGS="$LDFLAGS -Wl,-search_paths_first" ]) AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [ AC_DEFINE(MODULE_SCOPE, [__private_extern__], [Compiler support for module scope symbols]) tcl_cv_cc_visibility_hidden=yes ]) CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH" # TEA specific: for combined 32 & 64 bit fat builds of Tk # extensions, verify that 64-bit build is possible. AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [ AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [ AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [ for v in CFLAGS CPPFLAGS LDFLAGS; do eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"' done CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include" LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11" AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();], tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no) for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="$hold_'$v'"' done]) ]) AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [ AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [ for v in CFLAGS CPPFLAGS LDFLAGS; do eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"' done CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}" LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}" AC_TRY_LINK([#include <tk.h>], [Tk_InitStubs(NULL, "", 0);], tcl_cv_lib_tk_64=yes, tcl_cv_lib_tk_64=no) for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="$hold_'$v'"' done]) ]) # remove 64-bit arch flags from CFLAGS et al. if configuration # does not support 64-bit. AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [ AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags]) for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"' done]) ]) ;; OS/390-*) CFLAGS_OPTIMIZE="" # Optimizer is buggy AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h [Should OS/390 do the right thing with sockets?]) ;; OSF1-V*) # Digital OSF/1 SHLIB_CFLAGS="" AS_IF([test "$SHARED_BUILD" = 1], [ SHLIB_LD='ld -shared -expect_unresolved "*"' ], [ SHLIB_LD='ld -non_shared -expect_unresolved "*"' ]) SHLIB_SUFFIX=".so" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [ CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"]) # see pthread_intro(3) for pthread support on osf1, k.furukawa AS_IF([test "${TCL_THREADS}" = 1], [ CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE" CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64" LIBS=`echo $LIBS | sed s/-lpthreads//` AS_IF([test "$GCC" = yes], [ LIBS="$LIBS -lpthread -lmach -lexc" ], [ CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" ]) ]) ;; QNX-6*) # QNX RTP # This may work for all QNX, but it was only reported for v6. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; SCO_SV-3.2*) AS_IF([test "$GCC" = yes], [ SHLIB_CFLAGS="-fPIC -melf" LDFLAGS="$LDFLAGS -melf -Wl,-Bexport" ], [ SHLIB_CFLAGS="-Kpic -belf" LDFLAGS="$LDFLAGS -belf -Wl,-Bexport" ]) SHLIB_LD="ld -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; SunOS-5.[[0-6]]) # Careful to not let 5.10+ fall into this case # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) SHLIB_CFLAGS="-KPIC" SHLIB_SUFFIX=".so" AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CXX} -shared' CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ], [ SHLIB_LD="/usr/ccs/bin/ld -G -z text" CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ]) ;; SunOS-5*) # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) SHLIB_CFLAGS="-KPIC" # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = yes], [ arch=`isainfo` AS_IF([test "$arch" = "sparcv9 sparc"], [ AS_IF([test "$GCC" = yes], [ AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [ AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system]) ], [ do64bit_ok=yes CFLAGS="$CFLAGS -m64 -mcpu=v9" LDFLAGS="$LDFLAGS -m64 -mcpu=v9" SHLIB_CFLAGS="-fPIC" ]) ], [ do64bit_ok=yes AS_IF([test "$do64bitVIS" = yes], [ CFLAGS="$CFLAGS -xarch=v9a" LDFLAGS_ARCH="-xarch=v9a" ], [ CFLAGS="$CFLAGS -xarch=v9" LDFLAGS_ARCH="-xarch=v9" ]) # Solaris 64 uses this as well #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64" ]) ], [AS_IF([test "$arch" = "amd64 i386"], [ AS_IF([test "$GCC" = yes], [ case $system in SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*) do64bit_ok=yes CFLAGS="$CFLAGS -m64" LDFLAGS="$LDFLAGS -m64";; *) AC_MSG_WARN([64bit mode not supported with GCC on $system]);; esac ], [ do64bit_ok=yes case $system in SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*) CFLAGS="$CFLAGS -m64" LDFLAGS="$LDFLAGS -m64";; *) CFLAGS="$CFLAGS -xarch=amd64" LDFLAGS="$LDFLAGS -xarch=amd64";; esac ]) ], [AC_MSG_WARN([64bit mode not supported for $arch])])]) ]) SHLIB_SUFFIX=".so" AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CXX} -shared' CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} AS_IF([test "$do64bit_ok" = yes], [ AS_IF([test "$arch" = "sparcv9 sparc"], [ # We need to specify -static-libgcc or we need to # add the path to the sparv9 libgcc. # JH: static-libgcc is necessary for core Tcl, but may # not be necessary for extensions. SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc" # for finding sparcv9 libgcc, get the regular libgcc # path, remove so name and append 'sparcv9' #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..." #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir" ], [AS_IF([test "$arch" = "amd64 i386"], [ # JH: static-libgcc is necessary for core Tcl, but may # not be necessary for extensions. SHLIB_LD="$SHLIB_LD -m64 -static-libgcc" ])]) ]) ], [ case $system in SunOS-5.[[1-9]][[0-9]]*) # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS SHLIB_LD='${CXX} -G -z text ${LDFLAGS_DEFAULT}';; *) SHLIB_LD='/usr/ccs/bin/ld -G -z text';; esac CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' ]) ;; UNIX_SV* | UnixWare-5*) SHLIB_CFLAGS="-KPIC" SHLIB_LD='${CXX} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers # that don't grok the -Bexport option. Test that it does. AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [ hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-Bexport" AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no) LDFLAGS=$hold_ldflags]) AS_IF([test $tcl_cv_ld_Bexport = yes], [ LDFLAGS="$LDFLAGS -Wl,-Bexport" ]) CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; esac AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [ AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform]) ]) dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so dnl # until the end of configure, as configure's compile and link tests use dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's dnl # preprocessing tests use only CPPFLAGS. AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""]) # Add in the arch flags late to ensure it wasn't removed. # Not necessary in TEA, but this is aligned with core LDFLAGS="$LDFLAGS $LDFLAGS_ARCH" # If we're running gcc, then change the C flags for compiling shared # libraries to the right flags for gcc, instead of those for the # standard manufacturer compiler. AS_IF([test "$GCC" = yes], [ case $system in AIX-*) ;; BSD/OS*) ;; CYGWIN_*) ;; IRIX*) ;; NetBSD-*|FreeBSD-*|OpenBSD-*) ;; Darwin-*) ;; SCO_SV-3.2*) ;; windows) ;; *) SHLIB_CFLAGS="-fPIC" ;; esac]) AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [ AC_DEFINE(MODULE_SCOPE, [extern], [No Compiler support for module scope symbols]) AC_DEFINE(NO_VIZ, [], [No visibility hidden passed to zlib?]) ]) AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [ # TEA specific: use PACKAGE_VERSION instead of VERSION SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}']) AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [ # TEA specific: use PACKAGE_VERSION instead of VERSION UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a']) if test "${GCC}" = "yes" ; then AC_CACHE_CHECK(for SEH support in compiler, tcl_cv_seh, AC_TRY_RUN([ #define WIN32_LEAN_AND_MEAN #include <windows.h> #undef WIN32_LEAN_AND_MEAN int main(int argc, char** argv) { int a, b = 0; __try { a = 666 / b; } __except (EXCEPTION_EXECUTE_HANDLER) { return 0; } return 1; } ], tcl_cv_seh=yes, tcl_cv_seh=no, tcl_cv_seh=no) ) if test "$tcl_cv_seh" = "no" ; then AC_DEFINE(HAVE_NO_SEH, 1, [Defined when mingw does not support SEH]) fi # # Check to see if the excpt.h include file provided contains the # definition for EXCEPTION_DISPOSITION; if not, which is the case # with Cygwin's version as of 2002-04-10, define it to be int, # sufficient for getting the current code to work. # AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files, tcl_cv_eh_disposition, AC_TRY_COMPILE([ # define WIN32_LEAN_AND_MEAN # include <windows.h> # undef WIN32_LEAN_AND_MEAN ],[ EXCEPTION_DISPOSITION x; ], tcl_cv_eh_disposition=yes, tcl_cv_eh_disposition=no) ) if test "$tcl_cv_eh_disposition" = "no" ; then AC_DEFINE(EXCEPTION_DISPOSITION, int, [Defined when cygwin/mingw does not support EXCEPTION DISPOSITION]) fi # Check to see if winnt.h defines CHAR, SHORT, and LONG # even if VOID has already been #defined. The win32api # used by mingw and cygwin is known to do this. AC_CACHE_CHECK(for winnt.h that ignores VOID define, tcl_cv_winnt_ignore_void, AC_TRY_COMPILE([ #define VOID void #define WIN32_LEAN_AND_MEAN #include <windows.h> #undef WIN32_LEAN_AND_MEAN ], [ CHAR c; SHORT s; LONG l; ], tcl_cv_winnt_ignore_void=yes, tcl_cv_winnt_ignore_void=no) ) if test "$tcl_cv_winnt_ignore_void" = "yes" ; then AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1, [Defined when cygwin/mingw ignores VOID define in winnt.h]) fi # See if the compiler supports casting to a union type. # This is used to stop gcc from printing a compiler # warning when initializing a union member. AC_CACHE_CHECK(for cast to union support, tcl_cv_cast_to_union, AC_TRY_COMPILE([], [ union foo { int i; double d; }; union foo f = (union foo) (int) 0; ], tcl_cv_cast_to_union=yes, tcl_cv_cast_to_union=no) ) if test "$tcl_cv_cast_to_union" = "yes"; then AC_DEFINE(HAVE_CAST_TO_UNION, 1, [Defined when compiler supports casting to union type.]) fi fi AC_SUBST(CFLAGS_DEBUG) AC_SUBST(CFLAGS_OPTIMIZE) AC_SUBST(CFLAGS_WARNING) AC_SUBST(STLIB_LD) AC_SUBST(SHLIB_LD) AC_SUBST(SHLIB_LD_LIBS) AC_SUBST(SHLIB_CFLAGS) AC_SUBST(SHLIB_SUFFIX) AC_SUBST(LD_LIBRARY_PATH_VAR) # These must be called after we do the basic CFLAGS checks and # verify any possible 64-bit or similar switches are necessary TEA_TCL_EARLY_FLAGS TEA_TCL_64BIT_FLAGS ]) #-------------------------------------------------------------------- # TEA_SERIAL_PORT # # Determine which interface to use to talk to the serial port. # Note that #include lines must begin in leftmost column for # some compilers to recognize them as preprocessor directives, # and some build environments have stdin not pointing at a # pseudo-terminal (usually /dev/null instead.) # # Arguments: # none # # Results: # # Defines only one of the following vars: # HAVE_SYS_MODEM_H # USE_TERMIOS # USE_TERMIO # USE_SGTTY #-------------------------------------------------------------------- AC_DEFUN([TEA_SERIAL_PORT], [ AC_CHECK_HEADERS(sys/modem.h) AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [ AC_TRY_RUN([ #include <termios.h> int main() { struct termios t; if (tcgetattr(0, &t) == 0) { cfsetospeed(&t, 0); t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no) if test $tcl_cv_api_serial = no ; then AC_TRY_RUN([ #include <termio.h> int main() { struct termio t; if (ioctl(0, TCGETA, &t) == 0) { t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no) fi if test $tcl_cv_api_serial = no ; then AC_TRY_RUN([ #include <sgtty.h> int main() { struct sgttyb t; if (ioctl(0, TIOCGETP, &t) == 0) { t.sg_ospeed = 0; t.sg_flags |= ODDP | EVENP | RAW; return 0; } return 1; }], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no) fi if test $tcl_cv_api_serial = no ; then AC_TRY_RUN([ #include <termios.h> #include <errno.h> int main() { struct termios t; if (tcgetattr(0, &t) == 0 || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { cfsetospeed(&t, 0); t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no) fi if test $tcl_cv_api_serial = no; then AC_TRY_RUN([ #include <termio.h> #include <errno.h> int main() { struct termio t; if (ioctl(0, TCGETA, &t) == 0 || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no) fi if test $tcl_cv_api_serial = no; then AC_TRY_RUN([ #include <sgtty.h> #include <errno.h> int main() { struct sgttyb t; if (ioctl(0, TIOCGETP, &t) == 0 || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { t.sg_ospeed = 0; t.sg_flags |= ODDP | EVENP | RAW; return 0; } return 1; }], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none) fi]) case $tcl_cv_api_serial in termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);; termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);; sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);; esac ]) #-------------------------------------------------------------------- # TEA_MISSING_POSIX_HEADERS # # Supply substitutes for missing POSIX header files. Special # notes: # - stdlib.h doesn't define strtol, strtoul, or # strtod in some versions of SunOS # - some versions of string.h don't declare procedures such # as strstr # # Arguments: # none # # Results: # # Defines some of the following vars: # NO_DIRENT_H # NO_ERRNO_H # NO_VALUES_H # HAVE_LIMITS_H or NO_LIMITS_H # NO_STDLIB_H # NO_STRING_H # NO_SYS_WAIT_H # NO_DLFCN_H # HAVE_SYS_PARAM_H # # HAVE_STRING_H ? # # tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and # CHECK on limits.h #-------------------------------------------------------------------- AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [ AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [ AC_TRY_LINK([#include <sys/types.h> #include <dirent.h>], [ #ifndef _POSIX_SOURCE # ifdef __Lynx__ /* * Generate compilation error to make the test fail: Lynx headers * are only valid if really in the POSIX environment. */ missing_procedure(); # endif #endif DIR *d; struct dirent *entryPtr; char *p; d = opendir("foobar"); entryPtr = readdir(d); p = entryPtr->d_name; closedir(d); ], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)]) if test $tcl_cv_dirent_h = no; then AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?]) fi # TEA specific: AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])]) AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have <float.h>?])]) AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])]) AC_CHECK_HEADER(limits.h, [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])], [AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])]) AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0) AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0) AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0) AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0) if test $tcl_ok = 0; then AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?]) fi AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0) AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0) AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0) # See also memmove check below for a place where NO_STRING_H can be # set and why. if test $tcl_ok = 0; then AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?]) fi AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])]) AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])]) # OS/390 lacks sys/param.h (and doesn't need it, by chance). AC_HAVE_HEADERS(sys/param.h) ]) #-------------------------------------------------------------------- # TEA_PATH_X # # Locate the X11 header files and the X11 library archive. Try # the ac_path_x macro first, but if it doesn't find the X stuff # (e.g. because there's no xmkmf program) then check through # a list of possible directories. Under some conditions the # autoconf macro will return an include directory that contains # no include files, so double-check its result just to be safe. # # This should be called after TEA_CONFIG_CFLAGS as setting the # LIBS line can confuse some configure macro magic. # # Arguments: # none # # Results: # # Sets the following vars: # XINCLUDES # XLIBSW # PKG_LIBS (appends to) #-------------------------------------------------------------------- AC_DEFUN([TEA_PATH_X], [ if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then TEA_PATH_UNIX_X fi ]) AC_DEFUN([TEA_PATH_UNIX_X], [ AC_PATH_X not_really_there="" if test "$no_x" = ""; then if test "$x_includes" = ""; then AC_TRY_CPP([#include <X11/XIntrinsic.h>], , not_really_there="yes") else if test ! -r $x_includes/X11/Intrinsic.h; then not_really_there="yes" fi fi fi if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then AC_MSG_CHECKING([for X11 header files]) found_xincludes="no" AC_TRY_CPP([#include <X11/Intrinsic.h>], found_xincludes="yes", found_xincludes="no") if test "$found_xincludes" = "no"; then dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include" for i in $dirs ; do if test -r $i/X11/Intrinsic.h; then AC_MSG_RESULT([$i]) XINCLUDES=" -I$i" found_xincludes="yes" break fi done fi else if test "$x_includes" != ""; then XINCLUDES="-I$x_includes" found_xincludes="yes" fi fi if test "$found_xincludes" = "no"; then AC_MSG_RESULT([couldn't find any!]) fi if test "$no_x" = yes; then AC_MSG_CHECKING([for X11 libraries]) XLIBSW=nope dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib" for i in $dirs ; do if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then AC_MSG_RESULT([$i]) XLIBSW="-L$i -lX11" x_libraries="$i" break fi done else if test "$x_libraries" = ""; then XLIBSW=-lX11 else XLIBSW="-L$x_libraries -lX11" fi fi if test "$XLIBSW" = nope ; then AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow) fi if test "$XLIBSW" = nope ; then AC_MSG_RESULT([could not find any! Using -lX11.]) XLIBSW=-lX11 fi # TEA specific: if test x"${XLIBSW}" != x ; then PKG_LIBS="${PKG_LIBS} ${XLIBSW}" fi ]) #-------------------------------------------------------------------- # TEA_BLOCKING_STYLE # # The statements below check for systems where POSIX-style # non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented. # On these systems (mostly older ones), use the old BSD-style # FIONBIO approach instead. # # Arguments: # none # # Results: # # Defines some of the following vars: # HAVE_SYS_IOCTL_H # HAVE_SYS_FILIO_H # USE_FIONBIO # O_NONBLOCK #-------------------------------------------------------------------- AC_DEFUN([TEA_BLOCKING_STYLE], [ AC_CHECK_HEADERS(sys/ioctl.h) AC_CHECK_HEADERS(sys/filio.h) TEA_CONFIG_SYSTEM AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O]) case $system in OSF*) AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?]) AC_MSG_RESULT([FIONBIO]) ;; *) AC_MSG_RESULT([O_NONBLOCK]) ;; esac ]) #-------------------------------------------------------------------- # TEA_TIME_HANDLER # # Checks how the system deals with time.h, what time structures # are used on the system, and what fields the structures have. # # Arguments: # none # # Results: # # Defines some of the following vars: # USE_DELTA_FOR_TZ # HAVE_TM_GMTOFF # HAVE_TM_TZADJ # HAVE_TIMEZONE_VAR #-------------------------------------------------------------------- AC_DEFUN([TEA_TIME_HANDLER], [ AC_CHECK_HEADERS(sys/time.h) AC_HEADER_TIME AC_STRUCT_TIMEZONE AC_CHECK_FUNCS(gmtime_r localtime_r) AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [ AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_tzadj;], tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)]) if test $tcl_cv_member_tm_tzadj = yes ; then AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?]) fi AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [ AC_TRY_COMPILE([#include <time.h>], [struct tm tm; tm.tm_gmtoff;], tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)]) if test $tcl_cv_member_tm_gmtoff = yes ; then AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?]) fi # # Its important to include time.h in this check, as some systems # (like convex) have timezone functions, etc. # AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [ AC_TRY_COMPILE([#include <time.h>], [extern long timezone; timezone += 1; exit (0);], tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)]) if test $tcl_cv_timezone_long = yes ; then AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?]) else # # On some systems (eg IRIX 6.2), timezone is a time_t and not a long. # AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [ AC_TRY_COMPILE([#include <time.h>], [extern time_t timezone; timezone += 1; exit (0);], tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)]) if test $tcl_cv_timezone_time = yes ; then AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?]) fi fi ]) #-------------------------------------------------------------------- # TEA_BUGGY_STRTOD # # Under Solaris 2.4, strtod returns the wrong value for the # terminating character under some conditions. Check for this # and if the problem exists use a substitute procedure # "fixstrtod" (provided by Tcl) that corrects the error. # Also, on Compaq's Tru64 Unix 5.0, # strtod(" ") returns 0.0 instead of a failure to convert. # # Arguments: # none # # Results: # # Might defines some of the following vars: # strtod (=fixstrtod) #-------------------------------------------------------------------- AC_DEFUN([TEA_BUGGY_STRTOD], [ AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0) if test "$tcl_strtod" = 1; then AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[ AC_TRY_RUN([ extern double strtod(); int main() { char *infString="Inf", *nanString="NaN", *spaceString=" "; char *term; double value; value = strtod(infString, &term); if ((term != infString) && (term[-1] == 0)) { exit(1); } value = strtod(nanString, &term); if ((term != nanString) && (term[-1] == 0)) { exit(1); } value = strtod(spaceString, &term); if (term == (spaceString+1)) { exit(1); } exit(0); }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy, tcl_cv_strtod_buggy=buggy)]) if test "$tcl_cv_strtod_buggy" = buggy; then AC_LIBOBJ([fixstrtod]) USE_COMPAT=1 AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?]) fi fi ]) #-------------------------------------------------------------------- # TEA_TCL_LINK_LIBS # # Search for the libraries needed to link the Tcl shell. # Things like the math library (-lm) and socket stuff (-lsocket vs. # -lnsl) are dealt with here. # # Arguments: # Requires the following vars to be set in the Makefile: # DL_LIBS (not in TEA, only needed in core) # LIBS # MATH_LIBS # # Results: # # Substitutes the following vars: # TCL_LIBS # MATH_LIBS # # Might append to the following vars: # LIBS # # Might define the following vars: # HAVE_NET_ERRNO_H #-------------------------------------------------------------------- AC_DEFUN([TEA_TCL_LINK_LIBS], [ #-------------------------------------------------------------------- # On a few very rare systems, all of the libm.a stuff is # already in libc.a. Set compiler flags accordingly. # Also, Linux requires the "ieee" library for math to work # right (and it must appear before "-lm"). #-------------------------------------------------------------------- AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm") AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"]) #-------------------------------------------------------------------- # Interactive UNIX requires -linet instead of -lsocket, plus it # needs net/errno.h to define the socket-related error codes. #-------------------------------------------------------------------- AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"]) AC_CHECK_HEADER(net/errno.h, [ AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])]) #-------------------------------------------------------------------- # Check for the existence of the -lsocket and -lnsl libraries. # The order here is important, so that they end up in the right # order in the command line generated by make. Here are some # special considerations: # 1. Use "connect" and "accept" to check for -lsocket, and # "gethostbyname" to check for -lnsl. # 2. Use each function name only once: can't redo a check because # autoconf caches the results of the last check and won't redo it. # 3. Use -lnsl and -lsocket only if they supply procedures that # aren't already present in the normal libraries. This is because # IRIX 5.2 has libraries, but they aren't needed and they're # bogus: they goof up name resolution if used. # 4. On some SVR4 systems, can't use -lsocket without -lnsl too. # To get around this problem, check for both libraries together # if -lsocket doesn't work by itself. #-------------------------------------------------------------------- tcl_checkBoth=0 AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1) if test "$tcl_checkSocket" = 1; then AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt, LIBS="$LIBS -lsocket", tcl_checkBoth=1)]) fi if test "$tcl_checkBoth" = 1; then tk_oldLibs=$LIBS LIBS="$LIBS -lsocket -lnsl" AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs]) fi AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname, [LIBS="$LIBS -lnsl"])]) # TEA specific: Don't perform the eval of the libraries here because # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}' AC_SUBST(TCL_LIBS) AC_SUBST(MATH_LIBS) ]) #-------------------------------------------------------------------- # TEA_TCL_EARLY_FLAGS # # Check for what flags are needed to be passed so the correct OS # features are available. # # Arguments: # None # # Results: # # Might define the following vars: # _ISOC99_SOURCE # _LARGEFILE64_SOURCE # _LARGEFILE_SOURCE64 #-------------------------------------------------------------------- AC_DEFUN([TEA_TCL_EARLY_FLAG],[ AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]), AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no, AC_TRY_COMPILE([[#define ]$1[ 1 ]$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no))) if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then AC_DEFINE($1, 1, [Add the ]$1[ flag when building]) tcl_flags="$tcl_flags $1" fi ]) AC_DEFUN([TEA_TCL_EARLY_FLAGS],[ AC_MSG_CHECKING([for required early compiler flags]) tcl_flags="" TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>], [char *p = (char *)strtoll; char *q = (char *)strtoull;]) TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>], [struct stat64 buf; int i = stat64("/", &buf);]) TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>], [char *p = (char *)open64;]) if test "x${tcl_flags}" = "x" ; then AC_MSG_RESULT([none]) else AC_MSG_RESULT([${tcl_flags}]) fi ]) #-------------------------------------------------------------------- # TEA_TCL_64BIT_FLAGS # # Check for what is defined in the way of 64-bit features. # # Arguments: # None # # Results: # # Might define the following vars: # TCL_WIDE_INT_IS_LONG # TCL_WIDE_INT_TYPE # HAVE_STRUCT_DIRENT64 # HAVE_STRUCT_STAT64 # HAVE_TYPE_OFF64_T #-------------------------------------------------------------------- AC_DEFUN([TEA_TCL_64BIT_FLAGS], [ AC_MSG_CHECKING([for 64-bit integer type]) AC_CACHE_VAL(tcl_cv_type_64bit,[ tcl_cv_type_64bit=none # See if the compiler knows natively about __int64 AC_TRY_COMPILE(,[__int64 value = (__int64) 0;], tcl_type_64bit=__int64, tcl_type_64bit="long long") # See if we should use long anyway Note that we substitute in the # type that is our current guess for a 64-bit type inside this check # program, so it should be modified only carefully... AC_TRY_COMPILE(,[switch (0) { case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ; }],tcl_cv_type_64bit=${tcl_type_64bit})]) if test "${tcl_cv_type_64bit}" = none ; then AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?]) AC_MSG_RESULT([using long]) elif test "${tcl_cv_type_64bit}" = "__int64" \ -a "${TEA_PLATFORM}" = "windows" ; then # TEA specific: We actually want to use the default tcl.h checks in # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER* AC_MSG_RESULT([using Tcl header defaults]) else AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit}, [What type should be used to define wide integers?]) AC_MSG_RESULT([${tcl_cv_type_64bit}]) # Now check for auxiliary declarations AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[ AC_TRY_COMPILE([#include <sys/types.h> #include <sys/dirent.h>],[struct dirent64 p;], tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)]) if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?]) fi AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[ AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p; ], tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)]) if test "x${tcl_cv_struct_stat64}" = "xyes" ; then AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?]) fi AC_CHECK_FUNCS(open64 lseek64) AC_MSG_CHECKING([for off64_t]) AC_CACHE_VAL(tcl_cv_type_off64_t,[ AC_TRY_COMPILE([#include <sys/types.h>],[off64_t offset; ], tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)]) dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the dnl functions lseek64 and open64 are defined. if test "x${tcl_cv_type_off64_t}" = "xyes" && \ test "x${ac_cv_func_lseek64}" = "xyes" && \ test "x${ac_cv_func_open64}" = "xyes" ; then AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?]) AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi fi ]) ## ## Here ends the standard Tcl configuration bits and starts the ## TEA specific functions ## #------------------------------------------------------------------------ # TEA_INIT -- # # Init various Tcl Extension Architecture (TEA) variables. # This should be the first called TEA_* macro. # # Arguments: # none # # Results: # # Defines and substs the following vars: # CYGPATH # EXEEXT # Defines only: # TEA_VERSION # TEA_INITED # TEA_PLATFORM (windows or unix) # # "cygpath" is used on windows to generate native path names for include # files. These variables should only be used with the compiler and linker # since they generate native path names. # # EXEEXT # Select the executable extension based on the host type. This # is a lightweight replacement for AC_EXEEXT that doesn't require # a compiler. #------------------------------------------------------------------------ AC_DEFUN([TEA_INIT], [ # TEA extensions pass this us the version of TEA they think they # are compatible with. TEA_VERSION="3.9" AC_MSG_CHECKING([for correct TEA configuration]) if test x"${PACKAGE_NAME}" = x ; then AC_MSG_ERROR([ The PACKAGE_NAME variable must be defined by your TEA configure.in]) fi if test x"$1" = x ; then AC_MSG_ERROR([ TEA version not specified.]) elif test "$1" != "${TEA_VERSION}" ; then AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"]) else AC_MSG_RESULT([ok (TEA ${TEA_VERSION})]) fi # If the user did not set CFLAGS, set it now to keep macros # like AC_PROG_CC and AC_TRY_COMPILE from adding "-g -O2". if test "${CFLAGS+set}" != "set" ; then CFLAGS="" fi case "`uname -s`" in *win32*|*WIN32*|*MINGW32_*) AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo) EXEEXT=".exe" TEA_PLATFORM="windows" ;; *CYGWIN_*) AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo) EXEEXT=".exe" # TEA_PLATFORM is determined later in LOAD_TCLCONFIG ;; *) CYGPATH=echo # Maybe we are cross-compiling.... case ${host_alias} in *mingw32*) EXEEXT=".exe" TEA_PLATFORM="windows" ;; *) EXEEXT="" TEA_PLATFORM="unix" ;; esac ;; esac # Check if exec_prefix is set. If not use fall back to prefix. # Note when adjusted, so that TEA_PREFIX can correct for this. # This is needed for recursive configures, since autoconf propagates # $prefix, but not $exec_prefix (doh!). if test x$exec_prefix = xNONE ; then exec_prefix_default=yes exec_prefix=$prefix fi AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}]) AC_SUBST(EXEEXT) AC_SUBST(CYGPATH) # This package name must be replaced statically for AC_SUBST to work AC_SUBST(PKG_LIB_FILE) # Substitute STUB_LIB_FILE in case package creates a stub library too. AC_SUBST(PKG_STUB_LIB_FILE) # We AC_SUBST these here to ensure they are subst'ed, # in case the user doesn't call TEA_ADD_... AC_SUBST(PKG_STUB_SOURCES) AC_SUBST(PKG_STUB_OBJECTS) AC_SUBST(PKG_TCL_SOURCES) AC_SUBST(PKG_HEADERS) AC_SUBST(PKG_INCLUDES) AC_SUBST(PKG_LIBS) AC_SUBST(PKG_CFLAGS) ]) #------------------------------------------------------------------------ # TEA_ADD_SOURCES -- # # Specify one or more source files. Users should check for # the right platform before adding to their list. # It is not important to specify the directory, as long as it is # in the generic, win or unix subdirectory of $(srcdir). # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_SOURCES # PKG_OBJECTS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_SOURCES], [ vars="$@" for i in $vars; do case $i in [\$]*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ -a ! -f "${srcdir}/macosx/$i" \ ; then AC_MSG_ERROR([could not find source file '$i']) fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done AC_SUBST(PKG_SOURCES) AC_SUBST(PKG_OBJECTS) ]) #------------------------------------------------------------------------ # TEA_ADD_STUB_SOURCES -- # # Specify one or more source files. Users should check for # the right platform before adding to their list. # It is not important to specify the directory, as long as it is # in the generic, win or unix subdirectory of $(srcdir). # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_STUB_SOURCES # PKG_STUB_OBJECTS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_STUB_SOURCES], [ vars="$@" for i in $vars; do # check for existence - allows for generic/win/unix VPATH if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ -a ! -f "${srcdir}/macosx/$i" \ ; then AC_MSG_ERROR([could not find stub source file '$i']) fi PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}" fi PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j" done AC_SUBST(PKG_STUB_SOURCES) AC_SUBST(PKG_STUB_OBJECTS) ]) #------------------------------------------------------------------------ # TEA_ADD_TCL_SOURCES -- # # Specify one or more Tcl source files. These should be platform # independent runtime files. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_TCL_SOURCES #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_TCL_SOURCES], [ vars="$@" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i']) fi PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i" done AC_SUBST(PKG_TCL_SOURCES) ]) #------------------------------------------------------------------------ # TEA_ADD_HEADERS -- # # Specify one or more source headers. Users should check for # the right platform before adding to their list. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_HEADERS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_HEADERS], [ vars="$@" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then AC_MSG_ERROR([could not find header file '${srcdir}/$i']) fi PKG_HEADERS="$PKG_HEADERS $i" done AC_SUBST(PKG_HEADERS) ]) #------------------------------------------------------------------------ # TEA_ADD_INCLUDES -- # # Specify one or more include dirs. Users should check for # the right platform before adding to their list. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_INCLUDES], [ vars="$@" for i in $vars; do PKG_INCLUDES="$PKG_INCLUDES $i" done AC_SUBST(PKG_INCLUDES) ]) #------------------------------------------------------------------------ # TEA_ADD_LIBS -- # # Specify one or more libraries. Users should check for # the right platform before adding to their list. For Windows, # libraries provided in "foo.lib" format will be converted to # "-lfoo" when using GCC (mingw). # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_LIBS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_LIBS], [ vars="$@" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'` fi PKG_LIBS="$PKG_LIBS $i" done AC_SUBST(PKG_LIBS) ]) #------------------------------------------------------------------------ # TEA_ADD_CFLAGS -- # # Specify one or more CFLAGS. Users should check for # the right platform before adding to their list. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_CFLAGS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_CFLAGS], [ PKG_CFLAGS="$PKG_CFLAGS $@" AC_SUBST(PKG_CFLAGS) ]) #------------------------------------------------------------------------ # TEA_ADD_CLEANFILES -- # # Specify one or more CLEANFILES. # # Arguments: # one or more file names to clean target # # Results: # # Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_CLEANFILES], [ CLEANFILES="$CLEANFILES $@" ]) #------------------------------------------------------------------------ # TEA_PREFIX -- # # Handle the --prefix=... option by defaulting to what Tcl gave # # Arguments: # none # # Results: # # If --prefix or --exec-prefix was not specified, $prefix and # $exec_prefix will be set to the values given to Tcl when it was # configured. #------------------------------------------------------------------------ AC_DEFUN([TEA_PREFIX], [ if test "${prefix}" = "NONE"; then prefix_default=yes if test x"${TCL_PREFIX}" != x; then AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}]) prefix=${TCL_PREFIX} else AC_MSG_NOTICE([--prefix defaulting to /usr/local]) prefix=/usr/local fi fi if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \ -o x"${exec_prefix_default}" = x"yes" ; then if test x"${TCL_EXEC_PREFIX}" != x; then AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}]) exec_prefix=${TCL_EXEC_PREFIX} else AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}]) exec_prefix=$prefix fi fi ]) #------------------------------------------------------------------------ # TEA_SETUP_COMPILER_CC -- # # Do compiler checks the way we want. This is just a replacement # for AC_PROG_CC in TEA configure.in files to make them cleaner. # # Arguments: # none # # Results: # # Sets up CC var and other standard bits we need to make executables. #------------------------------------------------------------------------ AC_DEFUN([TEA_SETUP_COMPILER_CC], [ # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE) # in this macro, they need to go into TEA_SETUP_COMPILER instead. AC_PROG_CC AC_PROG_CPP #-------------------------------------------------------------------- # Checks to see if the make program sets the $MAKE variable. #-------------------------------------------------------------------- AC_PROG_MAKE_SET #-------------------------------------------------------------------- # Find ranlib #-------------------------------------------------------------------- AC_CHECK_TOOL(RANLIB, ranlib) #-------------------------------------------------------------------- # Determines the correct binary file extension (.o, .obj, .exe etc.) #-------------------------------------------------------------------- AC_OBJEXT AC_EXEEXT ]) #------------------------------------------------------------------------ # TEA_SETUP_COMPILER -- # # Do compiler checks that use the compiler. This must go after # TEA_SETUP_COMPILER_CC, which does the actual compiler check. # # Arguments: # none # # Results: # # Sets up CC var and other standard bits we need to make executables. #------------------------------------------------------------------------ AC_DEFUN([TEA_SETUP_COMPILER], [ # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here. AC_REQUIRE([TEA_SETUP_COMPILER_CC]) #------------------------------------------------------------------------ # If we're using GCC, see if the compiler understands -pipe. If so, use it. # It makes compiling go faster. (This is only a performance feature.) #------------------------------------------------------------------------ if test -z "$no_pipe" -a -n "$GCC"; then AC_CACHE_CHECK([if the compiler understands -pipe], tcl_cv_cc_pipe, [ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe" AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no) CFLAGS=$hold_cflags]) if test $tcl_cv_cc_pipe = yes; then CFLAGS="$CFLAGS -pipe" fi fi #-------------------------------------------------------------------- # Common compiler flag setup #-------------------------------------------------------------------- AC_C_BIGENDIAN if test "${TEA_PLATFORM}" = "unix" ; then TEA_TCL_LINK_LIBS TEA_MISSING_POSIX_HEADERS # Let the user call this, because if it triggers, they will # need a compat/strtod.c that is correct. Users can also # use Tcl_GetDouble(FromObj) instead. #TEA_BUGGY_STRTOD fi ]) #------------------------------------------------------------------------ # TEA_MAKE_LIB -- # # Generate a line that can be used to build a shared/unshared library # in a platform independent manner. # # Arguments: # none # # Requires: # # Results: # # Defines the following vars: # CFLAGS - Done late here to note disturb other AC macros # MAKE_LIB - Command to execute to build the Tcl library; # differs depending on whether or not Tcl is being # compiled as a shared library. # MAKE_SHARED_LIB Makefile rule for building a shared library # MAKE_STATIC_LIB Makefile rule for building a static library # MAKE_STUB_LIB Makefile rule for building a stub library # VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL # VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE #------------------------------------------------------------------------ AC_DEFUN([TEA_MAKE_LIB], [ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)" AC_EGREP_CPP([manifest needed], [ #if defined(_MSC_VER) && _MSC_VER >= 1400 print("manifest needed") #endif ], [ # Could do a CHECK_PROG for mt, but should always be with MSVC8+ VC_MANIFEST_EMBED_DLL="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;2 ; fi" VC_MANIFEST_EMBED_EXE="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;1 ; fi" MAKE_SHARED_LIB="${MAKE_SHARED_LIB} ; ${VC_MANIFEST_EMBED_DLL}" TEA_ADD_CLEANFILES([*.manifest]) ]) MAKE_STUB_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_STUB_OBJECTS)" else MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}" MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)" fi if test "${SHARED_BUILD}" = "1" ; then MAKE_LIB="${MAKE_SHARED_LIB} " else MAKE_LIB="${MAKE_STATIC_LIB} " fi #-------------------------------------------------------------------- # Shared libraries and static libraries have different names. # Use the double eval to make sure any variables in the suffix is # substituted. (@@@ Might not be necessary anymore) #-------------------------------------------------------------------- if test "${TEA_PLATFORM}" = "windows" ; then if test "${SHARED_BUILD}" = "1" ; then # We force the unresolved linking of symbols that are really in # the private libraries of Tcl and Tk. SHLIB_LD_LIBS="${SHLIB_LD_LIBS} '`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`'" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} '`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`'" fi eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" else eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build their own stubs libraries eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" if test "$GCC" = "yes"; then PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE} fi # These aren't needed on Windows (either MSVC or gcc) RANLIB=: RANLIB_STUB=: else RANLIB_STUB="${RANLIB}" if test "${SHARED_BUILD}" = "1" ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC} ${TCL_LIB_SPEC}" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}" fi eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" RANLIB=: else eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build their own stubs libraries eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" fi # These are escaped so that only CFLAGS is picked up at configure time. # The other values will be substituted at make time. CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}" if test "${SHARED_BUILD}" = "1" ; then CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}" fi AC_SUBST(MAKE_LIB) AC_SUBST(MAKE_SHARED_LIB) AC_SUBST(MAKE_STATIC_LIB) AC_SUBST(MAKE_STUB_LIB) AC_SUBST(RANLIB_STUB) AC_SUBST(VC_MANIFEST_EMBED_DLL) AC_SUBST(VC_MANIFEST_EMBED_EXE) ]) #------------------------------------------------------------------------ # TEA_LIB_SPEC -- # # Compute the name of an existing object library located in libdir # from the given base name and produce the appropriate linker flags. # # Arguments: # basename The base name of the library without version # numbers, extensions, or "lib" prefixes. # extra_dir Extra directory in which to search for the # library. This location is used first, then # $prefix/$exec-prefix, then some defaults. # # Requires: # TEA_INIT and TEA_PREFIX must be called first. # # Results: # # Defines the following vars: # ${basename}_LIB_NAME The computed library name. # ${basename}_LIB_SPEC The computed linker flags. #------------------------------------------------------------------------ AC_DEFUN([TEA_LIB_SPEC], [ AC_MSG_CHECKING([for $1 library]) # Look in exec-prefix for the library (defined by TEA_PREFIX). tea_lib_name_dir="${exec_prefix}/lib" # Or in a user-specified location. if test x"$2" != x ; then tea_extra_lib_dir=$2 else tea_extra_lib_dir=NONE fi for i in \ `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr /usr/lib64/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr /usr/lib64/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do if test -f "$i" ; then tea_lib_name_dir=`dirname $i` $1_LIB_NAME=`basename $i` $1_LIB_PATH_NAME=$i break fi done if test "${TEA_PLATFORM}" = "windows"; then $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\" else # Strip off the leading "lib" and trailing ".a" or ".so" tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'` $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}" fi if test "x${$1_LIB_NAME}" = x ; then AC_MSG_ERROR([not found]) else AC_MSG_RESULT([${$1_LIB_SPEC}]) fi ]) #------------------------------------------------------------------------ # TEA_PRIVATE_TCL_HEADERS -- # # Locate the private Tcl include files # # Arguments: # # Requires: # TCL_SRC_DIR Assumes that TEA_LOAD_TCLCONFIG has # already been called. # # Results: # # Substitutes the following vars: # TCL_TOP_DIR_NATIVE # TCL_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [ # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh} AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS]) AC_MSG_CHECKING([for Tcl private include files]) TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}` TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\" # Check to see if tcl<Plat>Port.h isn't already with the public headers # Don't look for tclInt.h because that resides with tcl.h in the core # sources, but the <plat>Port headers are in a different directory if test "${TEA_PLATFORM}" = "windows" -a \ -f "${ac_cv_c_tclh}/tclWinPort.h"; then result="private headers found with public headers" elif test "${TEA_PLATFORM}" = "unix" -a \ -f "${ac_cv_c_tclh}/tclUnixPort.h"; then result="private headers found with public headers" else TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\" if test "${TEA_PLATFORM}" = "windows"; then TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\" else TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\" fi # Overwrite the previous TCL_INCLUDES as this should capture both # public and private headers in the same set. # We want to ensure these are substituted so as not to require # any *_NATIVE vars be defined in the Makefile TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}" if test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use # the framework's Headers and PrivateHeaders directories case ${TCL_DEFS} in *TCL_FRAMEWORK*) if test -d "${TCL_BIN_DIR}/Headers" -a \ -d "${TCL_BIN_DIR}/PrivateHeaders"; then TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}" else TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`" fi ;; esac result="Using ${TCL_INCLUDES}" else if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}]) fi result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}" fi fi AC_SUBST(TCL_TOP_DIR_NATIVE) AC_SUBST(TCL_INCLUDES) AC_MSG_RESULT([${result}]) ]) #------------------------------------------------------------------------ # TEA_PUBLIC_TCL_HEADERS -- # # Locate the installed public Tcl header files # # Arguments: # None. # # Requires: # CYGPATH must be set # # Results: # # Adds a --with-tclinclude switch to configure. # Result is cached. # # Substitutes the following vars: # TCL_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [ AC_MSG_CHECKING([for Tcl public headers]) AC_ARG_WITH(tclinclude, [ --with-tclinclude directory containing the public Tcl header files], with_tclinclude=${withval}) AC_CACHE_VAL(ac_cv_c_tclh, [ # Use the value from --with-tclinclude, if it was given if test x"${with_tclinclude}" != x ; then if test -f "${with_tclinclude}/tcl.h" ; then ac_cv_c_tclh=${with_tclinclude} else AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h]) fi else list="" if test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use # the framework's Headers directory case ${TCL_DEFS} in *TCL_FRAMEWORK*) list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`" ;; esac fi # Look in the source dir only if Tcl is not installed, # and in that situation, look there before installed locations. if test -f "${TCL_BIN_DIR}/Makefile" ; then list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" if test x"${TCL_INCLUDE_SPEC}" != x ; then d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'` list="$list `ls -d ${d} 2>/dev/null`" fi fi for i in $list ; do if test -f "$i/tcl.h" ; then ac_cv_c_tclh=$i break fi done fi ]) # Print a message based on how we determined the include path if test x"${ac_cv_c_tclh}" = x ; then AC_MSG_ERROR([tcl.h not found. Please specify its location with --with-tclinclude]) else AC_MSG_RESULT([${ac_cv_c_tclh}]) fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}` TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" AC_SUBST(TCL_INCLUDES) ]) #------------------------------------------------------------------------ # TEA_PRIVATE_TK_HEADERS -- # # Locate the private Tk include files # # Arguments: # # Requires: # TK_SRC_DIR Assumes that TEA_LOAD_TKCONFIG has # already been called. # # Results: # # Substitutes the following vars: # TK_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [ # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh} AC_REQUIRE([TEA_PUBLIC_TK_HEADERS]) AC_MSG_CHECKING([for Tk private include files]) TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}` TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\" # Check to see if tk<Plat>Port.h isn't already with the public headers # Don't look for tkInt.h because that resides with tk.h in the core # sources, but the <plat>Port headers are in a different directory if test "${TEA_PLATFORM}" = "windows" -a \ -f "${ac_cv_c_tkh}/tkWinPort.h"; then result="private headers found with public headers" elif test "${TEA_PLATFORM}" = "unix" -a \ -f "${ac_cv_c_tkh}/tkUnixPort.h"; then result="private headers found with public headers" else TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\" TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\" if test "${TEA_PLATFORM}" = "windows"; then TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\" else TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\" fi # Overwrite the previous TK_INCLUDES as this should capture both # public and private headers in the same set. # We want to ensure these are substituted so as not to require # any *_NATIVE vars be defined in the Makefile TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}" # Detect and add ttk subdir if test -d "${TK_SRC_DIR}/generic/ttk"; then TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\"" fi if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\"" fi if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\"" fi if test "`uname -s`" = "Darwin"; then # If Tk was built as a framework, attempt to use # the framework's Headers and PrivateHeaders directories case ${TK_DEFS} in *TK_FRAMEWORK*) if test -d "${TK_BIN_DIR}/Headers" -a \ -d "${TK_BIN_DIR}/PrivateHeaders"; then TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}" else TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`" fi ;; esac result="Using ${TK_INCLUDES}" else if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}]) fi result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}" fi fi AC_SUBST(TK_TOP_DIR_NATIVE) AC_SUBST(TK_XLIB_DIR_NATIVE) AC_SUBST(TK_INCLUDES) AC_MSG_RESULT([${result}]) ]) #------------------------------------------------------------------------ # TEA_PUBLIC_TK_HEADERS -- # # Locate the installed public Tk header files # # Arguments: # None. # # Requires: # CYGPATH must be set # # Results: # # Adds a --with-tkinclude switch to configure. # Result is cached. # # Substitutes the following vars: # TK_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [ AC_MSG_CHECKING([for Tk public headers]) AC_ARG_WITH(tkinclude, [ --with-tkinclude directory containing the public Tk header files], with_tkinclude=${withval}) AC_CACHE_VAL(ac_cv_c_tkh, [ # Use the value from --with-tkinclude, if it was given if test x"${with_tkinclude}" != x ; then if test -f "${with_tkinclude}/tk.h" ; then ac_cv_c_tkh=${with_tkinclude} else AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h]) fi else list="" if test "`uname -s`" = "Darwin"; then # If Tk was built as a framework, attempt to use # the framework's Headers directory. case ${TK_DEFS} in *TK_FRAMEWORK*) list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`" ;; esac fi # Look in the source dir only if Tk is not installed, # and in that situation, look there before installed locations. if test -f "${TK_BIN_DIR}/Makefile" ; then list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tk's --prefix location, # relative to directory of tkConfig.sh, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TK_PREFIX}/include 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" if test x"${TK_INCLUDE_SPEC}" != x ; then d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'` list="$list `ls -d ${d} 2>/dev/null`" fi fi for i in $list ; do if test -f "$i/tk.h" ; then ac_cv_c_tkh=$i break fi done fi ]) # Print a message based on how we determined the include path if test x"${ac_cv_c_tkh}" = x ; then AC_MSG_ERROR([tk.h not found. Please specify its location with --with-tkinclude]) else AC_MSG_RESULT([${ac_cv_c_tkh}]) fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}` #TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" TK_INCLUDES=-I\'${INCLUDE_DIR_NATIVE}\' AC_SUBST(TK_INCLUDES) if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then # On Windows and Aqua, we need the X compat headers AC_MSG_CHECKING([for X11 header files]) if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`" TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" AC_SUBST(TK_XINCLUDES) fi AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}]) fi ]) #------------------------------------------------------------------------ # TEA_PATH_CONFIG -- # # Locate the ${1}Config.sh file and perform a sanity check on # the ${1} compile flags. These are used by packages like # [incr Tk] that load *Config.sh files from more than Tcl and Tk. # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-$1=... # # Defines the following vars: # $1_BIN_DIR Full path to the directory containing # the $1Config.sh file #------------------------------------------------------------------------ AC_DEFUN([TEA_PATH_CONFIG], [ # # Ok, lets find the $1 configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-$1 # if test x"${no_$1}" = x ; then # we reset no_$1 in case something fails here no_$1=true AC_ARG_WITH($1, [ --with-$1 directory containing $1 configuration ($1Config.sh)], with_$1config=${withval}) AC_MSG_CHECKING([for $1 configuration]) AC_CACHE_VAL(ac_cv_c_$1config,[ # First check to see if --with-$1 was specified. if test x"${with_$1config}" != x ; then case ${with_$1config} in */$1Config.sh ) if test -f ${with_$1config}; then AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself]) with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'` fi;; esac if test -f "${with_$1config}/$1Config.sh" ; then ac_cv_c_$1config=`(cd ${with_$1config}; pwd)` else AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh]) fi fi # then check for a private $1 installation if test x"${ac_cv_c_$1config}" = x ; then for i in \ ../$1 \ `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ../../$1 \ `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ../../../$1 \ `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ${srcdir}/../$1 \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ; do if test -f "$i/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i; pwd)` break fi if test -f "$i/unix/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i/unix; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_$1config}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ ; do if test -f "$i/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i; pwd)` break fi done fi ]) if test x"${ac_cv_c_$1config}" = x ; then $1_BIN_DIR="# no $1 configs found" AC_MSG_WARN([Cannot find $1 configuration definitions]) exit 0 else no_$1= $1_BIN_DIR=${ac_cv_c_$1config} AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh]) fi fi ]) #------------------------------------------------------------------------ # TEA_LOAD_CONFIG -- # # Load the $1Config.sh file # # Arguments: # # Requires the following vars to be set: # $1_BIN_DIR # # Results: # # Substitutes the following vars: # $1_SRC_DIR # $1_LIB_FILE # $1_LIB_SPEC #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_CONFIG], [ AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh]) if test -f "${$1_BIN_DIR}/$1Config.sh" ; then AC_MSG_RESULT([loading]) . "${$1_BIN_DIR}/$1Config.sh" else AC_MSG_RESULT([file not found]) fi # # If the $1_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable $1_LIB_SPEC will be set to the value # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC # instead of $1_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. # if test -f "${$1_BIN_DIR}/Makefile" ; then AC_MSG_WARN([Found Makefile - using build library specs for $1]) $1_LIB_SPEC=${$1_BUILD_LIB_SPEC} $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC} $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH} $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC} $1_LIBRARY_PATH=${$1_LIBRARY_PATH} fi AC_SUBST($1_VERSION) AC_SUBST($1_BIN_DIR) AC_SUBST($1_SRC_DIR) AC_SUBST($1_LIB_FILE) AC_SUBST($1_LIB_SPEC) AC_SUBST($1_STUB_LIB_FILE) AC_SUBST($1_STUB_LIB_SPEC) AC_SUBST($1_STUB_LIB_PATH) # Allow the caller to prevent this auto-check by specifying any 2nd arg AS_IF([test "x$2" = x], [ # Check both upper and lower-case variants # If a dev wanted non-stubs libs, this function could take an option # to not use _STUB in the paths below AS_IF([test "x${$1_STUB_LIB_SPEC}" = x], [TEA_LOAD_CONFIG_LIB(translit($1,[a-z],[A-Z])_STUB)], [TEA_LOAD_CONFIG_LIB($1_STUB)]) ]) ]) #------------------------------------------------------------------------ # TEA_LOAD_CONFIG_LIB -- # # Helper function to load correct library from another extension's # ${PACKAGE}Config.sh. # # Results: # Adds to LIBS the appropriate extension library #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_CONFIG_LIB], [ AC_MSG_CHECKING([For $1 library for LIBS]) # This simplifies the use of stub libraries by automatically adding # the stub lib to your path. Normally this would add to SHLIB_LD_LIBS, # but this is called before CONFIG_CFLAGS. More importantly, this adds # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD. if test "x${$1_LIB_SPEC}" != "x" ; then if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then TEA_ADD_LIBS([\"`${CYGPATH} ${$1_LIB_PATH}`\"]) AC_MSG_RESULT([using $1_LIB_PATH ${$1_LIB_PATH}]) else TEA_ADD_LIBS([${$1_LIB_SPEC}]) AC_MSG_RESULT([using $1_LIB_SPEC ${$1_LIB_SPEC}]) fi else AC_MSG_RESULT([file not found]) fi ]) #------------------------------------------------------------------------ # TEA_EXPORT_CONFIG -- # # Define the data to insert into the ${PACKAGE}Config.sh file # # Arguments: # # Requires the following vars to be set: # $1 # # Results: # Substitutes the following vars: #------------------------------------------------------------------------ AC_DEFUN([TEA_EXPORT_CONFIG], [ #-------------------------------------------------------------------- # These are for $1Config.sh #-------------------------------------------------------------------- # pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib) eval pkglibdir="[$]{libdir}/$1${PACKAGE_VERSION}" if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then eval $1_LIB_FLAG="-l$1${PACKAGE_VERSION}${DBGX}" eval $1_STUB_LIB_FLAG="-l$1stub${PACKAGE_VERSION}${DBGX}" else eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}" eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}" fi $1_BUILD_LIB_SPEC="-L`pwd` ${$1_LIB_FLAG}" $1_LIB_SPEC="-L${pkglibdir} ${$1_LIB_FLAG}" $1_BUILD_STUB_LIB_SPEC="-L`pwd` [$]{$1_STUB_LIB_FLAG}" $1_STUB_LIB_SPEC="-L${pkglibdir} [$]{$1_STUB_LIB_FLAG}" $1_BUILD_STUB_LIB_PATH="`pwd`/[$]{PKG_STUB_LIB_FILE}" $1_STUB_LIB_PATH="${pkglibdir}/[$]{PKG_STUB_LIB_FILE}" AC_SUBST($1_BUILD_LIB_SPEC) AC_SUBST($1_LIB_SPEC) AC_SUBST($1_BUILD_STUB_LIB_SPEC) AC_SUBST($1_STUB_LIB_SPEC) AC_SUBST($1_BUILD_STUB_LIB_PATH) AC_SUBST($1_STUB_LIB_PATH) AC_SUBST(MAJOR_VERSION) AC_SUBST(MINOR_VERSION) AC_SUBST(PATCHLEVEL) ]) #------------------------------------------------------------------------ # TEA_PATH_CELIB -- # # Locate Keuchel's celib emulation layer for targeting Win/CE # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-celib=... # # Defines the following vars: # CELIB_DIR Full path to the directory containing # the include and platform lib files #------------------------------------------------------------------------ AC_DEFUN([TEA_PATH_CELIB], [ # First, look for one uninstalled. # the alternative search directory is invoked by --with-celib if test x"${no_celib}" = x ; then # we reset no_celib in case something fails here no_celib=true AC_ARG_WITH(celib,[ --with-celib=DIR use Windows/CE support library from DIR], with_celibconfig=${withval}) AC_MSG_CHECKING([for Windows/CE celib directory]) AC_CACHE_VAL(ac_cv_c_celibconfig,[ # First check to see if --with-celibconfig was specified. if test x"${with_celibconfig}" != x ; then if test -d "${with_celibconfig}/inc" ; then ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)` else AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory]) fi fi # then check for a celib library if test x"${ac_cv_c_celibconfig}" = x ; then for i in \ ../celib-palm-3.0 \ ../celib \ ../../celib-palm-3.0 \ ../../celib \ `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \ ${srcdir}/../celib-palm-3.0 \ ${srcdir}/../celib \ `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \ ; do if test -d "$i/inc" ; then ac_cv_c_celibconfig=`(cd $i; pwd)` break fi done fi ]) if test x"${ac_cv_c_celibconfig}" = x ; then AC_MSG_ERROR([Cannot find celib support library directory]) else no_celib= CELIB_DIR=${ac_cv_c_celibconfig} CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'` AC_MSG_RESULT([found $CELIB_DIR]) fi fi ]) # Local Variables: # mode: autoconf # End: |
Added tk/test/widget-test.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 |
# location of Tk text widget source code: # /u/prod_dev/tcltk/src/8.5.a5/tk/generic/tkText.c set DO_TEXT 0 ;# create a std Tk Text widget? set DO_SBAR 1 ;# create scrollbar? set DO_FILE 1 ;# load a file? set DO_FOCUS 1 ;# put focus into widget? set DO_LANG 1 ;# use syntax highlighting? set DO_BINDS 1 ;# do we load the default bindings? set DO_LNUMS 1 ;# show line numbers? set DO_IMGS 1 ;# show image-based markers? set DO_FOLD 1 ;# show fold margin # load the shared library set SUFFIX "" if {[info exists ::env(WINDIR)] && [info exists ::tcl_platform(debug)]} { set SUFFIX "g" } lappend auto_path [file normalize ../../build/usr/lib] package require ScintillaTk ################## # TEST ################## set curr_loc "" proc moveupdate {args} { set ix [$::sci index insert] ::scan $ix {%d.%d} row col set ::curr_loc [format "RC: %d, %d" $row $col] } proc addedupdate {args} { # puts "ADDED UPDATE: args=$args" eval $::sci margin filln LINENUMBERS $args } proc clicked {args} { ::lassign $args margin line x y btn shift ctrl alt puts "MARGIN CLICK: margin=$margin line=$line X,Y=$x,$y btn=$btn shift=$shift ctrl=$ctrl alt=$alt" } set scif .cf destroy $scif .t # create the widget frame $scif set sci $scif.c scintilla $sci set rpad [frame $scif.rpad -width 4] ;# << "internal" pad on RHS of text area $scif config -bg [$sci cget -bg] $rpad config -bg [$sci cget -bg] pack $rpad -side right -fill y pack $sci -side left -fill both -expand 1 # configure callbacks $sci config -moveupdatec moveupdate -linesa addedupdate # configure appearance $sci tag config exec -margin -fg red # configure the margins we want $sci margin config 0 -type text -alias cov1 $sci margin config 1 -type symbol -alias cov2 -clickc clicked $sci margin config 2 -type lnums_alt -alias LINENUMBERS -clickc clicked $sci margin config 3 -type symbol -alias marks -wid 18 -clickc clicked $sci margin config 4 -type fold if {$DO_SBAR} { ttk::scrollbar .vsb -command "$sci yview" ttk::scrollbar .hsb -command "$sci xview" -orient horizontal $sci config -yscrollcommand ".vsb set" $sci config -xscrollcommand ".hsb set" frame .f button .f.b1 -text "-" -command "$sci zoomout" -repeatdelay 500 -repeatint 100 button .f.b2 -text "+" -command "$sci zoomin" -repeatdelay 500 -repeatint 100 label .f.loc -textvariable ::curr_loc -font {-family courier} -relief sunken label .f.l -text "Zoom:" pack .f.loc -side right pack .f.l .f.b1 .f.b2 -side left grid $scif -row 0 -column 0 -sticky nswe grid .vsb -row 0 -column 1 -sticky ns grid .hsb -row 1 -column 0 -sticky we grid .f -row 2 -column 0 -sticky we grid rowconfig . 0 -weight 1 grid columnconfig . 0 -weight 1 } else { pack $scif -fill both -expand 1 } set lang "none" if {[llength $argv] > 0} { set f [lindex $argv 0] } else { set EX . set f $EX/PlatTK.cxx } if {$DO_LANG} { switch [::file extension $f] { .tcl {$sci config -lang tcl} .sv - .svh - .v {$sci config -lang verilog} .c - .cxx - .cpp {$sci config -lang cpp} .vhd - .vhdl {$sci config -lang vhdl} .htm - .html - .rmdb {$sci config -lang html} } } if {$DO_TEXT} { toplevel .t wm title .t "Tk Text" ttk::scrollbar .t.vsb -command ".t.t yview" ttk::scrollbar .t.hsb -command ".t.t xview" -orient horizontal text .t.t -wrap none -yscrollc ".t.vsb set" -xscrollc ".t.hsb set" grid .t.t -row 0 -column 0 -sticky nswe grid .t.vsb -row 0 -column 1 -sticky ns grid .t.hsb -row 1 -column 0 -sticky we grid rowconfig .t 0 -weight 1 grid columnconfig .t 0 -weight 1 # pack .t.vsb -side right -fill y -expand 0 # pack .t.t -side left -fill both -expand 1 } if {$DO_FILE} { set fd [open $f r] puts [format "FILE LOAD TIME1: %s" [lrange [time [list $sci insert end [read $fd]]] 0 1]] if {$DO_TEXT} { seek $fd 0 puts [format "FILE LOAD TIME2: %s" [lrange [time [list .t.t insert end [read $fd]]] 0 1]] } close $fd if {$DO_LNUMS} { $sci margin show LINENUMBERS ;# do it here so we'll know how many lines are in the file } wm title . "Scintilla TK ($f)" } else { wm title . "Scintilla TK" } if {$DO_FOCUS} { focus $sci } . config -bg red ;# <<< this will show if we're missing something in the paint code set xpm_pointer {/* XPM */ static char * InlineData[] = { "16 16 14 1", " s None c None", ". c #0080ff", "# c #006ce0", "a c #0000c0", "b c #3b9bff", "c c #3b70ea", "d c #0076ef", "e c #58a8ff", "f c #002cc0", "g c #168aff", "h c #162ad0", "i c #0042c0", "j c #0058c0", "k c #2c54e0", " ", " j ", " #b ", " #.b ", " #..g ", "j######d...ge ", "j............b ", "j#############j ", "jaaaaaaaaaaaahj ", "jaaaaaaaaaaak ", "ajjjjjjfaaac ", " fahc ", " fh ", " i ", " ", " "};} set xpm_rightarrow {/* XPM */ static char * InlineData[] = { "16 16 76 2", " s None c None", ".. c #0543df", "#. c #083bcc", "a. c #0850e2", "b. c #0659f0", "c. c #065af4", "d. c #073dc7", "e. c #0551eb", "f. c #3d9cfd", "g. c #0127b7", "h. c #0360fb", "i. c #065cf8", "j. c #7bbefd", "k. c #1789fd", "l. c #0127b3", "m. c #0668fc", "n. c #025df4", "o. c #0752eb", "p. c #3c96fc", "q. c #0f68fb", "r. c #0649e2", "s. c #0940cb", "t. c #247ffc", "u. c #0637c2", "v. c #3090fc", "w. c #0638c6", "x. c #063cd6", "y. c #064fe4", "z. c #55acfd", "A. c #093bc9", "B. c #91c4fd", "C. c #0350ed", "D. c #71b9fd", "E. c #419efd", "F. c #083fcc", "G. c #0841d4", "H. c #022fc2", "I. c #0460f8", "J. c #4fa5fd", "K. c #69b2fd", "L. c #3291fc", "M. c #084fe0", "N. c #57adfd", "O. c #0548df", "P. c #0550e9", "Q. c #022abc", "R. c #0e79fe", "S. c #a1ccfd", "T. c #0740d1", "U. c #0743dd", "V. c #0748db", "W. c #0749df", "X. c #0128b9", "Y. c #073cd3", "Z. c #1074fc", "0. c #0750e5", "1. c #33a5fd", "2. c #0335c5", "3. c #074deb", "4. c #0457f0", "5. c #032fbf", "6. c #025ffa", "7. c #093ac7", "8. c #b6d5fc", "9. c #3c92fc", ".# c #064ae4", "## c #1e7cfc", "a# c #0535c1", "b# c #4fa9fd", "c# c #2796fd", "d# c #0650e6", "e# c #0351ef", "f# c #43a3fd", "g# c #0842d6", "h# c #086ffc", "i# c #4db5fd", " ", " a.5. ", " y.9.5. ", " d#p.J.a# ", " W.M.0.o.b.i.q.t.f.b#K.u. ", " g#U..#o.c.q.##v.E.z.D.B.w. ", " g#U..#3.c.q.##L.f#N.j.S.8.d.", " 7.7.7.7.#.x.O.e#6.h#k.1.i#2.", " 7.7.7.7.A.Y...C.n.m.R.c#H. ", " G.G.G.G.G.V.r.P.4.h.Z.Q. ", " T.P.I.X. ", " F.e.g. ", " s.l. ", " ", " ", " "};} set xpm_rainbow {/* XPM */ static char * InlineData[] = { "16 16 199 2", " s None c None", ".. c #faceac", "#. c #f8ed8d", "a. c #1d6494", "b. c #fc0e2b", "c. c #1a8693", "d. c #f53780", "e. c #705fbd", "f. c #f9dd9d", "g. c #f24dac", "h. c #6c43ff", "i. c #ed6ae7", "j. c #f054bb", "k. c #9955ff", "l. c #4457a7", "m. c #695eba", "n. c #ebf388", "o. c #245297", "p. c #f348a1", "q. c #12e190", "r. c #ff81fa", "s. c #fda0db", "t. c #f8e496", "u. c #f479ff", "v. c #1c7094", "w. c #f056bf", "x. c #35fd8d", "y. c #fbbdbd", "z. c #ca6eea", "A. c #f24ba9", "B. c #eb73fa", "C. c #4458a7", "D. c #fca9d3", "E. c #fcafcc", "F. c #f63479", "G. c #facead", "H. c #fca7d4", "I. c #1b7b94", "J. c #ff82fa", "K. c #37fd8d", "L. c #bcf589", "M. c #189f92", "N. c #ebf289", "O. c #c46de7", "P. c #1e6694", "Q. c #fa1d49", "R. c #f3459a", "S. c #b1f68a", "T. c #baf689", "U. c #fbb0cc", "V. c #ed6eef", "W. c #199592", "X. c #de71f4", "Y. c #705fbe", "Z. c #edf289", "0. c #5039ff", "1. c #f6367d", "2. c #bb62ff", "3. c #f9db9f", "4. c #f6f288", "5. c #ef5fd2", "6. c #ca68ff", "7. c #f43d8c", "8. c #3efc8d", "9. c #f3479e", ".# c #f348a2", "## c #ec70f3", "a# c #f8265c", "b# c #ee65dd", "c# c #d16fee", "d# c #f05ac7", "e# c #73fa8c", "f# c #7ff98b", "g# c #f53985", "h# c #17ab92", "i# c #1b7f93", "j# c #fbbdbe", "k# c #f92255", "l# c #ed68e5", "m# c #bc63ff", "n# c #fc163b", "o# c #1a8a93", "p# c #f151b5", "q# c #8b64cb", "r# c #f3469f", "s# c #17ac92", "t# c #fcabcf", "u# c #8c64cb", "v# c #fad2a8", "w# c #c9f489", "x# c #32549f", "y# c #4758a8", "z# c #f058c4", "A# c #50fb8c", "B# c #11fe8e", "C# c #f7ef8a", "D# c #12dd8f", "E# c #7ff88c", "F# c #10f28f", "G# c #eb75ff", "H# c #fd95e6", "I# c #85f98b", "J# c #9f58ff", "K# c #f152b5", "L# c #d870f2", "M# c #f9d9a1", "N# c #fc1334", "O# c #f8265d", "P# c #f53c89", "Q# c #af5eff", "R# c #1b8193", "S# c #f7306f", "T# c #f059c4", "U# c #ec6be9", "V# c #a158ff", "W# c #f24eae", "X# c #ee60d3", "Y# c #fb1a43", "Z# c #3b56a2", "0# c #ed6ced", "1# c #9352ff", "2# c #18a392", "3# c #ef5fcf", "4# c #fd9cdf", "5# c #fbc3b8", "6# c #c3f58a", "7# c #59fa8c", "8# c #1e5694", "9# c #fa2152", ".a c #b36adf", "#a c #f9daa1", "aa c #1c6b94", "ba c #f82861", "ca c #f73377", "da c #cdf589", "ea c #f53982", "fa c #fd7cff", "ga c #ee63db", "ha c #ee62d7", "ia c #e070ff", "ja c #19fe8e", "ka c #50fb8d", "la c #fac2b9", "ma c #1a8d93", "na c #f8ef8b", "oa c #11ea8f", "pa c #1a8393", "qa c #fd95e7", "ra c #fda3d8", "sa c #17b191", "ta c #eb70f5", "ua c #f82a65", "va c #a0f68a", "wa c #f347a0", "xa c #f9d9a2", "ya c #ee77ff", "za c #95f78b", "Aa c #d4f489", "Ba c #10f58f", "Ca c #f73174", "Da c #f73070", "Ea c #f059c5", "Fa c #96f78b", "Ga c #a167d6", "Ha c #f44191", "Ia c #f054ba", "Ja c #ed6ae6", "Ka c #fac9b2", "La c #f6377f", "Ma c #3c30ff", "Na c #fac1ba", "Oa c #3455a0", "Pa c #a0f78a", "Qa c #8262c6", "Ra c #3d30ff", "Sa c #ec71f5", "Ta c #ec72f9", "Ua c #18a891", "Va c #3555a0", "Wa c #f8275e", "Xa c #f14faf", "Ya c #fe091f", "Za c #fbbfbb", "0a c #a2f78a", "1a c #a969d9", "2a c #ee62d8", "3a c #1c7093", "4a c #fb1c48", "5a c #f72e6d", "6a c #5c5cb3", "7a c #3c31ff", "8a c #d36cff", "9a c #a7f68a", ".b c #22fe8e", "#b c #fac8b3", "ab c #2efd8d", "bb c #fca1da", "cb c #3d31ff", "db c #ef5dcd", " cbcb7acbcb1#J#cbRacbcbcb ", " 7a7acb6.bb#bM#3.G.U.ya7aRaMa ", "7acbcbqaf.vaK.oaq..bf##.E.V#cbcb", "7a7as.n..bpax#m.e.y#3aD#S.y.1#7a", "cbJ.naBa8#.a0#b#gai.L#l.s#T.H.cb", "0.Kakaa.c#haK#p.r#W#dbSaZ#F#t.8a", "G#4.h#Qab#g.eaS#5a1.wa3#O.i#0a4#", "H#9aI.X.z#7.ua4aY#a#d.p#V.o.A#j#", "raI#P.SaIaLak#b.YaQ.CaA.l#l.ab#b", "4#zav.Taw.g#O#n#N#9#F.XaU#Va8.5#", "r.AaW.1aX#9.cabaWaDaHaT#B.aaE#t#", "Q#M#jaOa##d#.#7.P#R.j.JaY.saZ.fa", "7as.L.2#6ata2ad#Ea5.0#q#R#e#Nacb", "Rak.laFaUao.u#z.c#GaC.ma7##aiacb", " cb2.Zadax.h#o#c.M.B#Pav#u.cb ", " cbh.H#..C#w#6#N.xaD.m#cb "};} puts "LOADED widget.tcl" if {$DO_IMGS} { if {![catch {package require Img} oops]} { set img1 [image create photo -data $xpm_pointer] $sci marker configure pointer -image $img1 set img2 [image create photo -data $xpm_rightarrow] $sci marker configure rightarrow -image $img2 } else { $sci marker configure pointer -xpm $xpm_pointer $sci marker configure rightarrow -xpm $xpm_rightarrow } # here's an example of using the raw XPM data directly $sci marker configure rainbow -xpm $xpm_rainbow $sci margin marker 3 add pointer 16 $sci margin marker 3 add rainbow 17 $sci margin marker 3 add rightarrow 19 } if {$DO_FOLD} { $sci margin show fold } |
Added tk/test/widget-text-test.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 |
# # Taken from Tk tests for the text widget # proc test {tname desc args} { global testlist set match 0 foreach t $testlist { if {[set match [string match $t $tname]]} { break } } if {!$match} return foreach {opt val} $args { switch -- $opt { -setup { set setup $val } -body { set script $val } -cleanup { set cleanup $val } -result { set expected $val } default { lappend leftover $opt $val } } } if {[info exists leftover]} { lassign $leftover script expected } puts -nonewline "# $tname - $desc..." if {[info exists setup]} { if {[catch {uplevel $setup} rv]} { puts "\nError: $rv" return } } if {[catch {uplevel $script} rv]} { puts " Error: $rv" } elseif {[string compare $rv $expected]} { puts " Error: mismatch. Exptected: \"$expected\" Got: \"$rv\"" } else { puts " Pass" } if {[info exists cleanup]} { if {[catch {uplevel $cleanup} rv]} { puts "Cleanup Error: $rv" return } } } proc deleteWindows {} { catch { foreach c [winfo children .] { destroy $c } } } # load the shared library lappend auto_path [file normalize ../../build/usr/lib] package require ScintillaTk scintilla .t pack .t catch {destroy .t2} scintilla .t2 set i 0 if {[llength $argv] > 0} { set testlist $argv } else { set testlist * } foreach test { {-autoseparators yes 1 nah} {-background #ff00ff #ff00ff <gorp>} {-bd 4 4 foo} {-bg blue blue #xx} {-blockcursor 0 0 xx} {-borderwidth 7 7 ++} {-cursor watch watch lousy} {-exportselection no 0 maybe} {-fg red red stupid} {-font fixed fixed {}} {-foreground #012 #012 bogus} {-height 5 5 bad} {-highlightbackground #123 #123 bogus} {-highlightcolor #234 #234 bogus} {-highlightthickness -2 0 bad} {-inactiveselectbackground #ffff01234567 #ffff01234567 bogus} {-insertbackground green green <bogus>} {-insertborderwidth 45 45 bogus} {-insertofftime 100 100 2.4} {-insertontime 47 47 e1} {-insertwidth 2.3 2 47d} {-maxundo 5 5 noway} {-padx 3.4 3 2.4.} {-pady 82 82 bogus} {-relief raised raised bumpy} {-selectbackground #ffff01234567 #ffff01234567 bogus} {-selectborderwidth 21 21 3x} {-selectforeground yellow yellow #12345} {-spacing1 20 20 1.3x} {-spacing1 -5 0 bogus} {-spacing2 5 5 bogus} {-spacing2 -1 0 bogus} {-spacing3 20 20 bogus} {-spacing3 -10 0 bogus} {-state d disabled foo} {-tabs {1i 2i 3i 4i} {1i 2i 3i 4i} bad_tabs} {-tabstyle wordprocessor wordprocessor garbage} {-undo 1 1 eh} {-width 73 73 2.4} {-wrap w word bad_wrap} } { test text-1.[incr i] {text options} { set result {} lappend result [catch {.t2 configure [lindex $test 0] [lindex $test 3]}] .t2 configure [lindex $test 0] [lindex $test 1] lappend result [.t2 cget [lindex $test 0]] } [list 1 [lindex $test 2]] } test text-1.[incr i] {text options} { .t2 configure -takefocus "any old thing" .t2 cget -takefocus } {any old thing} test text-1.[incr i] {text options} { .t2 configure -xscrollcommand "x scroll command" .t2 configure -xscrollcommand } {-xscrollcommand xScrollCommand ScrollCommand {} {x scroll command}} test text-1.[incr i] {text options} { .t2 configure -yscrollcommand "test command" .t2 configure -yscrollcommand } {-yscrollcommand yScrollCommand ScrollCommand {} {test command}} test text-1.[incr i] {text options} { set result {} foreach i [.t2 configure] { lappend result [lindex $i 4] } set result } {1 blue {} {} 0 7 watch {} 0 {} fixed #012 5 #123 #234 0 #ffff01234567 green 45 100 47 2 5 3 82 raised #ffff01234567 21 yellow 0 0 0 0 {} disabled {1i 2i 3i 4i} wordprocessor {any old thing} 1 73 word {x scroll command} {test command}} test text-2.1 {Tk_TextCmd procedure} { list [catch {text} msg] $msg } {1 {wrong # args: should be "text pathName ?options?"}} test text-2.2 {Tk_TextCmd procedure} { list [catch {scintilla foobar} msg] $msg } {1 {bad window path name "foobar"}} test text-2.3 {Tk_TextCmd procedure} { catch {destroy .t2} list [catch {scintilla .t2 -gorp nofun} msg] $msg [winfo exists .t2] } {1 {unknown option "-gorp"} 0} test text-2.4 {Tk_TextCmd procedure} { catch {destroy .t2} list [catch {scintilla .t2 -bd 2 -fg red} msg] $msg \ [lindex [.t2 config -bd] 4] [lindex [.t2 config -fg] 4] } {0 .t2 2 red} if {$tcl_platform(platform) == "windows"} { set relief flat } elseif {[tk windowingsystem] eq "aqua"} { set relief solid } else { set relief raised } test text-2.5 {Tk_TextCmd procedure} { catch {destroy .t2} scintilla .t2 .t2 tag cget sel -relief } $relief test text-2.6 {Tk_TextCmd procedure} { catch {destroy .t2} list [scintilla .t2] [winfo class .t2] } {.t2 Scintilla} test text-3.1 {TextWidgetCmd procedure, basics} { list [catch {.t} msg] $msg } {1 {wrong # args: should be ".t option ?arg arg ...?"}} test text-3.2 {TextWidgetCmd procedure} { list [catch {.t gorp 1.0 z 1.2} msg] $msg } {1 {bad option "gorp": must be bbox, cget, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, peer, replace, scan, search, see, tag, window, xview, or yview}} test text-4.1 {TextWidgetCmd procedure, "bbox" option} { list [catch {.t bbox} msg] $msg } {1 {wrong # args: should be ".t bbox index"}} test text-4.2 {TextWidgetCmd procedure, "bbox" option} { list [catch {.t bbox a b} msg] $msg } {1 {wrong # args: should be ".t bbox index"}} test text-4.3 {TextWidgetCmd procedure, "bbox" option} { list [catch {.t bbox bad_mark} msg] $msg } {1 {bad text index "bad_mark"}} test text-5.1 {TextWidgetCmd procedure, "cget" option} { list [catch {.t cget} msg] $msg } {1 {wrong # args: should be ".t cget option"}} test text-5.2 {TextWidgetCmd procedure, "cget" option} { list [catch {.t cget a b} msg] $msg } {1 {wrong # args: should be ".t cget option"}} test text-5.3 {TextWidgetCmd procedure, "cget" option} { list [catch {.t cget -gorp} msg] $msg } {1 {unknown option "-gorp"}} test text-5.4 {TextWidgetCmd procedure, "cget" option} { .t configure -bd 17 .t cget -bd } {17} .t configure -borderwidth [lindex [.t configure -borderwidth] 3] test text-6.1 {TextWidgetCmd procedure, "compare" option} { list [catch {.t compare a b} msg] $msg } {1 {wrong # args: should be ".t compare index1 op index2"}} test text-6.2 {TextWidgetCmd procedure, "compare" option} { list [catch {.t compare a b c d} msg] $msg } {1 {wrong # args: should be ".t compare index1 op index2"}} test text-6.3 {TextWidgetCmd procedure, "compare" option} { list [catch {.t compare @x == 1.0} msg] $msg } {1 {bad text index "@x"}} test text-6.4 {TextWidgetCmd procedure, "compare" option} { list [catch {.t compare 1.0 < @y} msg] $msg } {1 {bad text index "@y"}} test text-6.5 {TextWidgetCmd procedure, "compare" option} { list [.t compare 1.1 < 1.0] [.t compare 1.1 < 1.1] [.t compare 1.1 < 1.2] } {0 0 1} test text-6.6 {TextWidgetCmd procedure, "compare" option} { list [.t compare 1.1 <= 1.0] [.t compare 1.1 <= 1.1] [.t compare 1.1 <= 1.2] } {0 1 1} test text-6.7 {TextWidgetCmd procedure, "compare" option} { list [.t compare 1.1 == 1.0] [.t compare 1.1 == 1.1] [.t compare 1.1 == 1.2] } {0 1 0} test text-6.8 {TextWidgetCmd procedure, "compare" option} { list [.t compare 1.1 >= 1.0] [.t compare 1.1 >= 1.1] [.t compare 1.1 >= 1.2] } {1 1 0} test text-6.9 {TextWidgetCmd procedure, "compare" option} { list [.t compare 1.1 > 1.0] [.t compare 1.1 > 1.1] [.t compare 1.1 > 1.2] } {1 0 0} test text-6.10 {TextWidgetCmd procedure, "compare" option} { list [.t com 1.1 != 1.0] [.t compare 1.1 != 1.1] [.t compare 1.1 != 1.2] } {1 0 1} test text-6.11 {TextWidgetCmd procedure, "compare" option} { list [catch {.t compare 1.0 <x 1.2} msg] $msg } {1 {bad comparison operator "<x": must be <, <=, ==, >=, >, or !=}} test text-6.12 {TextWidgetCmd procedure, "compare" option} { list [catch {.t compare 1.0 >> 1.2} msg] $msg } {1 {bad comparison operator ">>": must be <, <=, ==, >=, >, or !=}} test text-6.13 {TextWidgetCmd procedure, "compare" option} { list [catch {.t compare 1.0 z 1.2} msg] $msg } {1 {bad comparison operator "z": must be <, <=, ==, >=, >, or !=}} test text-6.14 {TextWidgetCmd procedure, "compare" option} { list [catch {.t co 1.0 z 1.2} msg] $msg } {1 {ambiguous option "co": must be bbox, cget, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, peer, replace, scan, search, see, tag, window, xview, or yview}} # "configure" option is already covered above test text-7.1 {TextWidgetCmd procedure, "debug" option} { list [catch {.t debug 0 1} msg] $msg } {1 {wrong # args: should be ".t debug boolean"}} test text-7.2 {TextWidgetCmd procedure, "debug" option} { list [catch {.t de 0 1} msg] $msg } {1 {ambiguous option "de": must be bbox, cget, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, peer, replace, scan, search, see, tag, window, xview, or yview}} test text-7.3 {TextWidgetCmd procedure, "debug" option} { .t debug true .t deb } 1 test text-7.4 {TextWidgetCmd procedure, "debug" option} { .t debug false .t debug } 0 catch {.t debug} test text-8.1 {TextWidgetCmd procedure, "delete" option} { list [catch {.t delete} msg] $msg } {1 {wrong # args: should be ".t delete index1 ?index2 ...?"}} test text-8.2 {TextWidgetCmd procedure, "delete" option} { list [catch {.t delete a b c} msg] $msg } {1 {bad text index "a"}} test text-8.3 {TextWidgetCmd procedure, "delete" option} { list [catch {.t delete @x 2.2} msg] $msg } {1 {bad text index "@x"}} test text-8.4 {TextWidgetCmd procedure, "delete" option} { list [catch {.t delete 2.3 @y} msg] $msg } {1 {bad text index "@y"}} test text-8.5 {TextWidgetCmd procedure, "delete" option} { .t configure -state disabled .t delete 2.3 .t g 2.0 2.end } abcdefghijklm .t configure -state normal test text-8.6 {TextWidgetCmd procedure, "delete" option} { .t delete 2.3 .t get 2.0 2.end } abcefghijklm test text-8.7 {TextWidgetCmd procedure, "delete" option} { .t delete 2.1 2.3 .t get 2.0 2.end } aefghijklm test text-8.8 {TextWidgetCmd procedure, "delete" option} { # All indices are checked before we actually delete anything list [catch {.t delete 2.1 2.3 foo} msg] $msg \ [.t get 2.0 2.end] } {1 {bad text index "foo"} aefghijklm} set prevtext [.t get 1.0 end-1c] test text-8.9 {TextWidgetCmd procedure, "delete" option} { # auto-forward one byte if the last "pair" is just one .t delete 1.0 end; .t insert 1.0 "foo\nabcdefghijklm" .t delete 2.1 2.3 2.3 .t get 1.0 end-1c } foo\naefghijklm test text-8.10 {TextWidgetCmd procedure, "delete" option} { # all indices will be ordered before deletion .t delete 1.0 end; .t insert 1.0 "foo\nabcdefghijklm" .t delete 2.0 2.3 2.7 2.9 2.4 .t get 1.0 end-1c } foo\ndfgjklm test text-8.11 {TextWidgetCmd procedure, "delete" option} { # and check again with even pairs .t delete 1.0 end; .t insert 1.0 "foo\nabcdefghijklm" .t delete 2.0 2.2 2.7 2.9 2.4 2.5 .t get 1.0 end-1c } foo\ncdfgjklm test text-8.12 {TextWidgetCmd procedure, "delete" option} { # we should get the longest range on equal start indices .t delete 1.0 end; .t insert 1.0 "foo\nabcdefghijklm" .t delete 2.0 2.2 2.0 2.5 2.0 2.3 2.8 2.7 .t get 1.0 end-1c } foo\nfghijklm test text-8.13 {TextWidgetCmd procedure, "delete" option} { # we should get the longest range on equal start indices .t delete 1.0 end; .t insert 1.0 "foo\nabcdefghijklm" .t delete 2.0 2.2 1.2 2.6 2.0 2.5 .t get 1.0 end-1c } foghijklm test text-8.14 {TextWidgetCmd procedure, "delete" option} { # we should get the longest range on equal start indices .t delete 1.0 end; .t insert 1.0 "foo\nabcdefghijklm" .t delete 2.0 2.2 2.0 2.5 1.1 2.3 2.8 2.7 .t get 1.0 end-1c } ffghijklm test text-8.15 {TextWidgetCmd procedure, "delete" option} { # we should get the watch for overlapping ranges - they should # essentially be merged into one span. .t delete 1.0 end; .t insert 1.0 "foo\nabcdefghijklm" .t delete 2.0 2.6 2.2 2.8 .t get 1.0 end-1c } foo\nijklm test text-8.16 {TextWidgetCmd procedure, "delete" option} { # we should get the watch for overlapping ranges - they should # essentially be merged into one span. .t delete 1.0 end; .t insert 1.0 "foo\nabcdefghijklm" .t delete 2.0 2.6 2.2 2.4 .t get 1.0 end-1c } foo\nghijklm .t delete 1.0 end; .t insert 1.0 $prevtext test text-8.17 {TextWidgetCmd procedure, "replace" option} { list [catch {.t replace 1.3 2.3} err] $err } {1 {wrong # args: should be ".t replace index1 index2 chars ?tagList chars tagList ...?"}} test text-8.18 {TextWidgetCmd procedure, "replace" option} { list [catch {.t replace 3.1 2.3 foo} err] $err } {1 {Index "2.3" before "3.1" in the text}} test text-8.19 {TextWidgetCmd procedure, "replace" option} { list [catch {.t replace 2.1 2.3 foo} err] $err } {0 {}} .t delete 1.0 end; .t insert 1.0 $prevtext test text-8.20 {TextWidgetCmd procedure, "replace" option with undo} { .t configure -undo 0 .t configure -undo 1 # Ensure it is treated as a single undo action .t replace 2.1 2.3 foo .t edit undo .t configure -undo 0 string equal [.t get 1.0 end-1c] $prevtext } {1} test text-8.21 {TextWidgetCmd procedure, "replace" option with undo} { .t configure -undo 0 .t configure -undo 1 .t replace 2.1 2.3 foo # Ensure we can override a text widget and intercept undo # actions. If in the future a different mechanism is available # to do this, then we should be able to change this test. The # behaviour tested for here is not, strictly speaking, documented. rename .t test.t set res {} proc .t {args} { lappend ::res $args ; uplevel 1 test.t $args } .t edit undo rename .t {} rename test.t .t .t configure -undo 0 set res } {{edit undo} {delete 2.1 2.4} {mark set insert 2.1} {see insert} {insert 2.1 ef} {mark set insert 2.3} {see insert}} test text-8.22 {TextWidgetCmd procedure, "replace" option with undo} { .t configure -undo 0 .t configure -undo 1 # Ensure that undo (even composite undo like 'replace') # works when the widget shows nothing useful. .t replace 2.1 2.3 foo .t configure -start 1 -end 1 .t edit undo .t configure -start {} -end {} .t configure -undo 0 if {![string equal [.t get 1.0 end-1c] $prevtext]} { set res [list [.t get 1.0 end-1c] ne $prevtext] } else { set res 1 } } {1} .t delete 1.0 end; .t insert 1.0 $prevtext test text-8.23 {TextWidgetCmd procedure, "replace" option with peers, undo} { .t configure -undo 0 .t configure -undo 1 .t peer create .tt -undo 1 # Ensure that undo (even composite undo like 'replace') # works when the the event took place in one peer, which # is then deleted, before the undo takes place in another peer. .tt replace 2.1 2.3 foo .tt configure -start 1 -end 1 destroy .tt .t edit undo .t configure -start {} -end {} .t configure -undo 0 if {![string equal [.t get 1.0 end-1c] $prevtext]} { set res [list [.t get 1.0 end-1c] ne $prevtext] } else { set res 1 } } {1} .t delete 1.0 end; .t insert 1.0 $prevtext test text-8.24 {TextWidgetCmd procedure, "replace" option with peers, undo} { .t configure -undo 0 .t configure -undo 1 .t peer create .tt -undo 1 # Ensure that undo (even composite undo like 'replace') # works when the the event took place in one peer, which # is then deleted, before the undo takes place in another peer # which isn't showing everything. .tt replace 2.1 2.3 foo set res [.tt get 2.1 2.4] .tt configure -start 1 -end 1 destroy .tt .t configure -start 3 -end 4 # msg will actually be set to a silently ignored error message here, # (that the .tt command doesn't exist), but that is not important. lappend res [catch {.t edit undo} msg] .t configure -undo 0 .t configure -start {} -end {} if {![string equal [.t get 1.0 end-1c] $prevtext]} { lappend res [list [.t get 1.0 end-1c] ne $prevtext] } else { lappend res 1 } } {foo 0 1} test text-8.25 {TextWidgetCmd procedure, "replace" option crash} -setup { destroy .tt } -body { scintilla .tt .tt insert 0.0 foo\n .tt replace end-1l end bar } -cleanup { destroy .tt } -result {} .t delete 1.0 end; .t insert 1.0 $prevtext test text-9.1 {TextWidgetCmd procedure, "get" option} { list [catch {.t get} msg] $msg } {1 {wrong # args: should be ".t get ?-displaychars? ?--? index1 ?index2 ...?"}} test text-9.2 {TextWidgetCmd procedure, "get" option} { list [catch {.t get a b c} msg] $msg } {1 {bad text index "a"}} test text-9.3 {TextWidgetCmd procedure, "get" option} { list [catch {.t get @q 3.1} msg] $msg } {1 {bad text index "@q"}} test text-9.4 {TextWidgetCmd procedure, "get" option} { list [catch {.t get 3.1 @r} msg] $msg } {1 {bad text index "@r"}} test text-9.5 {TextWidgetCmd procedure, "get" option} { .t get 5.7 5.3 } {} test text-9.6 {TextWidgetCmd procedure, "get" option} { .t get 5.3 5.5 } { G} test text-9.7 {TextWidgetCmd procedure, "get" option} { .t get 5.3 end } { GIrl .#@? x_yz !@#$% Line 7 } .t mark set a 5.3 .t mark set b 5.3 .t mark set c 5.5 test text-9.8 {TextWidgetCmd procedure, "get" option} { .t get 5.2 5.7 } {y GIr} test text-9.9 {TextWidgetCmd procedure, "get" option} { .t get 5.2 } {y} test text-9.10 {TextWidgetCmd procedure, "get" option} { .t get 5.2 5.4 } {y } test text-9.11 {TextWidgetCmd procedure, "get" option} { .t get 5.2 5.4 5.4 } {{y } G} test text-9.12 {TextWidgetCmd procedure, "get" option} { .t get 5.2 5.4 5.4 5.5 } {{y } G} test text-9.13 {TextWidgetCmd procedure, "get" option} { .t get 5.2 5.4 5.5 "5.5+5c" } {{y } {Irl .}} test text-9.14 {TextWidgetCmd procedure, "get" option} { .t get 5.2 5.4 5.4 5.5 end-3c } {{y } G { }} test text-9.15 {TextWidgetCmd procedure, "get" option} { .t get 5.2 5.4 5.4 5.5 end-3c end } {{y } G { 7 }} test text-9.16 {TextWidgetCmd procedure, "get" option} { .t get 5.2 5.3 5.4 5.3 } {y} test text-9.17 {TextWidgetCmd procedure, "get" option} { .t index "5.2 +3 indices" } {5.5} test text-9.17a {TextWidgetCmd procedure, "get" option} { .t index "5.2 +3chars" } {5.5} test text-9.17b {TextWidgetCmd procedure, "get" option} { .t index "5.2 +3displayindices" } {5.5} catch {.t tag configure elide -elide 1} .t tag add elide 5.2 5.4 test text-9.18 {TextWidgetCmd procedure, "get" option} { list [catch {.t get 5.2 5.4 5.5 foo} msg] $msg } {1 {bad text index "foo"}} test text-9.19 {TextWidgetCmd procedure, "get" option} { .t get 5.2 5.4 5.4 5.5 end-3c end } {{y } G { 7 }} test text-9.20 {TextWidgetCmd procedure, "get" option} { .t get -displaychars 5.2 5.4 5.4 5.5 end-3c end } {{} G { 7 }} test text-9.21 {TextWidgetCmd procedure, "get" option} { list [.t index "5.1 +4indices"] [.t index "5.1+4d indices"] } {5.5 5.7} test text-9.22 {TextWidgetCmd procedure, "get" option} { list [.t index "5.1 +4a chars"] [.t index "5.1+4d chars"] } {5.5 5.7} test text-9.23 {TextWidgetCmd procedure, "get" option} { list [.t index "5.5 -4indices"] [.t index "5.7-4d indices"] } {5.1 5.1} test text-9.24 {TextWidgetCmd procedure, "get" option} { list [.t index "5.5 -4a chars"] [.t index "5.7-4d chars"] } {5.1 5.1} catch {.t window create 5.4} test text-9.25 {TextWidgetCmd procedure, "get" option} { list [.t index "5.1 +4indices"] [.t index "5.1+4d indices"] } {5.5 5.7} test text-9.25a {TextWidgetCmd procedure, "get" option} { list [.t index "5.1 +4a chars"] [.t index "5.1+4d chars"] } {5.6 5.8} test text-9.26 {TextWidgetCmd procedure, "get" option} { list [.t index "5.5 -4indices"] [.t index "5.7-4d indices"] } {5.1 5.1} test text-9.26a {TextWidgetCmd procedure, "get" option} { list [.t index "5.6 -4a chars"] [.t index "5.8-4d chars"] } {5.1 5.1} .t delete 5.4 .t tag add elide 5.5 5.6 test text-9.27 {TextWidgetCmd procedure, "get" option} { .t get -displaychars 5.2 5.8 } {Grl} .t tag delete elide .t mark unset a .t mark unset b .t mark unset c test text-9.2.1 {TextWidgetCmd procedure, "count" option} { list [catch {.t count} msg] $msg } {1 {wrong # args: should be ".t count ?options? index1 index2"}} test text-9.2.2.1 {TextWidgetCmd procedure, "count" option} { list [catch {.t count blah 1.0 2.0} msg] $msg } {1 {bad option "blah" must be -chars, -displaychars, -displayindices, -displaylines, -indices, -lines, -update, -xpixels, or -ypixels}} test text-9.2.2 {TextWidgetCmd procedure, "count" option} { list [catch {.t count a b} msg] $msg } {1 {bad text index "a"}} test text-9.2.3 {TextWidgetCmd procedure, "count" option} { list [catch {.t count @q 3.1} msg] $msg } {1 {bad text index "@q"}} test text-9.2.4 {TextWidgetCmd procedure, "count" option} { list [catch {.t count 3.1 @r} msg] $msg } {1 {bad text index "@r"}} test text-9.2.5 {TextWidgetCmd procedure, "count" option} { .t count 5.7 5.3 } {-4} test text-9.2.6 {TextWidgetCmd procedure, "count" option} { .t count 5.3 5.5 } {2} test text-9.2.7 {TextWidgetCmd procedure, "count" option} { .t count 5.3 end } {29} .t mark set a 5.3 .t mark set b 5.3 .t mark set c 5.5 test text-9.2.8 {TextWidgetCmd procedure, "count" option} { .t count 5.2 5.7 } {5} test text-9.2.9 {TextWidgetCmd procedure, "count" option} { .t count 5.2 5.3 } {1} test text-9.2.10 {TextWidgetCmd procedure, "count" option} { .t count 5.2 5.4 } {2} test text-9.2.17 {TextWidgetCmd procedure, "count" option} { list [catch {.t count 5.2 foo} msg] $msg } {1 {bad text index "foo"}} catch {.t tag configure elide -elide 1} .t tag add elide 2.2 3.4 .t tag add elide 4.0 4.1 test text-9.2.18 {TextWidgetCmd procedure, "count" option} { .t count -displayindices 2.0 3.0 } {2} test text-9.2.19 {TextWidgetCmd procedure, "count" option} { .t count -displayindices 2.2 3.0 } {0} test text-9.2.20 {TextWidgetCmd procedure, "count" option} { .t count -displayindices 2.0 4.2 } {5} # Create one visible and one invisible window frame .t.w1 frame .t.w2 .t mark set a 2.2 # Creating this window here means that the elidden text # now starts at 2.3, but 'a' is automatically moved to 2.3 catch { .t window create 2.1 -window .t.w1 .t window create 3.1 -window .t.w2 } test text-9.2.21 {TextWidgetCmd procedure, "count" option} { .t count -displayindices 2.0 3.0 } {3} test text-9.2.22 {TextWidgetCmd procedure, "count" option} { .t count -displayindices 2.2 3.0 } {1} test text-9.2.23 {TextWidgetCmd procedure, "count" option} { .t count -displayindices a 3.0 } {0} test text-9.2.24 {TextWidgetCmd procedure, "count" option} { .t count -displayindices 2.0 4.2 } {6} test text-9.2.25 {TextWidgetCmd procedure, "count" option} { .t count -displaychars 2.0 3.0 } {2} test text-9.2.26 {TextWidgetCmd procedure, "count" option} { .t count -displaychars 2.2 3.0 } {1} test text-9.2.27 {TextWidgetCmd procedure, "count" option} { .t count -displaychars a 3.0 } {0} test text-9.2.28 {TextWidgetCmd procedure, "count" option} { .t count -displaychars 2.0 4.2 } {5} test text-9.2.29 {TextWidgetCmd procedure, "count" option} { list [.t count -indices 2.2 3.0] [.t count 2.2 3.0] } {10 10} test text-9.2.30 {TextWidgetCmd procedure, "count" option} { list [.t count -indices a 3.0] [.t count a 3.0] } {9 9} test text-9.2.31 {TextWidgetCmd procedure, "count" option} { .t count -indices 2.0 4.2 } {21} test text-9.2.32 {TextWidgetCmd procedure, "count" option} { .t count -chars 2.2 3.0 } {10} test text-9.2.33 {TextWidgetCmd procedure, "count" option} { .t count -chars a 3.0 } {9} test text-9.2.34 {TextWidgetCmd procedure, "count" option} { .t count -chars 2.0 4.2 } {19} destroy .t.w1 destroy .t.w2 set current [.t get 1.0 end-1c] .t delete 1.0 end .t insert end [string repeat "abcde " 50]\n .t insert end [string repeat "fghij " 50]\n .t insert end [string repeat "klmno " 50] test text-9.2.35 {TextWidgetCmd procedure, "count" option} { .t count -lines 1.0 end } {3} test text-9.2.36 {TextWidgetCmd procedure, "count" option} { .t count -lines end 1.0 } {-3} test text-9.2.37 {TextWidgetCmd procedure, "count" option} { list [catch {.t count -lines 1.0 2.0 3.0} res] $res } {1 {bad option "1.0" must be -chars, -displaychars, -displayindices, -displaylines, -indices, -lines, -update, -xpixels, or -ypixels}} test text-9.2.38 {TextWidgetCmd procedure, "count" option} { .t count -lines end end } {0} test text-9.2.39 {TextWidgetCmd procedure, "count" option} { .t count -lines 1.5 2.5 } {1} test text-9.2.40 {TextWidgetCmd procedure, "count" option} { .t count -lines 2.5 "2.5 lineend" } {0} test text-9.2.41 {TextWidgetCmd procedure, "count" option} { .t count -lines 2.7 "1.0 lineend" } {-1} test text-9.2.42 {TextWidgetCmd procedure, "count" option} { set old_wrap [.t cget -wrap] .t configure -wrap none set res [.t count -displaylines 1.0 end] .t configure -wrap $old_wrap set res } {3} test text-9.2.43 {TextWidgetCmd procedure, "count" option} { .t count -lines -chars -indices -displaylines 1.0 end } {3 903 903 45} catch {.t configure -wrap none} # Newer tags are higher priority catch { .t tag configure elide1 -elide 0 .t tag configure elide2 -elide 1 .t tag configure elide3 -elide 0 .t tag configure elide4 -elide 1 } test text-0.2.44.0 {counting with tag priority eliding} { .t delete 1.0 end .t insert end "hello" list [.t count -displaychars 1.0 1.0] \ [.t count -displaychars 1.0 1.1] \ [.t count -displaychars 1.0 1.2] \ [.t count -displaychars 1.0 1.3] \ [.t count -displaychars 1.0 1.4] \ [.t count -displaychars 1.0 1.5] \ [.t count -displaychars 1.0 1.6] \ [.t count -displaychars 1.0 2.6] \ } {0 1 2 3 4 5 5 6} test text-0.2.44 {counting with tag priority eliding} { .t delete 1.0 end .t insert end "hello" .t tag add elide1 1.2 1.4 .t count -displaychars 1.0 1.5 } {5} test text-0.2.45 {counting with tag priority eliding} { .t delete 1.0 end .t insert end "hello" .t tag add elide2 1.2 1.4 .t count -displaychars 1.0 1.5 } {3} test text-0.2.46 {counting with tag priority eliding} { set res {} .t delete 1.0 end .t insert end "hello" .t tag add elide2 1.2 1.4 .t tag add elide1 1.2 1.4 lappend res [.t count -displaychars 1.0 1.5] .t delete 1.0 end .t insert end "hello" .t tag add elide1 1.2 1.4 .t tag add elide2 1.2 1.4 lappend res [.t count -displaychars 1.0 1.5] } {3 3} test text-0.2.47 {counting with tag priority eliding} { set res {} .t delete 1.0 end .t insert end "hello" .t tag add elide2 1.2 1.4 .t tag add elide3 1.2 1.4 lappend res [.t count -displaychars 1.0 1.5] .t delete 1.0 end .t insert end "hello" .t tag add elide3 1.2 1.4 .t tag add elide3 1.2 1.4 lappend res [.t count -displaychars 1.0 1.5] } {5 5} test text-0.2.48 {counting with tag priority eliding} { set res {} .t delete 1.0 end .t insert end "hello" .t tag add elide2 1.2 1.4 .t tag add elide3 1.2 1.4 .t tag add elide4 1.2 1.4 .t tag add elide1 1.2 1.4 lappend res [.t count -displaychars 1.0 1.5] .t delete 1.0 end .t insert end "hello" .t tag add elide1 1.2 1.4 .t tag add elide4 1.2 1.4 .t tag add elide2 1.2 1.4 .t tag add elide3 1.2 1.4 lappend res [.t count -displaychars 1.0 1.5] } {3 3} test text-0.2.49 {counting with tag priority eliding} { set res {} .t delete 1.0 end .t insert end "hello" .t tag add elide2 1.2 1.4 .t tag add elide3 1.2 1.4 .t tag add elide1 1.2 1.4 lappend res [.t count -displaychars 1.0 1.5] .t delete 1.0 end .t insert end "hello" .t tag add elide1 1.2 1.4 .t tag add elide2 1.2 1.4 .t tag add elide3 1.2 1.4 lappend res [.t count -displaychars 1.0 1.5] } {5 5} test text-0.2.50 {counting with tag priority eliding} { set res {} .t delete 1.0 end .t insert end "hello" .t tag add elide2 1.0 1.5 .t tag add elide1 1.2 1.4 lappend res [.t count -displaychars 1.0 1.5] lappend res [.t count -displaychars 1.1 1.5] lappend res [.t count -displaychars 1.2 1.5] lappend res [.t count -displaychars 1.3 1.5] .t delete 1.0 end .t insert end "hello" .t tag add elide1 1.0 1.5 .t tag add elide2 1.2 1.4 lappend res [.t count -displaychars 1.0 1.5] lappend res [.t count -displaychars 1.1 1.5] lappend res [.t count -displaychars 1.2 1.5] lappend res [.t count -displaychars 1.3 1.5] } {0 0 0 0 3 2 1 1} test text-0.2.51 {counting with tag priority eliding} { set res {} .t delete 1.0 end .t tag configure WELCOME -elide 1 .t tag configure SYSTEM -elide 0 .t tag configure TRAFFIC -elide 1 .t insert end "\n" {SYSTEM TRAFFIC} .t insert end "\n" WELCOME lappend res [.t count -displaychars 1.0 end] lappend res [.t count -displaychars 1.0 end-1c] lappend res [.t count -displaychars 1.0 1.2] lappend res [.t count -displaychars 2.0 end] lappend res [.t count -displaychars 2.0 end-1c] lappend res [.t index "1.0 +1 indices"] lappend res [.t index "1.0 +1 display indices"] lappend res [.t index "1.0 +1 display chars"] lappend res [.t index end] lappend res [.t index "end -1 indices"] lappend res [.t index "end -1 display indices"] lappend res [.t index "end -1 display chars"] lappend res [.t index "end -2 indices"] lappend res [.t index "end -2 display indices"] lappend res [.t index "end -2 display chars"] } {1 0 0 1 0 2.0 4.0 4.0 4.0 3.0 3.0 3.0 2.0 1.0 1.0} .t delete 1.0 end .t insert end $current unset current test text-10.1 {TextWidgetCmd procedure, "index" option} { list [catch {.t index} msg] $msg } {1 {wrong # args: should be ".t index index"}} test text-10.2 {TextWidgetCmd procedure, "index" option} { list [catch {.t ind a b} msg] $msg } {1 {wrong # args: should be ".t index index"}} test text-10.3 {TextWidgetCmd procedure, "index" option} { list [catch {.t in a b} msg] $msg } {1 {ambiguous option "in": must be bbox, cget, compare, configure, count, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, peer, replace, scan, search, see, tag, window, xview, or yview}} test text-10.4 {TextWidgetCmd procedure, "index" option} { list [catch {.t index @xyz} msg] $msg } {1 {bad text index "@xyz"}} test text-10.5 {TextWidgetCmd procedure, "index" option} { .t index 1.2 } 1.2 test text-11.1 {TextWidgetCmd procedure, "insert" option} { list [catch {.t insert 1.2} msg] $msg } {1 {wrong # args: should be ".t insert index chars ?tagList chars tagList ...?"}} test text-11.2 {TextWidgetCmd procedure, "insert" option} { .t config -state disabled .t insert 1.2 xyzzy .t get 1.0 1.end } {Line 1} .t config -state normal test text-11.3 {TextWidgetCmd procedure, "insert" option} { .t insert 1.2 xyzzy .t get 1.0 1.end } {Lixyzzyne 1} test text-11.4 {TextWidgetCmd procedure, "insert" option} { .t delete 1.0 end .t insert 1.0 "Sample text" x .t tag ranges x } {1.0 1.11} test text-11.5 {TextWidgetCmd procedure, "insert" option} { .t delete 1.0 end .t insert 1.0 "Sample text" x .t insert 1.2 "XYZ" y list [.t tag ranges x] [.t tag ranges y] } {{1.0 1.2 1.5 1.14} {1.2 1.5}} test text-11.6 {TextWidgetCmd procedure, "insert" option} { .t delete 1.0 end .t insert 1.0 "Sample text" {x y z} list [.t tag ranges x] [.t tag ranges y] [.t tag ranges z] } {{1.0 1.11} {1.0 1.11} {1.0 1.11}} test text-11.7 {TextWidgetCmd procedure, "insert" option} { .t delete 1.0 end .t insert 1.0 "Sample text" {x y z} .t insert 1.3 "A" {a b z} list [.t tag ranges a] [.t tag ranges b] [.t tag ranges x] [.t tag ranges y] [.t tag ranges z] } {{1.3 1.4} {1.3 1.4} {1.0 1.3 1.4 1.12} {1.0 1.3 1.4 1.12} {1.0 1.12}} test text-11.8 {TextWidgetCmd procedure, "insert" option} { .t delete 1.0 end list [catch {.t insert 1.0 "Sample text" "a \{b"} msg] $msg } {1 {unmatched open brace in list}} test text-11.9 {TextWidgetCmd procedure, "insert" option} { .t delete 1.0 end .t insert 1.0 "First" bold " " {} second "x y z" " third" list [.t get 1.0 1.end] [.t tag ranges bold] [.t tag ranges x] \ [.t tag ranges y] [.t tag ranges z] } {{First second third} {1.0 1.5} {1.6 1.12} {1.6 1.12} {1.6 1.12}} test text-11.10 {TextWidgetCmd procedure, "insert" option} { .t delete 1.0 end .t insert 1.0 "First" bold " second" silly list [.t get 1.0 1.end] [.t tag ranges bold] [.t tag ranges silly] } {{First second} {1.0 1.5} {1.5 1.12}} # Edit, mark, scan, search, see, tag, window, xview, and yview actions are tested elsewhere. test text-12.1 {ConfigureText procedure} { list [catch {.t2 configure -state foobar} msg] $msg } {1 {bad state "foobar": must be disabled or normal}} test text-12.2 {ConfigureText procedure} { .t2 configure -spacing1 -2 -spacing2 1 -spacing3 1 list [.t2 cget -spacing1] [.t2 cget -spacing2] [.t2 cget -spacing3] } {0 1 1} test text-12.3 {ConfigureText procedure} { .t2 configure -spacing1 1 -spacing2 -1 -spacing3 1 list [.t2 cget -spacing1] [.t2 cget -spacing2] [.t2 cget -spacing3] } {1 0 1} test text-12.4 {ConfigureText procedure} { .t2 configure -spacing1 1 -spacing2 1 -spacing3 -3 list [.t2 cget -spacing1] [.t2 cget -spacing2] [.t2 cget -spacing3] } {1 1 0} test text-12.5 {ConfigureText procedure} { set x [list [catch {.t2 configure -tabs {30 foo}} msg] $msg $errorInfo] .t2 configure -tabs {10 20 30} set x } {1 {bad tab alignment "foo": must be left, right, center, or numeric} {bad tab alignment "foo": must be left, right, center, or numeric (while processing -tabs option) invoked from within ".t2 configure -tabs {30 foo}"}} test text-12.6 {ConfigureText procedure} { .t2 configure -tabs {10 20 30} .t2 configure -tabs {} .t2 cget -tabs } {} test text-12.7 {ConfigureText procedure} { list [catch {.t2 configure -wrap bogus} msg] $msg } {1 {bad wrap "bogus": must be char, none, or word}} test text-12.8 {ConfigureText procedure} { .t2 configure -selectborderwidth 17 -selectforeground #332211 \ -selectbackground #abc list [lindex [.t2 tag config sel -borderwidth] 4] \ [lindex [.t2 tag config sel -foreground] 4] \ [lindex [.t2 tag config sel -background] 4] } {17 #332211 #abc} test text-12.9 {ConfigureText procedure} { .t2 configure -selectborderwidth {} .t2 tag cget sel -borderwidth } {} test text-12.10 {ConfigureText procedure} { list [catch {.t2 configure -selectborderwidth foo} msg] $msg } {1 {bad screen distance "foo"}} test text-12.11 {ConfigureText procedure} { catch {destroy .t2} .t.e select to 2 scintilla .t2 -exportselection 1 selection get } {ab} test text-12.12 {ConfigureText procedure} { catch {destroy .t2} .t.e select to 2 scintilla .t2 -exportselection 0 .t2 insert insert 1234657890 .t2 tag add sel 1.0 1.4 selection get } {ab} test text-12.13 {ConfigureText procedure} { catch {destroy .t2} .t.e select to 1 scintilla .t2 -exportselection 1 .t2 insert insert 1234657890 .t2 tag add sel 1.0 1.4 selection get } {1234} test text-12.14 {ConfigureText procedure} { catch {destroy .t2} .t.e select to 1 scintilla .t2 -exportselection 0 .t2 insert insert 1234657890 .t2 tag add sel 1.0 1.4 .t2 configure -exportselection 1 selection get } {1234} test text-12.15 {ConfigureText procedure} { catch {destroy .t2} scintilla .t2 -exportselection 1 .t2 insert insert 1234657890 .t2 tag add sel 1.0 1.4 set result [selection get] .t2 configure -exportselection 0 lappend result [catch {selection get} msg] $msg } {1234 1 {PRIMARY selection doesn't exist or form "STRING" not defined}} test text-12.16 {ConfigureText procedure} {fonts} { # This test is non-portable because the window size will vary depending # on the font size, which can vary. catch {destroy .t2} toplevel .t2 scintilla .t2.t -width 20 -height 10 pack append .t2 .t2.t top wm geometry .t2 +0+0 update wm geometry .t2 } {150x140+0+0} test text-12.17 {ConfigureText procedure} { # This test was failing Windows because the title bar on .t2 # was a certain minimum size and it was interfering with the size # requested by the -setgrid. The "overrideredirect" gets rid of the # titlebar so the toplevel can shrink to the appropriate size. catch {destroy .t2} toplevel .t2 wm overrideredirect .t2 1 scintilla .t2.t -width 20 -height 10 -setgrid 1 pack append .t2 .t2.t top wm geometry .t2 +0+0 update wm geometry .t2 } {20x10+0+0} test text-12.18 {ConfigureText procedure} { # This test was failing on Windows because the title bar on .t2 # was a certain minimum size and it was interfering with the size # requested by the -setgrid. The "overrideredirect" gets rid of the # titlebar so the toplevel can shrink to the appropriate size. catch {destroy .t2} toplevel .t2 wm overrideredirect .t2 1 scintilla .t2.t -width 20 -height 10 -setgrid 1 pack append .t2 .t2.t top wm geometry .t2 +0+0 update set result [wm geometry .t2] wm geometry .t2 15x8 update lappend result [wm geometry .t2] .t2.t configure -wrap word update lappend result [wm geometry .t2] } {20x10+0+0 15x8+0+0 15x8+0+0} test text-13.1 {TextWorldChanged procedure, spacing options} fonts { catch {destroy .t2} scintilla .t2 -width 20 -height 10 set result [winfo reqheight .t2] .t2 configure -spacing1 2 lappend result [winfo reqheight .t2] .t2 configure -spacing3 1 lappend result [winfo reqheight .t2] .t2 configure -spacing1 0 lappend result [winfo reqheight .t2] } {140 160 170 150} test text-14.1 {TextEventProc procedure} { scintilla .tx1 -bg #543210 rename .tx1 .tx2 set x {} lappend x [winfo exists .tx1] lappend x [.tx2 cget -bg] destroy .tx1 lappend x [info command .tx*] [winfo exists .tx1] [winfo exists .tx2] } {1 #543210 {} 0 0} test text-15.1 {TextCmdDeletedProc procedure} { scintilla .tx1 rename .tx1 {} list [info command .tx*] [winfo exists .tx1] } {{} 0} test text-15.2 {TextCmdDeletedProc procedure, disabling -setgrid} fonts { catch {destroy .top} toplevel .top wm geom .top +0+0 scintilla .top.t -setgrid 1 -width 20 -height 10 pack .top.t update set x [wm geometry .top] rename .top.t {} update lappend x [wm geometry .top] destroy .top set x } {20x10+0+0 150x140+0+0} test text-16.1 {InsertChars procedure} { catch {destroy .t2} scintilla .t2 .t2 insert 2.0 abcd\n .t2 get 1.0 end } {abcd } test text-16.2 {InsertChars procedure} { catch {destroy .t2} scintilla .t2 .t2 insert 1.0 abcd\n .t2 insert end 123\n .t2 get 1.0 end } {abcd 123 } test text-16.3 {InsertChars procedure} { catch {destroy .t2} scintilla .t2 .t2 insert 1.0 abcd\n .t2 insert 10.0 123 .t2 get 1.0 end } {abcd 123 } test text-16.4 {InsertChars procedure, inserting on top visible line} { catch {destroy .t2} scintilla .t2 -width 20 -height 4 -wrap word pack .t2 .t2 insert insert "Now is the time for all great men to come to the " .t2 insert insert "aid of their party.\n" .t2 insert insert "Now is the time for all great men.\n" .t2 see end update .t2 insert 1.0 "Short\n" .t2 index @0,0 } {2.56} test text-16.5 {InsertChars procedure, inserting on top visible line} { catch {destroy .t2} scintilla .t2 -width 20 -height 4 -wrap word pack .t2 .t2 insert insert "Now is the time for all great men to come to the " .t2 insert insert "aid of their party.\n" .t2 insert insert "Now is the time for all great men.\n" .t2 see end update .t2 insert 1.55 "Short\n" .t2 index @0,0 } {2.0} test text-16.6 {InsertChars procedure, inserting on top visible line} { catch {destroy .t2} scintilla .t2 -width 20 -height 4 -wrap word pack .t2 .t2 insert insert "Now is the time for all great men to come to the " .t2 insert insert "aid of their party.\n" .t2 insert insert "Now is the time for all great men.\n" .t2 see end update .t2 insert 1.56 "Short\n" .t2 index @0,0 } {1.56} test text-16.7 {InsertChars procedure, inserting on top visible line} { catch {destroy .t2} scintilla .t2 -width 20 -height 4 -wrap word pack .t2 .t2 insert insert "Now is the time for all great men to come to the " .t2 insert insert "aid of their party.\n" .t2 insert insert "Now is the time for all great men.\n" .t2 see end update .t2 insert 1.57 "Short\n" .t2 index @0,0 } {1.56} catch {destroy .t2} proc setup {} { .t delete 1.0 end .t insert 1.0 "Line 1 abcde 12345 Line 4" } .t delete 1.0 end test text-17.1 {DeleteChars procedure} { .t get 1.0 end } { } test text-17.2 {DeleteChars procedure} { list [catch {.t delete foobar} msg] $msg } {1 {bad text index "foobar"}} test text-17.3 {DeleteChars procedure} { list [catch {.t delete 1.0 lousy} msg] $msg } {1 {bad text index "lousy"}} test text-17.4 {DeleteChars procedure} { setup .t delete 2.1 .t get 1.0 end } {Line 1 acde 12345 Line 4 } test text-17.5 {DeleteChars procedure} { setup .t delete 2.3 .t get 1.0 end } {Line 1 abce 12345 Line 4 } test text-17.6 {DeleteChars procedure} { setup .t delete 2.end .t get 1.0 end } {Line 1 abcde12345 Line 4 } test text-17.7 {DeleteChars procedure} { setup .t tag add sel 4.2 end .t delete 4.2 end list [.t tag ranges sel] [.t get 1.0 end] } {{} {Line 1 abcde 12345 Li }} test text-17.8 {DeleteChars procedure} { setup .t tag add sel 1.0 end .t delete 4.0 end list [.t tag ranges sel] [.t get 1.0 end] } {{1.0 3.5} {Line 1 abcde 12345 }} test text-17.9 {DeleteChars procedure} { setup .t delete 2.2 2.2 .t get 1.0 end } {Line 1 abcde 12345 Line 4 } test text-17.10 {DeleteChars procedure} { setup .t delete 2.3 2.1 .t get 1.0 end } {Line 1 abcde 12345 Line 4 } test text-17.11 {DeleteChars procedure} { catch {destroy .t2} toplevel .t2 scintilla .t2.t -width 20 -height 5 pack append .t2 .t2.t top wm geometry .t2 +0+0 .t2.t insert 1.0 "abc\n123\nx\ny\nz\nq\nr\ns" update .t2.t delete 1.0 3.0 list [.t2.t index @0,0] [.t2.t get @0,0] } {1.0 x} test text-17.12 {DeleteChars procedure} { catch {destroy .t2} toplevel .t2 scintilla .t2.t -width 20 -height 5 pack append .t2 .t2.t top wm geometry .t2 +0+0 .t2.t insert 1.0 "abc\n123\nx\ny\nz\nq\nr\ns" .t2.t yview 3.0 update .t2.t delete 2.0 4.0 list [.t2.t index @0,0] [.t2.t get @0,0] } {2.0 y} catch {destroy .t2} toplevel .t2 scintilla .t2.t -width 1 -height 10 ;#-wrap char frame .t2.f -width 200 -height 20 -relief raised -bd 2 pack .t2.f .t2.t -side left wm geometry .t2 +0+0 update test text-17.13 {DeleteChars procedure, updates affecting topIndex} { .t2.t delete 1.0 end .t2.t insert end "abcde\n12345\nqrstuv" .t2.t yview 2.1 .t2.t delete 1.4 2.3 .t2.t index @0,0 } {1.2} test text-17.14 {DeleteChars procedure, updates affecting topIndex} { .t2.t delete 1.0 end .t2.t insert end "abcde\n12345\nqrstuv" .t2.t yview 2.1 .t2.t delete 2.3 2.4 .t2.t index @0,0 } {2.0} test text-17.15 {DeleteChars procedure, updates affecting topIndex} { .t2.t delete 1.0 end .t2.t insert end "abcde\n12345\nqrstuv" .t2.t yview 1.3 .t2.t delete 1.0 1.2 .t2.t index @0,0 } {1.1} test text-17.16 {DeleteChars procedure, updates affecting topIndex} { catch {destroy .t2} toplevel .t2 scintilla .t2.t -width 6 -height 10 -wrap word frame .t2.f -width 200 -height 20 -relief raised -bd 2 pack .t2.f .t2.t -side left wm geometry .t2 +0+0 update .t2.t insert end "abc def\n01 2345 678 9101112\nLine 3\nLine 4\nLine 5\n6\n7\n8\n" .t2.t yview 2.4 .t2.t delete 2.5 set x [.t2.t index @0,0] .t2.t delete 2.5 list $x [.t2.t index @0,0] } {2.3 2.0} .t delete 1.0 end foreach i {a b c d e f g h i j k l m n o p q r s t u v w x y z} { .t insert end $i.0$i.1$i.2$i.3$i.4\n } test text-18.1 {TextFetchSelection procedure} { .t tag add sel 1.3 3.4 selection get } {a.1a.2a.3a.4 b.0b.1b.2b.3b.4 c.0c} test text-18.2 {TextFetchSelection procedure} { .t tag add x 1.2 .t tag add x 1.4 .t tag add x 2.0 .t tag add x 2.3 .t tag remove sel 1.0 end .t tag add sel 1.0 3.4 selection get } {a.0a.1a.2a.3a.4 b.0b.1b.2b.3b.4 c.0c} test text-18.3 {TextFetchSelection procedure} { .t tag remove sel 1.0 end .t tag add sel 13.3 selection get } {m} test text-18.4 {TextFetchSelection procedure} { .t tag remove x 1.0 end .t tag add sel 1.0 3.4 .t tag remove sel 1.0 end .t tag add sel 1.2 1.5 .t tag add sel 2.4 3.1 .t tag add sel 10.0 10.end .t tag add sel 13.3 selection get } {0a..1b.2b.3b.4 cj.0j.1j.2j.3j.4m} set x "" for {set i 1} {$i < 200} {incr i} { append x "This is line $i, padded to just about 53 characters.\n" } test text-18.5 {TextFetchSelection procedure, long selections} { .t delete 1.0 end .t insert end $x .t tag add sel 1.0 end selection get } $x\n test text-19.1 {TkTextLostSelection procedure} unix { catch {destroy .t2} scintilla .t2 .t2 insert 1.0 "abc\ndef\nghijk\n1234" .t2 tag add sel 1.2 3.3 .t.e select to 1 .t2 tag ranges sel } {} test text-19.2 {TkTextLostSelection procedure} win { catch {destroy .t2} scintilla .t2 .t2 insert 1.0 "abc\ndef\nghijk\n1234" .t2 tag add sel 1.2 3.3 .t.e select to 1 .t2 tag ranges sel } {1.2 3.3} catch {destroy .t2} test text-19.3 {TkTextLostSelection procedure} { catch {destroy .t2} scintilla .t2 .t2 insert 1.0 "abcdef\nghijk\n1234" .t2 tag add sel 1.0 1.3 set x [selection get] selection clear lappend x [catch {selection get} msg] $msg .t2 tag add sel 1.0 1.3 lappend x [selection get] } {abc 1 {PRIMARY selection doesn't exist or form "STRING" not defined} abc} .t delete 1.0 end .t insert end "xxyz xyz x. the\nfoo -forward bar xxxxx BaR foo\nxyz xxyzx" test text-20.1 {TextSearchCmd procedure, argument parsing} { list [catch {.t search -} msg] $msg } {1 {bad switch "-": must be --, -all, -backward, -count, -elide, -exact, -forward, -nocase, -nolinestop, -overlap, -regexp, or -strictlimits}} test text-20.2 {TextSearchCmd procedure, -backwards option} { .t search -backwards xyz 1.4 } {1.1} test text-20.2.1 {TextSearchCmd procedure, -all option} { .t search -all xyz 1.4 } {1.5 3.0 3.5 1.1} test text-20.3 {TextSearchCmd procedure, -forwards option} { .t search -forwards xyz 1.4 } {1.5} test text-20.4 {TextSearchCmd procedure, -exact option} { .t search -f -exact x. 1.0 } {1.9} test text-20.5 {TextSearchCmd procedure, -regexp option} { .t search -b -regexp x.z 1.4 } {1.1} test text-20.6 {TextSearchCmd procedure, -count option} { set length unmodified list [.t search -count length x. 1.4] $length } {1.9 2} test text-20.7 {TextSearchCmd procedure, -count option} { list [catch {.t search -count} msg] $msg } {1 {no value given for "-count" option}} test text-20.8 {TextSearchCmd procedure, -nocase option} { list [.t search -nocase BaR 1.1] [.t search BaR 1.1] } {2.13 2.23} test text-20.9 {TextSearchCmd procedure, -n ambiguous option} { list [catch {.t search -n BaR 1.1} msg] $msg } {1 {bad switch "-n": must be --, -all, -backward, -count, -elide, -exact, -forward, -nocase, -nolinestop, -overlap, -regexp, or -strictlimits}} test text-20.9.1 {TextSearchCmd procedure, -nocase option} { .t search -noc BaR 1.1 } {2.13} test text-20.9.2 {TextSearchCmd procedure, -nolinestop option} { list [catch {.t search -nolinestop BaR 1.1} msg] $msg } {1 {the "-nolinestop" option requires the "-regexp" option to be present}} test text-20.9.3 {TextSearchCmd procedure, -nolinestop option} { set msg "" list [.t search -nolinestop -regexp -count msg e.*o 1.1] $msg } {1.14 32} test text-20.10 {TextSearchCmd procedure, -- option} { .t search -- -forward 1.0 } {2.4} test text-20.11 {TextSearchCmd procedure, argument parsing} { list [catch {.t search abc} msg] $msg } {1 {wrong # args: should be ".t search ?switches? pattern index ?stopIndex?"}} test text-20.12 {TextSearchCmd procedure, argument parsing} { list [catch {.t search abc d e f} msg] $msg } {1 {wrong # args: should be ".t search ?switches? pattern index ?stopIndex?"}} test text-20.13 {TextSearchCmd procedure, check index} { list [catch {.t search abc gorp} msg] $msg } {1 {bad text index "gorp"}} test text-20.14 {TextSearchCmd procedure, startIndex == "end"} { .t search non-existent end } {} test text-20.15 {TextSearchCmd procedure, startIndex == "end"} { .t search non-existent end } {} test text-20.16 {TextSearchCmd procedure, bad stopIndex} { list [catch {.t search abc 1.0 lousy} msg] $msg } {1 {bad text index "lousy"}} test text-20.17 {TextSearchCmd procedure, pattern case conversion} { list [.t search -nocase BAR 1.1] [.t search BAR 1.1] } {2.13 {}} test text-20.18 {TextSearchCmd procedure, bad regular expression pattern} { list [catch {.t search -regexp a( 1.0} msg] $msg } {1 {couldn't compile regular expression pattern: parentheses () not balanced}} test text-20.19 {TextSearchCmd procedure, skip dummy last line} { .t search -backwards BaR end 1.0 } {2.23} test text-20.20 {TextSearchCmd procedure, skip dummy last line} { .t search -backwards \n end 1.0 } {3.9} test text-20.21 {TextSearchCmd procedure, skip dummy last line} { .t search \n end } {1.15} test text-20.22 {TextSearchCmd procedure, skip dummy last line} { .t search -back \n 1.0 } {3.9} test text-20.23 {TextSearchCmd procedure, extract line contents} { .t tag add foo 1.2 .t tag add x 1.3 .t mark set silly 1.2 .t search xyz 3.6 } {1.1} test text-20.24 {TextSearchCmd procedure, stripping newlines} { .t search the\n 1.0 } {1.12} test text-20.25 {TextSearchCmd procedure, handling newlines} { .t search -regexp the\n 1.0 } {1.12} test text-20.26 {TextSearchCmd procedure, stripping newlines} { .t search -regexp {the$} 1.0 } {1.12} test text-20.27 {TextSearchCmd procedure, handling newlines} { .t search -regexp \n 1.0 } {1.15} test text-20.28 {TextSearchCmd procedure, line case conversion} { list [.t search -nocase bar 2.18] [.t search bar 2.18] } {2.23 2.13} test text-20.29 {TextSearchCmd procedure, firstChar and lastChar} { .t search -backwards xyz 1.6 } {1.5} test text-20.30 {TextSearchCmd procedure, firstChar and lastChar} { .t search -backwards xyz 1.5 } {1.1} test text-20.31 {TextSearchCmd procedure, firstChar and lastChar} { .t search xyz 1.5 } {1.5} test text-20.32 {TextSearchCmd procedure, firstChar and lastChar} { .t search xyz 1.6 } {3.0} test text-20.33 {TextSearchCmd procedure, firstChar and lastChar} { .t search {} 1.end } {1.15} test text-20.34 {TextSearchCmd procedure, firstChar and lastChar} { .t search f 1.end } {2.0} test text-20.35 {TextSearchCmd procedure, firstChar and lastChar} { .t search {} end } {1.0} test text-20.35a {TextSearchCmd procedure, regexp finds empty lines} { # Test for fix of bug #1643 .t insert end "\n" tk::TextSetCursor .t 4.0 .t search -forward -regexp {^$} insert end } {4.0} catch {destroy .t2} toplevel .t2 wm geometry .t2 +0+0 scintilla .t2.t -width 30 -height 10 pack .t2.t .t2.t insert 1.0 "This is a line\nand this is another" .t2.t insert end "\nand this is yet another" frame .t2.f -width 20 -height 20 -bd 2 -relief raised catch {.t2.t window create 2.5 -window .t2.f} test text-20.36 {TextSearchCmd procedure, firstChar and lastChar} { .t2.t search his 2.6 } {2.6} test text-20.37 {TextSearchCmd procedure, firstChar and lastChar} { .t2.t search this 2.6 } {3.4} test text-20.38 {TextSearchCmd procedure, firstChar and lastChar} { .t2.t search is 2.6 } {2.7} test text-20.39 {TextSearchCmd procedure, firstChar and lastChar} { .t2.t search his 2.7 } {3.5} test text-20.40 {TextSearchCmd procedure, firstChar and lastChar} { .t2.t search -backwards "his is another" 2.6 } {2.6} test text-20.41 {TextSearchCmd procedure, firstChar and lastChar} { .t2.t search -backwards "his is" 2.6 } {1.1} destroy .t2 test text-20.42 {TextSearchCmd procedure, firstChar and lastChar} { .t search -backwards forw 2.5 } {2.5} test text-20.43 {TextSearchCmd procedure, firstChar and lastChar} { .t search forw 2.5 } {2.5} test text-20.44 {TextSearchCmd procedure, firstChar and lastChar} { catch {destroy .t2} scintilla .t2 list [.t2 search a 1.0] [.t2 search -backward a 1.0] } {{} {}} test text-20.45 {TextSearchCmd procedure, regexp match length} { set length unchanged list [.t search -regexp -count length x(.)(.*)z 1.1] $length } {1.1 7} test text-20.46 {TextSearchCmd procedure, regexp match length} { set length unchanged list [.t search -regexp -backward -count length fo* 2.5] $length } {2.0 3} test text-20.47 {TextSearchCmd procedure, checking stopIndex} { list [.t search bar 2.1 2.13] [.t search bar 2.1 2.14] \ [.t search bar 2.12 2.14] [.t search bar 2.14 2.14] } {{} 2.13 2.13 {}} test text-20.48 {TextSearchCmd procedure, checking stopIndex} { list [.t search -backwards bar 2.20 2.13] \ [.t search -backwards bar 2.20 2.14] \ [.t search -backwards bar 2.14 2.13] \ [.t search -backwards bar 2.13 2.13] } {2.13 {} 2.13 {}} test text-20.48.1 {TextSearchCmd procedure, checking stopIndex} { list [.t search -backwards -strict bar 2.20 2.13] \ [.t search -backwards -strict bar 2.20 2.14] \ [.t search -backwards -strict bar 2.14 2.13] \ [.t search -backwards -strict bar 2.13 2.13] } {2.13 {} {} {}} test text-20.49 {TextSearchCmd procedure, embedded windows and index/count} { frame .t.f1 -width 20 -height 20 -relief raised -bd 2 frame .t.f2 -width 20 -height 20 -relief raised -bd 2 frame .t.f3 -width 20 -height 20 -relief raised -bd 2 frame .t.f4 -width 20 -height 20 -relief raised -bd 2 .t window create 2.10 -window .t.f3 .t window create 2.8 -window .t.f2 .t window create 2.8 -window .t.f1 .t window create 2.1 -window .t.f4 set result "" lappend result [.t search -count x forward 1.0] $x lappend result [.t search -count x wa 1.0] $x .t delete 2.1 .t delete 2.8 2.10 .t delete 2.10 set result } {2.6 10 2.11 2} test text-20.50 {TextSearchCmd procedure, error setting variable} { catch {unset a} set a 44 list [catch {.t search -count a(2) xyz 1.0} msg] $msg } {1 {can't set "a(2)": variable isn't array}} test text-20.51 {TextSearchCmd procedure, wrap-around} { .t search -backwards xyz 1.1 } {3.5} test text-20.52 {TextSearchCmd procedure, wrap-around} { .t search -backwards xyz 1.1 1.0 } {} test text-20.53 {TextSearchCmd procedure, wrap-around} { .t search xyz 3.6 } {1.1} test text-20.54 {TextSearchCmd procedure, wrap-around} { .t search xyz 3.6 end } {} test text-20.55 {TextSearchCmd procedure, no match} { .t search non_existent 3.5 } {} test text-20.56 {TextSearchCmd procedure, no match} { .t search -regexp non_existent 3.5 } {} test text-20.57 {TextSearchCmd procedure, special cases} { .t search -back x 1.1 } {1.0} test text-20.58 {TextSearchCmd procedure, special cases} { .t search -back x 1.0 } {3.8} test text-20.59 {TextSearchCmd procedure, special cases} { .t search \n {end-2c} } {3.9} test text-20.60 {TextSearchCmd procedure, special cases} { .t search \n end } {1.15} test text-20.61 {TextSearchCmd procedure, special cases} { .t search x 1.0 } {1.0} test text-20.62 {TextSearchCmd, freeing copy of pattern} { # This test doesn't return a result, but it will generate # a core leak if the pattern copy isn't properly freed. # (actually in Tk 8.5 objectification means there is no # longer a copy of the pattern, but we leave this test in # anyway). set p abcdefg1234567890 set p $p$p$p$p$p$p$p$p set p $p$p$p$p$p .t search -nocase $p 1.0 } {} test text-20.63 {TextSearchCmd, unicode} { .t delete 1.0 end .t insert end "foo\u30c9\u30cabar" .t search \u30c9\u30ca 1.0 } 1.3 test text-20.64 {TextSearchCmd, unicode} { .t delete 1.0 end .t insert end "foo\u30c9\u30cabar" list [.t search -count n \u30c9\u30ca 1.0] $n } {1.3 2} test text-20.65 {TextSearchCmd, unicode with non-text segments} { .t delete 1.0 end button .b1 -text baz .t insert end "foo\u30c9" .t window create end -window .b1 .t insert end "\u30cabar" set result [list [.t search -count n \u30c9\u30ca 1.0] $n] destroy .b1 set result } {1.3 3} test text-20.66 {TextSearchCmd, hidden text does not affect match index} { deleteWindows pack [scintilla .t2] .t2 insert end "12345H7890" .t2 search 7 1.0 } 1.6 test text-20.67 {TextSearchCmd, hidden text does not affect match index} { deleteWindows pack [scintilla .t2] .t2 insert end "12345H7890" .t2 tag configure hidden -elide true .t2 tag add hidden 1.5 .t2 search 7 1.0 } 1.6 test text-20.68 {TextSearchCmd, hidden text does not affect match index} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nbarbaz\nbazboo" .t2 search boo 1.0 } 3.3 test text-20.69 {TextSearchCmd, hidden text does not affect match index} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nbarbaz\nbazboo" .t2 tag configure hidden -elide true .t2 tag add hidden 2.0 3.0 .t2 search boo 1.0 } 3.3 test text-20.70 {TextSearchCmd, -regexp -nocase searches} { catch {destroy .t} pack [scintilla .t] .t insert end "word1 word2" set res [.t search -nocase -regexp {\mword.} 1.0 end] destroy .t set res } 1.0 test text-20.71 {TextSearchCmd, -regexp -nocase searches} { catch {destroy .t} pack [scintilla .t] .t insert end "word1 word2" set res [.t search -nocase -regexp {word.\M} 1.0 end] destroy .t set res } 1.0 test text-20.72 {TextSearchCmd, -regexp -nocase searches} { catch {destroy .t} pack [scintilla .t] .t insert end "word1 word2" set res [.t search -nocase -regexp {word.\W} 1.0 end] destroy .t set res } 1.0 test text-20.73 {TextSearchCmd, hidden text and start index} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" .t2 search bar 1.3 } 1.3 test text-20.74 {TextSearchCmd, hidden text shouldn't influence start index} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" .t2 tag configure hidden -elide true .t2 tag add hidden 1.0 1.2 .t2 search bar 1.3 } 1.3 test text-20.75 {TextSearchCmd, hidden text inside match must count in length} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" .t2 tag configure hidden -elide true .t2 tag add hidden 1.2 1.4 list [.t2 search -count foo foar 1.3] $foo } {1.0 6} test text-20.75.1 {TextSearchCmd, hidden text inside match must count in length} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" .t2 tag configure hidden -elide true .t2 tag add hidden 1.2 1.4 list \ [.t2 search -strict -count foo foar 1.3] \ [.t2 search -strict -count foo foar 2.3] $foo } {{} 1.0 6} test text-20.76 {TextSearchCmd, hidden text and start index} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" .t2 search -regexp bar 1.3 } 1.3 test text-20.77 {TextSearchCmd, hidden text shouldn't influence start index} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" .t2 tag configure hidden -elide true .t2 tag add hidden 1.0 1.2 .t2 search -regexp bar 1.3 } 1.3 test text-20.78 {TextSearchCmd, hidden text inside match must count in length} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" .t2 tag configure hidden -elide true .t2 tag add hidden 1.2 1.4 list [.t2 search -regexp -count foo foar 1.3] $foo } {1.0 6} test text-20.78.1 {TextSearchCmd, hidden text inside match must count in length} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" .t2 tag configure hidden -elide true .t2 tag add hidden 1.2 1.4 list [.t2 search -count foo foar 1.3] $foo } {1.0 6} test text-20.78.2 {TextSearchCmd, hidden text inside match must count in length} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" .t2 tag configure hidden -elide true .t2 tag add hidden 1.2 1.4 .t2 search -strict -count foo foar 1.3 } {} test text-20.78.3 {TextSearchCmd, hidden text inside match must count in length} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoar" .t2 tag configure hidden -elide true .t2 tag add hidden 1.2 1.4 .t2 tag add hidden 2.2 2.4 list [.t2 search -regexp -all -count foo foar 1.3] $foo } {{2.0 3.0 1.0} {6 4 6}} test text-20.78.4 {TextSearchCmd, hidden text inside match must count in length} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoar" .t2 tag configure hidden -elide true .t2 tag add hidden 1.2 1.4 .t2 tag add hidden 2.2 2.4 list [.t2 search -all -count foo foar 1.3] $foo } {{2.0 3.0 1.0} {6 4 6}} test text-20.78.5 {TextSearchCmd, hidden text inside match must count in length} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoar" .t2 tag configure hidden -elide true .t2 tag add hidden 1.2 1.4 .t2 tag add hidden 2.2 2.4 list [.t2 search -strict -all -count foo foar 1.3] $foo } {{2.0 3.0} {6 4}} test text-20.78.6 {TextSearchCmd, single line with -all} { deleteWindows pack [scintilla .t2] .t2 insert end " X\n X\n X\n X\n X\n X\n" .t2 search -all -regexp { +| *\n} 1.0 end } {1.0 1.2 2.0 2.2 3.0 3.2 4.0 4.2 5.0 5.2 6.0 6.2 7.0} test text-20.79 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" list [.t2 search -count foo foobar\nfoo 1.0] $foo } {1.0 10} test text-20.80 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" list [.t2 search -count foo bar\nfoo 1.0] $foo } {1.3 7} test text-20.81 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" list [.t2 search -count foo \nfoo 1.0] $foo } {1.6 4} test text-20.82 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" list [.t2 search -count foo bar\nfoobar\nfoo 1.0] $foo } {1.3 14} test text-20.83 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" .t2 search -count foo bar\nfoobar\nfoobanearly 1.0 } {} test text-20.84 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" list [.t2 search -regexp -count foo foobar\nfoo 1.0] $foo } {1.0 10} test text-20.85 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" list [.t2 search -regexp -count foo bar\nfoo 1.0] $foo } {1.3 7} test text-20.86 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" list [.t2 search -regexp -count foo \nfoo 1.0] $foo } {1.6 4} test text-20.87 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" list [.t2 search -regexp -count foo bar\nfoobar\nfoo 1.0] $foo } {1.3 14} test text-20.88 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" .t2 search -regexp -count foo bar\nfoobar\nfoobanearly 1.0 } {} test text-20.89 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfaoobar\nfoobar" .t2 search -regexp -count foo bar\nfoo 1.0 } {2.4} test text-20.90 {TextSearchCmd, multiline matching end of window} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfaoobar\nfoobar" .t2 search -regexp -count foo bar\nfoobar\n\n 1.0 } {} test text-20.91 {TextSearchCmd, multiline matching end of window} { deleteWindows pack [scintilla .t2] .t2 search "\n\n" 1.0 } {} test text-20.92 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" list [.t2 search -backwards -count foo foobar\nfoo end] $foo } {2.0 10} test text-20.93 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" list [.t2 search -backwards -count foo bar\nfoo 1.0] $foo } {2.3 7} test text-20.94 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" list [.t2 search -backwards -count foo \nfoo 1.0] $foo } {2.6 4} test text-20.95 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" list [.t2 search -backwards -count foo bar\nfoobar\nfoo 1.0] $foo } {1.3 14} test text-20.96 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" .t2 search -backwards -count foo bar\nfoobar\nfoobanearly 1.0 } {} test text-20.97 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" list [.t2 search -backwards -regexp -count foo foobar\nfoo end] $foo } {2.0 10} test text-20.97.1 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" list [.t2 search -backwards -regexp -count foo foobar\nfo end] $foo } {2.0 9} test text-20.98 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" list [.t2 search -backwards -regexp -count foo bar\nfoo 1.0] $foo } {2.3 7} test text-20.99 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" list [.t2 search -backwards -regexp -count foo \nfoo 1.0] $foo } {2.6 4} test text-20.100 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" list [.t2 search -backwards -regexp -count foo bar\nfoobar\nfoo 1.0] $foo } {1.3 14} test text-20.101 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" .t2 search -backwards -regexp -count foo bar\nfoobar\nfoobanearly 1.0 } {} test text-20.102 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfaoobar\nfoobar" .t2 search -backwards -regexp -count foo bar\nfoo 1.0 } {2.4} test text-20.103 {TextSearchCmd, multiline matching end of window} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfaoobar\nfoobar" .t2 search -backwards -regexp -count foo bar\nfoobar\n\n 1.0 } {} test text-20.104 {TextSearchCmd, multiline matching end of window} { deleteWindows pack [scintilla .t2] .t2 search -backwards "\n\n" 1.0 } {} test text-20.105 {TextSearchCmd, multiline regexp matching} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 { Tcl_Obj *objPtr)); static Tcl_Obj* FSNormalizeAbsolutePath _ANSI_ARGS_((Tcl_Interp* interp, Tcl_Obj *pathPtr));} set markExpr "^(\[A-Za-z0-9~_\]+\[ \t\n\r\]*\\(|(\[^ \t\(#\n\r/@:\*\]\[^=\(\r\n\]*\[ \t\]+\\*?)?" append markExpr "(\[A-Za-z0-9~_\]+(<\[^>\]*>)?(::)?(\[A-Za-z0-9~_\]+::)*\[-A-Za-z0-9~_+ <>\|\\*/\]+|\[A-Za-z0-9~_\]+)" append markExpr "\[ \n\t\r\]*\\()" .t2 search -forwards -regexp $markExpr 1.41 end } {} test text-20.106 {TextSearchCmd, multiline regexp matching} { # Practical example which used to crash Tk, but only after the # search is complete. This is memory corruption caused by # a bug in Tcl's handling of string objects. # (Tcl bug 635200) deleteWindows pack [scintilla .t2] .t2 insert 1.0 {static int SetFsPathFromAny _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *objPtr)); static Tcl_Obj* FSNormalizeAbsolutePath _ANSI_ARGS_((Tcl_Interp* interp, Tcl_Obj *pathPtr));} set markExpr "^(\[A-Za-z0-9~_\]+\[ \t\n\r\]*\\(|(\[^ \t\(#\n\r/@:\*\]\[^=\(\r\n\]*\[ \t\]+\\*?)?" append markExpr "(\[A-Za-z0-9~_\]+(<\[^>\]*>)?(::)?(\[A-Za-z0-9~_\]+::)*\[-A-Za-z0-9~_+ <>\|\\*/\]+|\[A-Za-z0-9~_\]+)" append markExpr "\[ \n\t\r\]*\\()" .t2 search -forwards -regexp $markExpr 1.41 end } {} test text-20.107 {TextSearchCmd, multiline regexp matching} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 { static int SetFsPathFromAny _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *objPtr)); static Tcl_Obj* FSNormalizeAbsolutePath _ANSI_ARGS_((Tcl_Interp* interp, Tcl_Obj *pathPtr));} set markExpr "^(\[A-Za-z0-9~_\]+\[ \t\n\r\]*\\(|(\[^ \t\(#\n\r/@:\*\]\[^=\(\r\n\]*\[ \t\]+\\*?)?" append markExpr "(\[A-Za-z0-9~_\]+(<\[^>\]*>)?(::)?(\[A-Za-z0-9~_\]+::)*\[-A-Za-z0-9~_+ <>\|\\*/\]+|\[A-Za-z0-9~_\]+)" append markExpr "\[ \n\t\r\]*\\()" .t2 search -backwards -all -regexp $markExpr end } {2.0} test text-20.108 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" .t2 search -all -regexp -count foo bar\nfoo 1.0 } {1.3 2.3} test text-20.109 {TextSearchCmd, multiline matching} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" .t2 search -all -backwards -regexp -count foo bar\nfoo 1.0 } {2.3 1.3} test text-20.110 {TextSearchCmd, wrapping and limits} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" .t2 search -- "blah" 3.3 1.3 } {} test text-20.111 {TextSearchCmd, wrapping and limits} { deleteWindows pack [scintilla .t2] .t2 insert end "foobar\nfoobar\nfoobar" .t2 search -backwards -- "blah" 1.3 3.3 } {} test text-20.112 {TextSearchCmd, wrapping and limits} { deleteWindows pack [scintilla .t2] .t2 insert end "if (stringPtr->uallocated > 0) \{x" .t2 search -backwards -regexp -- "\[\]\")\}\[(\{\]" "1.32" 1.0 } {1.31} test text-20.113 {TextSearchCmd, wrapping and limits} { deleteWindows pack [scintilla .t2] .t2 insert end "if (stringPtr->uallocated > 0) \{x" .t2 search -regexp -- "\[\]\")\}\[(\{\]" 1.30 "1.0 lineend" } {1.31} test text-20.114 {TextSearchCmd, wrapping and limits} { deleteWindows pack [scintilla .t2] .t2 insert end "if (stringPtr->uallocated > 0) \{x" .t2 search -backwards -all -regexp -- "\[\]\")\}\[(\{\]" "1.32" 1.0 } {1.31 1.29 1.3} test text-20.115 {TextSearchCmd, wrapping and limits} { deleteWindows pack [scintilla .t2] .t2 insert end "if (stringPtr->uallocated > 0) \{x" .t2 search -all -regexp -- "\[\]\")\}\[(\{\]" 1.0 "1.0 lineend" } {1.3 1.29 1.31} test text-20.116 {TextSearchCmd, wrapping and limits} { deleteWindows pack [scintilla .t2] .t2 insert end "if (stringPtr->uallocated > 0) \{x" .t2 search -backwards -- "\{" "1.32" 1.0 } {1.31} test text-20.117 {TextSearchCmd, wrapping and limits} { deleteWindows pack [scintilla .t2] .t2 insert end "if (stringPtr->uallocated > 0) \{x" .t2 search -- "\{" 1.30 "1.0 lineend" } {1.31} test text-20.118 {TextSearchCmd, multiline regexp matching} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 { void Tcl_SetObjLength(objPtr, length) register Tcl_Obj *objPtr; /* Pointer to object. This object must * not currently be shared. */ register int length; /* Number of bytes desired for string * representation of object, not including * terminating null byte. */ \{ char *new; } set markExpr "^(\[A-Za-z0-9~_\]+\[ \t\n\r\]*\\(|(\[^ \t\(#\n\r/@:\*\]\[^=\(\r\n\]*\[ \t\]+\\*?)?" append markExpr "(\[A-Za-z0-9~_\]+(<\[^>\]*>)?(::)?(\[A-Za-z0-9~_\]+::)*\[-A-Za-z0-9~_+ <>\|\\*/\]+|\[A-Za-z0-9~_\]+)" append markExpr "\[ \n\t\r\]*\\()" .t2 search -all -regexp -- $markExpr 1.0 } {4.0} test text-20.119 {TextSearchCmd, multiline regexp matching} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "first line\nlast line of text" set markExpr {^[a-z]+} # This should not match, and should not wrap .t2 search -regexp -- $markExpr end end } {} test text-20.120 {TextSearchCmd, multiline regexp matching} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "first line\nlast line of text" set markExpr {^[a-z]+} # This should not match, and should not wrap .t2 search -regexp -- $markExpr end+10c end } {} test text-20.121 {TextSearchCmd, multiline regexp matching} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "first line\nlast line of text" set markExpr {^[a-z]+} # This should not match, and should not wrap .t2 search -regexp -backwards -- $markExpr 1.0 1.0 } {} test text-20.122 {TextSearchCmd, regexp linestop} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "first line\nlast line of text" .t2 search -regexp -- {i.*x} 1.0 } {2.6} test text-20.123 {TextSearchCmd, multiline regexp nolinestop matching} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "first line\nlast line of text" .t2 search -regexp -nolinestop -- {i.*x} 1.0 } {1.1} test text-20.124 {TextSearchCmd, regexp linestop} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "first line\nlast line of text" .t2 search -regexp -all -overlap -- {i.*x} 1.0 } {2.6} test text-20.124.1 {TextSearchCmd, regexp linestop} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "first line\nlast line of text" .t2 search -regexp -all -- {i.*x} 1.0 } {2.6} test text-20.125 {TextSearchCmd, multiline regexp nolinestop matching} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "first line\nlast line of text" list [.t2 search -regexp -all -overlap -count c -nolinestop -- {i.*x} 1.0] $c } {{1.1 2.6} {26 10}} test text-20.125.1 {TextSearchCmd, multiline regexp nolinestop matching} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "first line\nlast line of text" list [.t2 search -regexp -all -count c -nolinestop -- {i.*x} 1.0] $c } {1.1 26} test text-20.126 {TextSearchCmd, stop at end of line} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 " \t\n last line of text" .t2 search -regexp -nolinestop -- {[^ \t]} 1.0 } {1.3} test text-20.127 {TextSearchCmd, overlapping all matches} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde abcde" list [.t2 search -regexp -all -overlap -count c -- {\w+} 1.0] $c } {{1.0 1.6} {5 5}} test text-20.127.1 {TextSearchCmd, non-overlapping all matches} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde abcde" list [.t2 search -regexp -all -count c -- {\w+} 1.0] $c } {{1.0 1.6} {5 5}} test text-20.128 {TextSearchCmd, stop at end of line} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde abcde" list [.t2 search -backwards -regexp -all -count c -- {\w+} 1.0] $c } {{1.6 1.0} {5 5}} test text-20.129 {TextSearchCmd, backwards search stop index } { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "bla ZabcZdefZghi and some text again" list [.t2 search -backwards -regexp -count c -- {Z\w+} 1.21 1.5] $c } {1.8 8} test text-20.130 {TextSearchCmd, backwards search stop index } { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "bla ZabcZdefZghi and some text again" list [.t2 search -backwards -all -overlap -regexp -count c -- {Z\w+} 1.21 1.5] $c } {1.8 8} test text-20.130.1 {TextSearchCmd, backwards search stop index } { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "bla ZabcZdefZghi and some text again" list [.t2 search -backwards -all -regexp -count c -- {Z\w+} 1.21 1.5] $c } {1.8 8} test text-20.131 {TextSearchCmd, backwards search stop index } { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "bla ZabcZdefZghi and some text again" list [.t2 search -backwards -overlap -all -regexp -count c -- {Z\w+} 1.21 1.1] $c } {1.4 12} test text-20.131.1 {TextSearchCmd, backwards search stop index } { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "bla ZabcZdefZghi and some text again" list [.t2 search -backwards -overlap -all -regexp -count c -- {Z[^Z]+Z} 1.21 1.1] $c } {{1.8 1.4} {5 5}} test text-20.131.2 {TextSearchCmd, backwards search stop index } { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "bla ZabcZdefZghi and some text again" list [.t2 search -backwards -all -regexp -count c -- {Z\w+} 1.21 1.1] $c } {1.4 12} test text-20.132 {TextSearchCmd, backwards search stop index } { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "bla ZabcZdefZghi and some text again" .t2 insert 1.0 "bla ZabcZdefZghi and some text again\n" list [.t2 search -backwards -all -overlap -regexp -count c -- {Z\w+} 2.21 1.5] $c } {{2.4 1.8} {12 8}} test text-20.132.1 {TextSearchCmd, backwards search stop index } { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "bla ZabcZdefZghi and some text again" .t2 insert 1.0 "bla ZabcZdefZghi and some text again\n" list [.t2 search -backwards -all -regexp -count c -- {Z\w+} 2.21 1.5] $c } {{2.4 1.8} {12 8}} test text-20.133 {TextSearchCmd, backwards search stop index } { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "bla ZabcZdefZghi and some text again" .t2 insert 1.0 "bla ZabcZdefZghi and some text again\n" list [.t2 search -backwards -overlap -all -regexp -count c -- {Z\w+} 2.21 1.1] $c } {{2.4 1.4} {12 12}} test text-20.133.1 {TextSearchCmd, backwards search stop index } { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "bla ZabcZdefZghi and some text again" .t2 insert 1.0 "bla ZabcZdefZghi and some text again\n" list [.t2 search -backwards -all -regexp -count c -- {Z\w+} 2.21 1.1] $c } {{2.4 1.4} {12 12}} test text-20.134 {TextSearchCmd, search -all example} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 { See the package: supersearch for more information. See the package: incrementalSearch for more information. package: Brws . See the package: marks for more information. } set pat {package: ([a-zA-Z0-9][-a-zA-Z0-9._+#/]*)} list [.t2 search -nolinestop -regexp -nocase -all -forwards \ -count c -- $pat 1.0 end] $c } {{3.8 6.8 8.0 11.8} {20 26 13 14}} test text-20.135 {TextSearchCmd, backwards search overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "foobarfoobaaaaaaaaaaarfoo" .t2 search -backwards -regexp {fooba+rfoo} end } {1.6} test text-20.135.1 {TextSearchCmd, backwards search overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "foobarfoobaaaaaaaaaaarfoo" .t2 search -backwards -overlap -all -regexp {fooba+rfoo} end } {1.6 1.0} test text-20.135.2 {TextSearchCmd, backwards search overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "foobarfoobaaaaaaaaaaarfoo" .t2 search -backwards -all -regexp {fooba+rfoo} end } {1.6} test text-20.135.3 {TextSearchCmd, forwards search overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "foobarfoobaaaaaaaaaaarfoo" .t2 search -all -overlap -regexp {fooba+rfoo} end } {1.0 1.6} test text-20.135.4 {TextSearchCmd, forwards search overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "foobarfoobaaaaaaaaaaarfoo" .t2 search -all -regexp {fooba+rfoo} end } {1.0} test text-20.136 {TextSearchCmd, forward exact search overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abababab" .t2 search -exact -overlap -all {abab} 1.0 } {1.0 1.2 1.4} test text-20.136.1 {TextSearchCmd, forward exact search overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abababab" .t2 search -exact -all {abab} 1.0 } {1.0 1.4} test text-20.137 {TextSearchCmd, backward exact search overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "ababababab" .t2 search -exact -overlap -backwards -all {abab} end } {1.6 1.4 1.2 1.0} test text-20.137.1 {TextSearchCmd, backward exact search overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "ababababab" .t2 search -exact -backwards -all {abab} end } {1.6 1.2} test text-20.137.2 {TextSearchCmd, backward exact search overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abababababab" .t2 search -exact -backwards -all {abab} end } {1.8 1.4 1.0} test text-20.138 {TextSearchCmd, forward exact search overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "foo\nbar\nfoo\nbar\nfoo\nbar\nfoo\n" .t2 search -exact -overlap -all "foo\nbar\nfoo" 1.0 } {1.0 3.0 5.0} test text-20.138.1 {TextSearchCmd, forward exact search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "foo\nbar\nfoo\nbar\nfoo\nbar\nfoo\n" .t2 search -exact -all "foo\nbar\nfoo" 1.0 } {1.0 5.0} test text-20.139 {TextSearchCmd, backward exact search overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "foo\nbar\nfoo\nbar\nfoo\nbar\nfoo\n" .t2 search -exact -overlap -backward -all "foo\nbar\nfoo" end } {5.0 3.0 1.0} test text-20.140 {TextSearchCmd, backward exact search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "foo\nbar\nfoo\nbar\nfoo\nbar\nfoo\n" .t2 search -exact -backward -all "foo\nbar\nfoo" end } {5.0 1.0} test text-20.141 {TextSearchCmd, backward exact search overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "foo\nbar\nfoo\nbar\nfoo\nbar\nfoo\n" .t2 search -regexp -backward -overlap -all "foo\nbar\nfoo" end } {5.0 3.0 1.0} test text-20.142 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "foo\nbar\nfoo\nbar\nfoo\nbar\nfoo\n" .t2 search -regexp -backward -all "foo\nbar\nfoo" end } {5.0 1.0} test text-20.142a {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 " aasda asdj werwer" .t2 search -regexp -backward -- {(\$)?[\w:_]+} 1.9 } {1.7} test text-20.143 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 " aasda asdj werwer" .t2 search -regexp -backward -- {(\$)?[\w:_]+} 1.9 1.5 } {1.7} test text-20.144 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 " aasda asdj werwer" .t2 search -regexp -backward -- {(\$)?[\w:_]+} 1.9 1.7 } {1.7} test text-20.145 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 " aasda asdj werwer" .t2 search -regexp -backward -- {(\$)?[\w:_]+} 1.9 1.8 } {1.8} test text-20.146 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 " aasda asdj werwer" .t2 search -regexp -backward -all -- {(\$)?[\w:_]+} 1.9 1.3 } {1.7 1.3} test text-20.147 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 " aasda asdj werwer" .t2 search -regexp -backward -all -- {(\$)?[\w:_]+} 1.9 1.13 } {} test text-20.148 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 " aasda asdj werwer" .t2 search -regexp -backward -all -- {(\$)?[\w:_]+} 2.0 1.3 } {1.12 1.7 1.3} test text-20.149 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 " aasda asdj werwer" .t2 search -regexp -backward -all -- {(\$)?[\w:_]+} 1.3 } {1.1 1.12 1.7 1.3} test text-20.150 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde\nabcde\nabcde\n" .t2 search -regexp -backward -all -- {(\w+\n)+} end } {1.0} test text-20.151 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde\nabcde\nabcde\n" .t2 search -regexp -backward -all -- {(\w+\n)+} end 1.5 } {2.0} test text-20.152 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde\nabcde\nabcde\na" .t2 search -regexp -backward -all -- {(\w+\n\w)+} end 1.5 } {2.0} test text-20.153 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde\nabcde\nabcde\na" list [.t2 search -regexp -all -count foo -- {(\w+\n)+} 1.0] $foo } {1.0 20} test text-20.154 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde\nabcde\nabcde\na" set res {} lappend res \ [list [.t2 search -regexp -all -count foo -- {(\w+\n)+} 1.0] $foo] \ [list [.t2 search -regexp -all -count foo -- {(\w+)+} 1.0] $foo] } {{1.0 20} {{1.0 2.0 3.0 4.0} {5 5 5 1}}} test text-20.155 {TextSearchCmd, regexp search greedy} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde\nabcde\nabcde\na" list [.t2 search -regexp -all -nolinestop -count foo -- {.*} 1.0] $foo } {1.0 20} test text-20.156 {TextSearchCmd, regexp search greedy} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde\nabcde\nabcde\na" list [.t2 search -regexp -all -count foo -- {.*} 1.0] $foo } {{1.0 2.0 3.0 4.0} {5 5 5 1}} test text-20.157 {TextSearchCmd, regexp search greedy multi-line} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde\nabcde\nabcde\na" list [.t2 search -regexp -count foo -- {(\w+\n\w)+} 1.0] $foo } {1.0 19} test text-20.158 {TextSearchCmd, regexp search greedy multi-line} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde\nabcde\nabcde\na" list [.t2 search -regexp -backwards -count foo -- {(\w+\n\w)+} end] $foo } {1.0 19} test text-20.159 {TextSearchCmd, regexp search greedy multi-line} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde\nabcde\nabcde\na" list [.t2 search -regexp -all -backwards -count foo -- {(\w+\n\w)+} end] $foo } {1.0 19} test text-20.160 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde\nabcde\nabcde\na" .t2 search -regexp -backward -all -- {(\w+\n\w)+} end 1.5 } {2.0} test text-20.161 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde\nabcde\nabcde\na" .t2 search -regexp -backward -all -- {(\w+\n\w)+} end 1.3 } {1.3} test text-20.162 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde\nabcde\nabcde\na" list [.t2 search -regexp -forward -count foo -- {(\w+\n\w)+} 1.3] $foo } {1.3 16} test text-20.163 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde\nabcde\nabcde\na" list [.t2 search -regexp -forward -all -count foo -- {(\w+\n\w)+} 1.3] $foo # This result is somewhat debatable -- the two results do overlap, # but only because the search has totally wrapped around back to # the start. } {{1.3 1.0} {16 19}} test text-20.164 {TextSearchCmd, backward regexp search no-overlaps} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "abcde\nabcde\nabcde\na" list [.t2 search -regexp -forward -all -count foo -- {(\w+\n\w)+} 1.0 1.3] $foo } {1.0 19} test text-20.165 {TextSearchCmd, regexp search multi-line} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "aaaa\nbbbb\naaaa\nbbbb\n" list [.t2 search -regexp -forward -all -count foo -- {(a+\n(b+\n))+} 1.0] $foo } {1.0 20} test text-20.166 {TextSearchCmd, regexp search complex cases} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "aaaa\nbbbb\naaaa\nbbbb\n" list [.t2 search -regexp -forward -all -count foo \ -- {(a+\n(b+\n))+} 1.0] $foo } {1.0 20} test text-20.167 {TextSearchCmd, regexp search multi-line} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "aaaa\nbbbb\ncccc\nbbbb\naaaa\n" set foo {} list [.t2 search -regexp -forward -all -count foo \ -- {(b+\nc+\nb+)\na+} 1.0] $foo } {2.0 19} test text-20.168 {TextSearchCmd, regexp search multi-line} {knownBug} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "aaaa\nbbbb\ncccc\nbbbb\naaaa\n" set foo {} list [.t2 search -regexp -forward -all -count foo \ -- {(a+|b+\nc+\nb+)\na+} 1.0] $foo } {2.0 19} test text-20.169 {TextSearchCmd, regexp search multi-line} {knownBug} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "aaaa\nbbbb\ncccc\nbbbb\naaaa\n" set foo {} list [.t2 search -regexp -forward -all -count foo \ -- {(a+|b+\nc+\nb+)+\na+} 1.0] $foo } {2.0 19} test text-20.170 {TextSearchCmd, regexp search multi-line} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "aaaa\nbbbb\ncccc\nbbbb\naaaa\n" set foo {} list [.t2 search -regexp -forward -all -count foo \ -- {((a+|b+\nc+\nb+)+\n)+a+} 1.0] $foo } {1.0 24} test text-20.171 {TextSearchCmd, regexp search multi-line} {knownBug} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "aaaa\nbbbb\nbbbb\nbbbb\nbbbb\n" list [.t2 search -regexp -backward -all -count foo \ -- {b+\n|a+\n(b+\n)+} end] $foo } {1.0 25} test text-20.172 {TextSearchCmd, regexp search multi-line} {knownBug} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "aaaa\nbbbb\nbbbb\nbbbb\nbbbb\n" .t2 search -regexp -backward -- {b+\n|a+\n(b+\n)+} end # Should match at 1.0 for a true greedy match } {1.0} test text-20.172.1 {TextSearchCmd, regexp search multi-line} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "line0\nline1\nline1\nline1\nline1\nline2\nline2\nline2\nline3\n" .t2 search -nolinestop -regexp -nocase -forwards -- {^(.*)\n(\1\n)+} 1.0 end # Matches at 6.0 currently } {2.0} test text-20.173 {TextSearchCmd, regexp search multi-line} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "\naaaxxx\nyyy\n" set res {} lappend res [.t2 search -count c -regexp -- {x*\ny*} 2.0] $c lappend res [.t2 search -count c -regexp -- {x*\ny*} 2.1] $c set res } {2.3 7 2.3 7} test text-20.174 {TextSearchCmd, regexp search multi-line} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "\naaa\n\n\n\n\nxxx\n" set res {} lappend res [.t2 search -count c -regexp -- {\n+} 2.0] $c lappend res [.t2 search -count c -regexp -- {\n+} 2.1] $c set res } {2.3 5 2.3 5} test text-20.175 {TextSearchCmd, regexp search multi-line} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "\naaa\n\n\t \n\t\t\t \n\nxxx\n" set res {} lappend res [.t2 search -count c -regexp -- {(\n+(\t+ *)*)+} 2.0] $c set res } {2.3 13} test text-20.176 {TextSearchCmd, empty search range} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "a\na\na\n" .t2 search -- a 2.0 1.0 } {} test text-20.177 {TextSearchCmd, empty search range} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "a\na\na\n" .t2 search -backwards -- a 1.0 2.0 } {} test text-20.178 {TextSearchCmd, empty search range} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "a\na\na\n" .t2 search -- a 1.0 1.0 } {} test text-20.179 {TextSearchCmd, empty search range} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "a\na\na\n" .t2 search -backwards -- a 2.0 2.0 } {} test text-20.180 {TextSearchCmd, elide up to match} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "a\nb\nc" .t2 tag configure e -elide 1 set res {} lappend res [.t2 search -regexp a 1.0] lappend res [.t2 search -regexp b 1.0] lappend res [.t2 search -regexp c 1.0] .t2 tag add e 1.0 2.0 lappend res [.t2 search -regexp a 1.0] lappend res [.t2 search -regexp b 1.0] lappend res [.t2 search -regexp c 1.0] lappend res [.t2 search -elide -regexp a 1.0] lappend res [.t2 search -elide -regexp b 1.0] lappend res [.t2 search -elide -regexp c 1.0] } {1.0 2.0 3.0 {} 2.0 3.0 1.0 2.0 3.0} test text-20.181 {TextSearchCmd, elide up to match, backwards} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "a\nb\nc" .t2 tag configure e -elide 1 set res {} lappend res [.t2 search -backward -regexp a 1.0] lappend res [.t2 search -backward -regexp b 1.0] lappend res [.t2 search -backward -regexp c 1.0] .t2 tag add e 1.0 2.0 lappend res [.t2 search -backward -regexp a 1.0] lappend res [.t2 search -backward -regexp b 1.0] lappend res [.t2 search -backward -regexp c 1.0] lappend res [.t2 search -backward -elide -regexp a 1.0] lappend res [.t2 search -backward -elide -regexp b 1.0] lappend res [.t2 search -backward -elide -regexp c 1.0] } {1.0 2.0 3.0 {} 2.0 3.0 1.0 2.0 3.0} test text-20.182 {TextSearchCmd, elide up to match} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "a\nb\nc" .t2 tag configure e -elide 1 set res {} lappend res [.t2 search a 1.0] lappend res [.t2 search b 1.0] lappend res [.t2 search c 1.0] .t2 tag add e 1.0 2.0 lappend res [.t2 search a 1.0] lappend res [.t2 search b 1.0] lappend res [.t2 search c 1.0] lappend res [.t2 search -elide a 1.0] lappend res [.t2 search -elide b 1.0] lappend res [.t2 search -elide c 1.0] } {1.0 2.0 3.0 {} 2.0 3.0 1.0 2.0 3.0} test text-20.183 {TextSearchCmd, elide up to match, backwards} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "a\nb\nc" .t2 tag configure e -elide 1 set res {} lappend res [.t2 search -backward a 1.0] lappend res [.t2 search -backward b 1.0] lappend res [.t2 search -backward c 1.0] .t2 tag add e 1.0 2.0 lappend res [.t2 search -backward a 1.0] lappend res [.t2 search -backward b 1.0] lappend res [.t2 search -backward c 1.0] lappend res [.t2 search -backward -elide a 1.0] lappend res [.t2 search -backward -elide b 1.0] lappend res [.t2 search -backward -elide c 1.0] } {1.0 2.0 3.0 {} 2.0 3.0 1.0 2.0 3.0} test text-20.184 {TextSearchCmd, elide up to match} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "aa\nbb\ncc" .t2 tag configure e -elide 1 set res {} lappend res [.t2 search ab 1.0] lappend res [.t2 search bc 1.0] .t2 tag add e 1.1 2.1 lappend res [.t2 search ab 1.0] lappend res [.t2 search b 1.0] .t2 tag remove e 1.0 end .t2 tag add e 2.1 3.1 lappend res [.t2 search bc 1.0] lappend res [.t2 search c 1.0] .t2 tag remove e 1.0 end .t2 tag add e 2.1 3.0 lappend res [.t2 search bc 1.0] lappend res [.t2 search c 1.0] } {{} {} 1.0 2.1 2.0 3.1 2.0 3.0} test text-20.185 {TextSearchCmd, elide up to match} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "aa\nbb\ncc" .t2 tag configure e -elide 1 set res {} lappend res [.t2 search -regexp ab 1.0] lappend res [.t2 search -regexp bc 1.0] .t2 tag add e 1.1 2.1 lappend res [.t2 search -regexp ab 1.0] lappend res [.t2 search -regexp b 1.0] .t2 tag remove e 1.0 end .t2 tag add e 2.1 3.1 lappend res [.t2 search -regexp bc 1.0] lappend res [.t2 search -regexp c 1.0] .t2 tag remove e 1.0 end .t2 tag add e 2.1 3.0 lappend res [.t2 search -regexp bc 1.0] lappend res [.t2 search -regexp c 1.0] } {{} {} 1.0 2.1 2.0 3.1 2.0 3.0} test text-20.186 {TextSearchCmd, strict limits} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "Hello world!\nThis is a test\n" .t2 search -strictlimits -- "world" 1.3 1.8 } {} test text-20.187 {TextSearchCmd, strict limits} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "Hello world!\nThis is a test\n" .t2 search -strictlimits -- "world" 1.3 1.10 } {} test text-20.188 {TextSearchCmd, strict limits} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "Hello world!\nThis is a test\n" .t2 search -strictlimits -- "world" 1.3 1.11 } {1.6} test text-20.189 {TextSearchCmd, strict limits backwards} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "Hello world!\nThis is a test\n" .t2 search -strictlimits -backward -- "world" 2.3 1.8 } {} test text-20.190 {TextSearchCmd, strict limits backwards} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "Hello world!\nThis is a test\n" .t2 search -strictlimits -backward -- "world" 2.3 1.6 } {1.6} test text-20.191 {TextSearchCmd, strict limits backwards} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "Hello world!\nThis is a test\n" .t2 search -strictlimits -backward -- "world" 2.3 1.7 } {} test text-20.192 {TextSearchCmd, strict limits} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "Hello world!\nThis is a test\n" .t2 search -regexp -strictlimits -- "world" 1.3 1.8 } {} test text-20.193 {TextSearchCmd, strict limits} { deleteWindows pack [scintilla .t2] .t2 insert 1.0 "Hello world!\nThis is a test\n" .t2 search -regexp -strictlimits -backward -- "world" 2.3 1.8 } {} deleteWindows #scintilla .t2 -highlightthickness 0 -borderwidth 0 -relief flat -padx 0 -width 100 scintilla .t2 -highlightthickness 0 -borderwidth 0 -relief flat -width 100 pack .t2 .t2 insert end "1\t2\t3\t4\t55.5" test text-21.1 {TkTextGetTabs procedure} { list [catch {.t2 configure -tabs "\{{}"} msg] $msg } {1 {unmatched open brace in list}} test text-21.2 {TkTextGetTabs procedure} { list [catch {.t2 configure -tabs xyz} msg] $msg } {1 {bad screen distance "xyz"}} test text-21.3 {TkTextGetTabs procedure} { .t2 configure -tabs {100 200} update idletasks list [lindex [.t2 bbox 1.2] 0] [lindex [.t2 bbox 1.4] 0] } {100 200} test text-21.4 {TkTextGetTabs procedure} { .t2 configure -tabs {100 right 200 left 300 center 400 numeric} update idletasks list [expr [lindex [.t2 bbox 1.2] 0] + [lindex [.t2 bbox 1.2] 2]] \ [lindex [.t2 bbox 1.4] 0] \ [expr [lindex [.t2 bbox 1.6] 0] + [lindex [.t2 bbox 1.6] 2]/2] \ [lindex [.t2 bbox 1.10] 0] } {100 200 300 400} test text-21.5 {TkTextGetTabs procedure} { .t2 configure -tabs {105 r 205 l 305 c 405 n} update idletasks list [expr [lindex [.t2 bbox 1.2] 0] + [lindex [.t2 bbox 1.2] 2]] \ [lindex [.t2 bbox 1.4] 0] \ [expr [lindex [.t2 bbox 1.6] 0] + [lindex [.t2 bbox 1.6] 2]/2] \ [lindex [.t2 bbox 1.10] 0] } {105 205 305 405} test text-21.6 {TkTextGetTabs procedure} { list [catch {.t2 configure -tabs {100 left 200 lork}} msg] $msg } {1 {bad tab alignment "lork": must be left, right, center, or numeric}} test text-21.7 {TkTextGetTabs procedure} { list [catch {.t2 configure -tabs {100 !44 200 lork}} msg] $msg } {1 {bad screen distance "!44"}} deleteWindows scintilla .t pack .t .t insert 1.0 "One Line" .t mark set insert 1.0 test text-22.1 {TextDumpCmd procedure, bad args} { list [catch {.t dump} msg] $msg } {1 {Usage: .t dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?}} test text-22.2 {TextDumpCmd procedure, bad args} { list [catch {.t dump -all} msg] $msg } {1 {Usage: .t dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?}} test text-22.3 {TextDumpCmd procedure, bad args} { list [catch {.t dump -command} msg] $msg } {1 {Usage: .t dump ?-all -image -text -mark -tag -window? ?-command script? index ?index2?}} test text-22.4 {TextDumpCmd procedure, bad args} { list [catch {.t dump -bogus} msg] $msg } {1 {bad option "-bogus": must be -all, -command, -image, -mark, -tag, -text, or -window}} test text-22.5 {TextDumpCmd procedure, bad args} { list [catch {.t dump bogus} msg] $msg } {1 {bad text index "bogus"}} test text-22.6 {TextDumpCmd procedure, one index} { .t dump -text 1.2 } {text e 1.2} test text-22.7 {TextDumpCmd procedure, two indices} { .t dump -text 1.0 1.end } {text {One Line} 1.0} test text-22.8 {TextDumpCmd procedure, "end" index} { .t dump -text 1.end end } {text { } 1.8} test text-22.9 {TextDumpCmd procedure, same indices} { .t dump 1.5 1.5 } {} test text-22.10 {TextDumpCmd procedure, negative range} { .t dump 1.5 1.0 } {} .t delete 1.0 end .t insert end "Line One\nLine Two\nLine Three\nLine Four" .t mark set insert 1.0 .t mark set current 1.0 test text-22.11 {TextDumpCmd procedure, stop at begin-line} { .t dump -text 1.0 2.0 } {text {Line One } 1.0} test text-22.12 {TextDumpCmd procedure, span multiple lines} { .t dump -text 1.5 3.end } {text {One } 1.5 text {Line Two } 2.0 text {Line Three} 3.0} .t tag add x 2.0 2.end .t tag add y 1.0 end .t mark set m 2.4 .t mark set n 4.0 .t mark set END end test text-22.13 {TextDumpCmd procedure, tags only} { .t dump -tag 2.1 2.8 } {} test text-22.14 {TextDumpCmd procedure, tags only} { .t dump -tag 2.0 2.8 } {tagon x 2.0} test text-22.15 {TextDumpCmd procedure, tags only} { .t dump -tag 1.0 4.end } {tagon y 1.0 tagon x 2.0 tagoff x 2.8} test text-22.16 {TextDumpCmd procedure, tags only} { .t dump -tag 1.0 end } {tagon y 1.0 tagon x 2.0 tagoff x 2.8 tagoff y 5.0} .t mark set insert 1.0 .t mark set current 1.0 test text-22.17 {TextDumpCmd procedure, marks only} { .t dump -mark 1.1 1.8 } {} test text-22.18 {TextDumpCmd procedure, marks only} { .t dump -mark 2.0 2.8 } {mark m 2.4} test text-22.19 {TextDumpCmd procedure, marks only} { .t dump -mark 1.1 4.end } {mark m 2.4 mark n 4.0} test text-22.20 {TextDumpCmd procedure, marks only} { .t dump -mark 1.0 end } {mark current 1.0 mark insert 1.0 mark m 2.4 mark n 4.0 mark END 5.0} button .hello -text Hello catch {.t window create 3.end -window .hello} for {set i 0} {$i < 100} {incr i} { .t insert end "-\n" } catch {.t window create 100.0 -create { }} test text-22.21 {TextDumpCmd procedure, windows only} { .t dump -window 1.0 5.0 } {window .hello 3.10} test text-22.22 {TextDumpCmd procedure, windows only} { .t dump -window 5.0 end } {window {} 100.0} .t delete 1.0 end eval {.t mark unset} [.t mark names] .t insert end "Line One\nLine Two\nLine Three\nLine Four" .t mark set insert 1.0 .t mark set current 1.0 .t tag add x 2.0 2.end .t mark set m 2.4 proc Append {varName key value index} { upvar #0 $varName x lappend x $key $index $value } test text-22.23 {TextDumpCmd procedure, command script} { set x {} .t dump -command {Append x} -all 1.0 end set x } {mark 1.0 current mark 1.0 insert text 1.0 {Line One } tagon 2.0 x text 2.0 Line mark 2.4 m text 2.4 { Two} tagoff 2.8 x text 2.8 { } text 3.0 {Line Three } text 4.0 {Line Four }} test text-22.24 {TextDumpCmd procedure, command script} { set x {} .t dump -mark -command {Append x} 1.0 end set x } {mark 1.0 current mark 1.0 insert mark 2.4 m} catch {unset x} test text-22.25 {TextDumpCmd procedure, unicode characters} { catch {destroy .t} scintilla .t .t delete 1.0 end .t insert 1.0 \xb1\xb1\xb1 .t dump -all 1.0 2.0 } "text \xb1\xb1\xb1 1.0 mark insert 1.3 mark current 1.3 text {\n} 1.3" test text-22.26 {TextDumpCmd procedure, unicode characters} { catch {destroy .t} scintilla .t .t delete 1.0 end .t insert 1.0 abc\xb1\xb1\xb1 .t dump -all 1.0 2.0 } "text abc\xb1\xb1\xb1 1.0 mark insert 1.6 mark current 1.6 text {\n} 1.6" set l [interp hidden] deleteWindows test text-23.1 {text widget vs hidden commands} { catch {destroy .t} scintilla .t interp hide {} .t destroy .t list [winfo children .] [interp hidden] } [list {} $l] test text-24.1 {bug fix - 1642} { catch {destroy .t} scintilla .t pack .t .t insert end "line 1\n" .t insert end "line 2\n" .t insert end "line 3\n" .t insert end "line 4\n" .t insert end "line 5\n" tk::TextSetCursor .t 3.0 .t search -backward -regexp "\$" insert 1.0 } {2.6} test text-25.1 {TextEditCmd procedure, argument parsing} { list [catch {.t edit} msg] $msg } {1 {wrong # args: should be ".t edit option ?arg arg ...?"}} test text-25.2 {TextEditCmd procedure, argument parsing} { list [catch {.t edit gorp} msg] $msg } {1 {bad edit option "gorp": must be modified, redo, reset, separator, or undo}} test text-25.3 {TextEditUndo procedure, undoing changes} { catch {destroy .t} scintilla .t -undo 1 pack .t .t insert end "line 1\n" .t delete 1.4 1.6 .t insert end "should be gone after undo\n" .t edit undo .t get 1.0 end } "line\n\n" test text-25.4 {TextEditRedo procedure, redoing changes} { catch {destroy .t} scintilla .t -undo 1 pack .t .t insert end "line 1\n" .t delete 1.4 1.6 .t insert end "should be back after redo\n" .t edit undo .t edit redo .t get 1.0 end } "line\nshould be back after redo\n\n" test text-25.5 {TextEditUndo procedure, resetting stack} { catch {destroy .t} scintilla .t -undo 1 pack .t .t insert end "line 1\n" .t delete 1.4 1.6 .t insert end "should be back after redo\n" .t edit reset catch {.t edit undo} msg set msg } "nothing to undo" test text-25.6 {TextEditCmd procedure, insert separator} { catch {destroy .t} scintilla .t -undo 1 pack .t .t insert end "line 1\n" .t edit separator .t insert end "line 2\n" .t edit undo .t get 1.0 end } "line 1\n\n" test text-25.7 {-autoseparators configuration option} { catch {destroy .t} scintilla .t -undo 1 -autoseparators 0 pack .t .t insert end "line 1\n" .t delete 1.4 1.6 .t insert end "line 2\n" .t edit undo .t get 1.0 end } "\n" test text-25.8 {TextEditCmd procedure, modified flag} { catch {destroy .t} scintilla .t pack .t .t insert end "line 1\n" .t edit modified } {1} test text-25.9 {TextEditCmd procedure, reset modified flag} { catch {destroy .t} scintilla .t pack .t .t insert end "line 1\n" .t edit modified 0 .t edit modified } {0} test text-25.10 {TextEditCmd procedure, set modified flag} { catch {destroy .t} scintilla .t pack .t .t edit modified 1 .t edit modified } {1} test text-25.10.1 {TextEditCmd procedure, set modified flag repeat} { catch {destroy .t} scintilla .t pack .t set ::retval {} bind .t <<Modified>> "lappend ::retval modified" # Shouldn't require [update idle] to trigger event [Bug 1809538] lappend ::retval [.t edit modified] .t edit modified 1 update idletasks lappend ::retval [.t edit modified] .t edit modified 1 ; # binding should only fire once [Bug 1799782] update idletasks lappend ::retval [.t edit modified] } {0 modified 1 1} test text-25.11 {<<Modified>> virtual event} { set ::retval unmodified catch {destroy .t} scintilla .t -undo 1 pack .t bind .t <<Modified>> "set ::retval modified" update idletasks .t insert end "nothing special\n" set ::retval } {modified} test text-25.11.1 {<<Modified>> virtual event - insert before Modified} { set ::retval {} destroy .t pack [scintilla .t -undo 1] bind .t <<Modified>> { set ::retval [.t get 1.0 end-1c] } update idletasks .t insert end "nothing special" set ::retval } {nothing special} test text-25.11.2 {<<Modified>> virtual event - delete before Modified} { # Bug 1737288, make sure we delete chars before triggering <<Modified>> set ::retval {} destroy .t pack [scintilla .t -undo 1] bind .t <<Modified>> { set ::retval [.t get 1.0 end-1c] } .t insert end "nothing special" .t edit modified 0 .t delete 1.0 1.2 set ::retval } {thing special} test text-25.12 {<<Selection>> virtual event} { set ::retval no_selection catch {destroy .t} scintilla .t -undo 1 pack .t bind .t <<Selection>> "set ::retval selection_changed" update idletasks .t insert end "nothing special\n" .t tag add sel 1.0 1.1 set ::retval } {selection_changed} test text-25.13 {-maxundo configuration option} { catch {destroy .t} scintilla .t -undo 1 -autoseparators 1 -maxundo 2 pack .t .t insert end "line 1\n" .t delete 1.4 1.6 .t insert end "line 2\n" catch {.t edit undo} catch {.t edit undo} catch {.t edit undo} .t get 1.0 end } "line 1\n\n" test text-25.15 {bug fix 1536735 - undo with empty text} { catch {destroy .t} scintilla .t -undo 1 set r [.t edit modified] .t delete 1.0 lappend r [.t edit modified] lappend r [catch {.t edit undo}] lappend r [.t edit modified] } {0 0 1 0} test text-25.18 {patch 1469210 - inserting after undo} -setup { destroy .t } -body { scintilla .t -undo 1 .t insert end foo .t edit modified 0 .t edit undo .t insert end bar .t edit modified } -cleanup { destroy .t } -result 1 test text-26.1 {bug fix - 624372, ControlUtfProc long lines} { destroy .t pack [scintilla .t -wrap none] .t insert end [string repeat "\1" 500] } {} test text-27.1 {tabs - must be positive and must be increasing} { destroy .t pack [scintilla .t -wrap none] list [catch {.t configure -tabs {0}} msg] $msg } {1 {tab stop "0" is not at a positive distance}} test text-27.2 {tabs - must be positive and must be increasing} { destroy .t pack [scintilla .t -wrap none] list [catch {.t configure -tabs {-5}} msg] $msg } {1 {tab stop "-5" is not at a positive distance}} test text-27.3 {tabs - must be positive and must be increasing} {knownBug} { # This bug will be fixed in Tk 9.0, when we can allow a minor # incompatibility with Tk 8.x destroy .t pack [scintilla .t -wrap none] list [catch {.t configure -tabs {10c 5c}} msg] $msg } {1 {tabs must be monotonically increasing, but "5c" is smaller than or equal to the previous tab}} test text-27.4 {tabs - must be positive and must be increasing} { destroy .t pack [scintilla .t -wrap none] .t insert end "a\tb\tc\td\te" catch {.t configure -tabs {10c 5c}} update ; update ; update # This test must simply not go into an infinite loop to succeed set result 1 } {1} test text-28.0 {repeated insert and scroll} { foreach subcmd { {moveto 1} {scroll 1 pages} {scroll 100 pixels} {scroll 10 units} } { destroy .t pack [scintilla .t] for {set i 0} {$i < 30} {incr i} { .t insert end "blabla\n" eval .t yview $subcmd } } # This test must simply not crash to succeed set result 1 } {1} test text-29.0 {peer widgets} { destroy .t .tt toplevel .tt pack [scintilla .t] pack [.t peer create .tt.t] destroy .t .tt } {} test text-29.1 {peer widgets} { destroy .t .t1 .t2 toplevel .t1 toplevel .t2 pack [scintilla .t] pack [.t peer create .t1.t] pack [.t peer create .t2.t] .t insert end "abcd\nabcd" update destroy .t1 update .t insert end "abcd\nabcd" update destroy .t .t2 update } {} test text-29.2 {peer widgets} { destroy .t .t1 .t2 toplevel .t1 toplevel .t2 pack [scintilla .t] pack [.t peer create .t1.t] pack [.t peer create .t2.t] .t insert end "abcd\nabcd" update destroy .t update .t2.t insert end "abcd\nabcd" update destroy .t .t2 update } {} test text-29.3 {peer widgets} { destroy .t .tt toplevel .tt pack [scintilla .t] for {set i 1} {$i < 20} {incr i} { .t insert end "Line $i\n" } pack [.t peer create .tt.t -start 5 -end 11] update destroy .t .tt } {} test text-29.4 {peer widgets} { destroy .t .tt toplevel .tt pack [scintilla .t] for {set i 1} {$i < 20} {incr i} { .t insert end "Line $i\n" } pack [.t peer create .tt.t -start 5 -end 11] pack [.tt.t peer create .tt.t2] set res [list [.tt.t index end] [.tt.t2 index end]] update destroy .t .tt set res } {7.0 7.0} test text-29.4.1 {peer widgets} { destroy .t .tt toplevel .tt pack [scintilla .t] for {set i 1} {$i < 20} {incr i} { .t insert end "Line $i\n" } pack [.t peer create .tt.t -start 5 -end 11] pack [.tt.t peer create .tt.t2 -start {} -end {}] set res [list [.tt.t index end] [.tt.t2 index end]] update destroy .t .tt set res } {7.0 21.0} test text-29.5 {peer widgets} { destroy .t .tt toplevel .tt pack [scintilla .t] for {set i 1} {$i < 20} {incr i} { .t insert end "Line $i\n" } pack [.t peer create .tt.t -start 5 -end 11] update ; update set p1 [.tt.t count -update -ypixels 1.0 end] set p2 [.t count -update -ypixels 5.0 11.0] if {$p1 == $p2} { set res "ok" } else { set res "$p1 and $p2 not equal" } destroy .t .tt set res } {ok} test text-29.6 {peer widgets} { destroy .t .tt toplevel .tt pack [scintilla .t] for {set i 1} {$i < 20} {incr i} { .t insert end "Line $i\n" } pack [.t peer create .tt.t -start 5 -end 11] update ; update .t delete 3.0 6.0 set res [.tt.t index end] destroy .t .tt set res } {6.0} test text-29.7 {peer widgets} { destroy .t .tt toplevel .tt pack [scintilla .t] for {set i 1} {$i < 20} {incr i} { .t insert end "Line $i\n" } pack [.t peer create .tt.t -start 5 -end 11] update ; update .t delete 8.0 12.0 set res [.tt.t index end] destroy .t .tt set res } {4.0} test text-29.8 {peer widgets} { destroy .t .tt toplevel .tt pack [scintilla .t] for {set i 1} {$i < 20} {incr i} { .t insert end "Line $i\n" } pack [.t peer create .tt.t -start 5 -end 11] update ; update .t delete 3.0 13.0 set res [.tt.t index end] destroy .t .tt set res } {1.0} test text-29.9 {peer widgets} { destroy .t pack [scintilla .t] for {set i 1} {$i < 100} {incr i} { .t insert end "Line $i\n" } .t tag add sel 1.0 end-1c set res {} lappend res [.t tag ranges sel] .t configure -start 10 -end 20 lappend res [.t tag ranges sel] destroy .t set res } {{1.0 100.0} {1.0 11.0}} test text-29.10 {peer widgets} { destroy .t pack [scintilla .t] for {set i 1} {$i < 100} {incr i} { .t insert end "Line $i\n" } .t tag add sel 1.0 end-1c set res {} lappend res [.t tag ranges sel] .t configure -start 11 lappend res [.t tag ranges sel] destroy .t set res } {{1.0 100.0} {1.0 90.0}} test text-29.11 {peer widgets} { destroy .t pack [scintilla .t] for {set i 1} {$i < 100} {incr i} { .t insert end "Line $i\n" } .t tag add sel 1.0 end-1c set res {} lappend res [.t tag ranges sel] .t configure -end 90 lappend res [.t tag ranges sel] destroy .t set res } {{1.0 100.0} {1.0 90.0}} test text-29.12 {peer widgets} { destroy .t pack [scintilla .t] for {set i 1} {$i < 20} {incr i} { .t insert end "Line $i\n" } .t tag add sel 1.0 3.0 5.0 7.0 9.0 11.0 13.0 15.0 17.0 19.0 set res {} lappend res [.t tag prevrange sel 1.0] .t configure -start 6 -end 12 lappend res [.t tag ranges sel] lappend res "next" [.t tag nextrange sel 4.0] \ [.t tag nextrange sel 5.0] [.t tag nextrange sel 6.0] \ [.t tag nextrange sel 7.0] lappend res "prev" [.t tag prevrange sel 1.0] \ [.t tag prevrange sel 2.0] [.t tag prevrange sel 3.0] \ [.t tag prevrange sel 4.0] destroy .t set res } {{} {1.0 2.0 4.0 6.0} next {4.0 6.0} {} {} {} prev {} {1.0 2.0} {1.0 2.0} {1.0 2.0}} test text-29.13 {peer widgets} { destroy .t pack [scintilla .t] for {set i 1} {$i < 20} {incr i} { .t insert end "Line $i\n" } .t tag add sel 1.0 3.0 9.0 11.0 13.0 15.0 17.0 19.0 set res {} .t configure -start 6 -end 12 lappend res [.t tag ranges sel] lappend res "next" [.t tag nextrange sel 4.0] \ [.t tag nextrange sel 5.0] [.t tag nextrange sel 6.0] \ [.t tag nextrange sel 7.0] lappend res "prev" [.t tag prevrange sel 1.0] \ [.t tag prevrange sel 2.0] [.t tag prevrange sel 3.0] \ [.t tag prevrange sel 4.0] destroy .t set res } {{4.0 6.0} next {4.0 6.0} {} {} {} prev {} {} {} {}} test text-29.14 {peer widgets} { destroy .t pack [scintilla .t] for {set i 1} {$i < 20} {incr i} { .t insert end "Line $i\n" } .t tag add sel 1.0 7.0 9.0 11.0 13.0 15.0 17.0 19.0 set res {} .t configure -start 6 -end 12 lappend res [.t tag ranges sel] lappend res "next" [.t tag nextrange sel 4.0] \ [.t tag nextrange sel 5.0] [.t tag nextrange sel 6.0] \ [.t tag nextrange sel 7.0] lappend res "prev" [.t tag prevrange sel 1.0] \ [.t tag prevrange sel 2.0] [.t tag prevrange sel 3.0] \ [.t tag prevrange sel 4.0] destroy .t set res } {{1.0 2.0 4.0 6.0} next {4.0 6.0} {} {} {} prev {} {1.0 2.0} {1.0 2.0} {1.0 2.0}} test text-29.15 {peer widgets} { destroy .t pack [scintilla .t] for {set i 1} {$i < 20} {incr i} { .t insert end "Line $i\n" } set res {} .t tag add sel 1.0 11.0 lappend res [.t tag ranges sel] lappend res [catch {.t configure -start 15 -end 10}] lappend res [.t tag ranges sel] .t configure -start 6 -end 12 lappend res [.t tag ranges sel] .t configure -start {} -end {} lappend res [.t tag ranges sel] destroy .t set res } {{1.0 11.0} 1 {1.0 11.0} {1.0 6.0} {1.0 11.0}} test text-29.16 {peer widgets} { destroy .t pack [scintilla .t] for {set i 1} {$i < 20} {incr i} { .t insert end "Line $i\n" } set res {} .t tag add sel 1.0 11.0 lappend res [.t index sel.first] lappend res [.t index sel.last] destroy .t set res } {1.0 11.0} test text-29.17 {peer widgets} { destroy .t pack [scintilla .t] for {set i 1} {$i < 20} {incr i} { .t insert end "Line $i\n" } set res {} .t tag delete sel set res [list [catch {.t index sel.first} msg] $msg] destroy .t set res } {1 {text doesn't contain any characters tagged with "sel"}} proc makeText {} { set w .g set font "Times 11" destroy .g toplevel .g frame $w.f -highlightthickness 2 -borderwidth 2 -relief sunken set t $w.f.text scintilla $t -yscrollcommand "$w.scroll set" -setgrid true -font $font -width 70 \ -height 35 -wrap word -highlightthickness 0 -borderwidth 0 pack $t -expand yes -fill both scrollbar $w.scroll -command "$t yview" pack $w.scroll -side right -fill y pack $w.f -expand yes -fill both $t tag configure center -justify center -spacing1 5m -spacing3 5m $t tag configure buttons -lmargin1 1c -lmargin2 1c -rmargin 1c \ -spacing1 3m -spacing2 0 -spacing3 0 for {set i 0} {$i < 40} {incr i} { $t insert end "${i}word " } return $t } test text-30.1 {line heights on creation} { set w [makeText] update ; after 1000 ; update set before [$w count -ypixels 1.0 2.0] $w insert 1.0 "a" update set after [$w count -ypixels 1.0 2.0] destroy .g if {$before != $after} { set res "Count changed: $before $after" } else { set res "ok" } } {ok} destroy .t scintilla .t test text-31.1 {TextWidgetCmd procedure, "peer" option} { list [catch {.t peer foo 1} msg] $msg } {1 {bad peer option "foo": must be create or names}} test text-31.2 {TextWidgetCmd procedure, "peer" option} { list [catch {.t peer names foo} msg] $msg } {1 {wrong # args: should be ".t peer names"}} test text-31.3 {TextWidgetCmd procedure, "peer" option} { list [catch {.t p names} msg] $msg } {0 {}} test text-31.4 {TextWidgetCmd procedure, "peer" option} { .t peer names } {} test text-31.5 {TextWidgetCmd procedure, "peer" option} { list [catch {.t peer create foo} msg] $msg } {1 {bad window path name "foo"}} test text-31.6 {TextWidgetCmd procedure, "peer" option} { .t peer create .t2 set res {} lappend res [.t peer names] lappend res [.t2 peer names] destroy .t2 lappend res [.t peer names] } {.t2 .t {}} test text-31.7 {peer widget -start, -end} { set res [list [catch {.t configure -start 10 -end 5} msg] $msg] .t configure -start {} -end {} set res } {0 {}} test text-31.8 {peer widget -start, -end} { .t delete 1.0 end for {set i 1} {$i < 100} {incr i} { .t insert end "Line $i\n" } list [catch {.t configure -start 10 -end 5} msg] $msg } {1 {-startline must be less than or equal to -endline}} test text-31.9 {peer widget -start, -end} { .t delete 1.0 end for {set i 1} {$i < 100} {incr i} { .t insert end "Line $i\n" } set res [list [catch {.t configure -start 5 -end 10} msg] $msg] .t configure -start {} -end {} set res } {0 {}} test text-31.10 {peer widget -start, -end} { .t delete 1.0 end for {set i 1} {$i < 100} {incr i} { .t insert end "Line $i\n" } set res [.t index end] lappend res [catch {.t configure -start 5 -end 10 -tab foo}] lappend res [.t index end] lappend res [catch {.t configure -tab foo -start 15 -end 20}] lappend res [.t index end] .t configure -start {} -end {} lappend res [.t index end] set res } {101.0 1 101.0 1 101.0 101.0} test text-31.11 {peer widget -start, -end} { .t delete 1.0 end for {set i 1} {$i < 100} {incr i} { .t insert end "Line $i\n" } set res [.t index end] lappend res [catch {.t configure -start 5 -end 15}] lappend res [.t index end] lappend res [catch {.t configure -start 10 -end 40}] lappend res [.t index end] .t configure -start {} -end {} lappend res [.t index end] set res } {101.0 0 11.0 0 31.0 101.0} test text-32.1 {peer widget -start, -end and selection} { .t delete 1.0 end for {set i 1} {$i < 100} {incr i} { .t insert end "Line $i\n" } .t tag add sel 10.0 20.0 set res {} lappend res [.t tag ranges sel] .t configure -start 5 -end 30 lappend res [.t tag ranges sel] .t configure -start 5 -end 15 lappend res [.t tag ranges sel] .t configure -start 15 -end 30 lappend res [.t tag ranges sel] .t configure -start 15 -end 16 lappend res [.t tag ranges sel] .t configure -start 25 -end 30 lappend res [.t tag ranges sel] .t configure -start {} -end {} lappend res [.t tag ranges sel] set res } {{10.0 20.0} {6.0 16.0} {6.0 11.0} {1.0 6.0} {1.0 2.0} {} {10.0 20.0}} test text-33.1 {widget dump -command alters tags} { .t delete 1.0 end .t insert end "abc\n" a "---" {} "def" b " \n" {} "ghi\n" c .t tag configure b -background red proc Dumpy {key value index} { #puts "KK: $key, $value" .t tag add $value [list $index linestart] [list $index lineend] } .t dump -all -command Dumpy 1.0 end set result "ok" } {ok} test text-33.2 {widget dump -command makes massive changes} { .t delete 1.0 end .t insert end "abc\n" a "---" {} "def" b " \n" {} "ghi\n" c .t tag configure b -background red proc Dumpy {key value index} { #puts "KK: $key, $value" .t delete 1.0 end } .t dump -all -command Dumpy 1.0 end set result "ok" } {ok} test text-33.3 {widget dump -command destroys widget} { .t delete 1.0 end .t insert end "abc\n" a "---" {} "def" b " \n" {} "ghi\n" c .t tag configure b -background red proc Dumpy {key value index} { #puts "KK: $key, $value" destroy .t } .t dump -all -command Dumpy 1.0 end set result "ok" } {ok} exit |
Added version.txt.
> |
1 |
330
|
Added win32/CheckD2D.cxx.
> > > |
1 2 3 |
// This file is compiled to check whether Direct2D and DirectWrite headers are available. #include <d2d1.h> #include <dwrite.h> |
Added win32/PlatWin.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 |
// Scintilla source code edit control /** @file PlatWin.cxx ** Implementation of platform facilities on Windows. **/ // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdarg.h> #include <stdio.h> #include <time.h> #include <limits.h> #include <math.h> #include <vector> #include <map> #undef _WIN32_WINNT #define _WIN32_WINNT 0x0500 #undef WINVER #define WINVER 0x0500 #include <windows.h> #include <commctrl.h> #include <richedit.h> #include <windowsx.h> #if defined(NTDDI_WIN7) && !defined(DISABLE_D2D) #define USE_D2D 1 #endif #if defined(USE_D2D) #include <d2d1.h> #include <dwrite.h> #endif #include "Platform.h" #include "UniConversion.h" #include "XPM.h" #include "FontQuality.h" #ifndef IDC_HAND #define IDC_HAND MAKEINTRESOURCE(32649) #endif // Take care of 32/64 bit pointers #ifdef GetWindowLongPtr static void *PointerFromWindow(HWND hWnd) { return reinterpret_cast<void *>(::GetWindowLongPtr(hWnd, 0)); } static void SetWindowPointer(HWND hWnd, void *ptr) { ::SetWindowLongPtr(hWnd, 0, reinterpret_cast<LONG_PTR>(ptr)); } #else static void *PointerFromWindow(HWND hWnd) { return reinterpret_cast<void *>(::GetWindowLong(hWnd, 0)); } static void SetWindowPointer(HWND hWnd, void *ptr) { ::SetWindowLong(hWnd, 0, reinterpret_cast<LONG>(ptr)); } #ifndef GWLP_USERDATA #define GWLP_USERDATA GWL_USERDATA #endif #ifndef GWLP_WNDPROC #define GWLP_WNDPROC GWL_WNDPROC #endif #ifndef LONG_PTR #define LONG_PTR LONG #endif static LONG_PTR SetWindowLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong) { return ::SetWindowLong(hWnd, nIndex, dwNewLong); } static LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex) { return ::GetWindowLong(hWnd, nIndex); } #endif // Declarations needed for functions dynamically loaded as not available on all Windows versions. typedef BOOL (WINAPI *AlphaBlendSig)(HDC, int, int, int, int, HDC, int, int, int, int, BLENDFUNCTION); typedef HMONITOR (WINAPI *MonitorFromPointSig)(POINT, DWORD); typedef HMONITOR (WINAPI *MonitorFromRectSig)(LPCRECT, DWORD); typedef BOOL (WINAPI *GetMonitorInfoSig)(HMONITOR, LPMONITORINFO); static CRITICAL_SECTION crPlatformLock; static HINSTANCE hinstPlatformRes = 0; static bool onNT = false; static HMODULE hDLLImage = 0; static AlphaBlendSig AlphaBlendFn = 0; static HMODULE hDLLUser32 = 0; static HMONITOR (WINAPI *MonitorFromPointFn)(POINT, DWORD) = 0; static HMONITOR (WINAPI *MonitorFromRectFn)(LPCRECT, DWORD) = 0; static BOOL (WINAPI *GetMonitorInfoFn)(HMONITOR, LPMONITORINFO) = 0; static HCURSOR reverseArrowCursor = NULL; bool IsNT() { return onNT; } #ifdef SCI_NAMESPACE using namespace Scintilla; #endif Point Point::FromLong(long lpoint) { return Point(static_cast<short>(LOWORD(lpoint)), static_cast<short>(HIWORD(lpoint))); } static RECT RectFromPRectangle(PRectangle prc) { RECT rc = {static_cast<LONG>(prc.left), static_cast<LONG>(prc.top), static_cast<LONG>(prc.right), static_cast<LONG>(prc.bottom)}; return rc; } #if defined(USE_D2D) IDWriteFactory *pIDWriteFactory = 0; ID2D1Factory *pD2DFactory = 0; bool LoadD2D() { static bool triedLoadingD2D = false; static HMODULE hDLLD2D = 0; static HMODULE hDLLDWrite = 0; if (!triedLoadingD2D) { typedef HRESULT (WINAPI *D2D1CFSig)(D2D1_FACTORY_TYPE factoryType, REFIID riid, CONST D2D1_FACTORY_OPTIONS *pFactoryOptions, IUnknown **factory); typedef HRESULT (WINAPI *DWriteCFSig)(DWRITE_FACTORY_TYPE factoryType, REFIID iid, IUnknown **factory); hDLLD2D = ::LoadLibraryEx(TEXT("D2D1.DLL"), 0, 0x00000800 /*LOAD_LIBRARY_SEARCH_SYSTEM32*/); if (hDLLD2D) { D2D1CFSig fnD2DCF = (D2D1CFSig)::GetProcAddress(hDLLD2D, "D2D1CreateFactory"); if (fnD2DCF) { // A single threaded factory as Scintilla always draw on the GUI thread fnD2DCF(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory), 0, reinterpret_cast<IUnknown**>(&pD2DFactory)); } } hDLLDWrite = ::LoadLibraryEx(TEXT("DWRITE.DLL"), 0, 0x00000800 /*LOAD_LIBRARY_SEARCH_SYSTEM32*/); if (hDLLDWrite) { DWriteCFSig fnDWCF = (DWriteCFSig)::GetProcAddress(hDLLDWrite, "DWriteCreateFactory"); if (fnDWCF) { fnDWCF(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&pIDWriteFactory)); } } } triedLoadingD2D = true; return pIDWriteFactory && pD2DFactory; } #endif struct FormatAndMetrics { int technology; HFONT hfont; #if defined(USE_D2D) IDWriteTextFormat *pTextFormat; #endif int extraFontFlag; FLOAT yAscent; FLOAT yDescent; FLOAT yInternalLeading; FormatAndMetrics(HFONT hfont_, int extraFontFlag_) : technology(SCWIN_TECH_GDI), hfont(hfont_), #if defined(USE_D2D) pTextFormat(0), #endif extraFontFlag(extraFontFlag_), yAscent(2), yDescent(1), yInternalLeading(0) { } #if defined(USE_D2D) FormatAndMetrics(IDWriteTextFormat *pTextFormat_, int extraFontFlag_, FLOAT yAscent_, FLOAT yDescent_, FLOAT yInternalLeading_) : technology(SCWIN_TECH_DIRECTWRITE), hfont(0), pTextFormat(pTextFormat_), extraFontFlag(extraFontFlag_), yAscent(yAscent_), yDescent(yDescent_), yInternalLeading(yInternalLeading_) { } #endif ~FormatAndMetrics() { if (hfont) ::DeleteObject(hfont); #if defined(USE_D2D) if (pTextFormat) pTextFormat->Release(); pTextFormat = 0; #endif extraFontFlag = 0; yAscent = 2; yDescent = 1; yInternalLeading = 0; } HFONT HFont(); }; HFONT FormatAndMetrics::HFont() { LOGFONTW lf; memset(&lf, 0, sizeof(lf)); #if defined(USE_D2D) if (technology == SCWIN_TECH_GDI) { if (0 == ::GetObjectW(hfont, sizeof(lf), &lf)) { return 0; } } else { HRESULT hr = pTextFormat->GetFontFamilyName(lf.lfFaceName, LF_FACESIZE); if (!SUCCEEDED(hr)) { return 0; } lf.lfWeight = pTextFormat->GetFontWeight(); lf.lfItalic = pTextFormat->GetFontStyle() == DWRITE_FONT_STYLE_ITALIC; lf.lfHeight = -static_cast<int>(pTextFormat->GetFontSize()); } #else if (0 == ::GetObjectW(hfont, sizeof(lf), &lf)) { return 0; } #endif return ::CreateFontIndirectW(&lf); } #ifndef CLEARTYPE_QUALITY #define CLEARTYPE_QUALITY 5 #endif static BYTE Win32MapFontQuality(int extraFontFlag) { switch (extraFontFlag & SC_EFF_QUALITY_MASK) { case SC_EFF_QUALITY_NON_ANTIALIASED: return NONANTIALIASED_QUALITY; case SC_EFF_QUALITY_ANTIALIASED: return ANTIALIASED_QUALITY; case SC_EFF_QUALITY_LCD_OPTIMIZED: return CLEARTYPE_QUALITY; default: return SC_EFF_QUALITY_DEFAULT; } } #if defined(USE_D2D) static D2D1_TEXT_ANTIALIAS_MODE DWriteMapFontQuality(int extraFontFlag) { switch (extraFontFlag & SC_EFF_QUALITY_MASK) { case SC_EFF_QUALITY_NON_ANTIALIASED: return D2D1_TEXT_ANTIALIAS_MODE_ALIASED; case SC_EFF_QUALITY_ANTIALIASED: return D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE; case SC_EFF_QUALITY_LCD_OPTIMIZED: return D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE; default: return D2D1_TEXT_ANTIALIAS_MODE_DEFAULT; } } #endif static void SetLogFont(LOGFONTA &lf, const char *faceName, int characterSet, float size, int weight, bool italic, int extraFontFlag) { memset(&lf, 0, sizeof(lf)); // The negative is to allow for leading lf.lfHeight = -(abs(static_cast<int>(size + 0.5))); lf.lfWeight = weight; lf.lfItalic = static_cast<BYTE>(italic ? 1 : 0); lf.lfCharSet = static_cast<BYTE>(characterSet); lf.lfQuality = Win32MapFontQuality(extraFontFlag); strncpy(lf.lfFaceName, faceName, sizeof(lf.lfFaceName)); } /** * Create a hash from the parameters for a font to allow easy checking for identity. * If one font is the same as another, its hash will be the same, but if the hash is the * same then they may still be different. */ static int HashFont(const FontParameters &fp) { return static_cast<int>(fp.size) ^ (fp.characterSet << 10) ^ ((fp.extraFontFlag & SC_EFF_QUALITY_MASK) << 9) ^ ((fp.weight/100) << 12) ^ (fp.italic ? 0x20000000 : 0) ^ (fp.technology << 15) ^ fp.faceName[0]; } class FontCached : Font { FontCached *next; int usage; float size; LOGFONTA lf; int technology; int hash; FontCached(const FontParameters &fp); ~FontCached() {} bool SameAs(const FontParameters &fp); virtual void Release(); static FontCached *first; public: static FontID FindOrCreate(const FontParameters &fp); static void ReleaseId(FontID fid_); }; FontCached *FontCached::first = 0; FontCached::FontCached(const FontParameters &fp) : next(0), usage(0), size(1.0), hash(0) { SetLogFont(lf, fp.faceName, fp.characterSet, fp.size, fp.weight, fp.italic, fp.extraFontFlag); technology = fp.technology; hash = HashFont(fp); fid = 0; if (technology == SCWIN_TECH_GDI) { HFONT hfont = ::CreateFontIndirectA(&lf); fid = reinterpret_cast<void *>(new FormatAndMetrics(hfont, fp.extraFontFlag)); } else { #if defined(USE_D2D) IDWriteTextFormat *pTextFormat; const int faceSize = 200; WCHAR wszFace[faceSize]; UTF16FromUTF8(fp.faceName, static_cast<unsigned int>(strlen(fp.faceName))+1, wszFace, faceSize); FLOAT fHeight = fp.size; DWRITE_FONT_STYLE style = fp.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL; HRESULT hr = pIDWriteFactory->CreateTextFormat(wszFace, NULL, static_cast<DWRITE_FONT_WEIGHT>(fp.weight), style, DWRITE_FONT_STRETCH_NORMAL, fHeight, L"en-us", &pTextFormat); if (SUCCEEDED(hr)) { pTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP); const int maxLines = 2; DWRITE_LINE_METRICS lineMetrics[maxLines]; UINT32 lineCount = 0; FLOAT yAscent = 1.0f; FLOAT yDescent = 1.0f; FLOAT yInternalLeading = 0.0f; IDWriteTextLayout *pTextLayout = 0; hr = pIDWriteFactory->CreateTextLayout(L"X", 1, pTextFormat, 100.0f, 100.0f, &pTextLayout); if (SUCCEEDED(hr)) { hr = pTextLayout->GetLineMetrics(lineMetrics, maxLines, &lineCount); if (SUCCEEDED(hr)) { yAscent = lineMetrics[0].baseline; yDescent = lineMetrics[0].height - lineMetrics[0].baseline; FLOAT emHeight; hr = pTextLayout->GetFontSize(0, &emHeight); if (SUCCEEDED(hr)) { yInternalLeading = lineMetrics[0].height - emHeight; } } pTextLayout->Release(); } fid = reinterpret_cast<void *>(new FormatAndMetrics(pTextFormat, fp.extraFontFlag, yAscent, yDescent, yInternalLeading)); } #endif } usage = 1; } bool FontCached::SameAs(const FontParameters &fp) { return (size == fp.size) && (lf.lfWeight == fp.weight) && (lf.lfItalic == static_cast<BYTE>(fp.italic ? 1 : 0)) && (lf.lfCharSet == fp.characterSet) && (lf.lfQuality == Win32MapFontQuality(fp.extraFontFlag)) && (technology == fp.technology) && 0 == strcmp(lf.lfFaceName,fp.faceName); } void FontCached::Release() { delete reinterpret_cast<FormatAndMetrics *>(fid); fid = 0; } FontID FontCached::FindOrCreate(const FontParameters &fp) { FontID ret = 0; ::EnterCriticalSection(&crPlatformLock); int hashFind = HashFont(fp); for (FontCached *cur=first; cur; cur=cur->next) { if ((cur->hash == hashFind) && cur->SameAs(fp)) { cur->usage++; ret = cur->fid; } } if (ret == 0) { FontCached *fc = new FontCached(fp); if (fc) { fc->next = first; first = fc; ret = fc->fid; } } ::LeaveCriticalSection(&crPlatformLock); return ret; } void FontCached::ReleaseId(FontID fid_) { ::EnterCriticalSection(&crPlatformLock); FontCached **pcur=&first; for (FontCached *cur=first; cur; cur=cur->next) { if (cur->fid == fid_) { cur->usage--; if (cur->usage == 0) { *pcur = cur->next; cur->Release(); cur->next = 0; delete cur; } break; } pcur=&cur->next; } ::LeaveCriticalSection(&crPlatformLock); } Font::Font() { fid = 0; } Font::~Font() { } #define FONTS_CACHED void Font::Create(const FontParameters &fp) { Release(); if (fp.faceName) fid = FontCached::FindOrCreate(fp); } void Font::Release() { if (fid) FontCached::ReleaseId(fid); fid = 0; } // Buffer to hold strings and string position arrays without always allocating on heap. // May sometimes have string too long to allocate on stack. So use a fixed stack-allocated buffer // when less than safe size otherwise allocate on heap and free automatically. template<typename T, int lengthStandard> class VarBuffer { T bufferStandard[lengthStandard]; // Private so VarBuffer objects can not be copied VarBuffer(const VarBuffer &); VarBuffer &operator=(const VarBuffer &); public: T *buffer; VarBuffer(size_t length) : buffer(0) { if (length > lengthStandard) { buffer = new T[length]; } else { buffer = bufferStandard; } } ~VarBuffer() { if (buffer != bufferStandard) { delete []buffer; buffer = 0; } } }; const int stackBufferLength = 10000; class TextWide : public VarBuffer<wchar_t, stackBufferLength> { public: int tlen; TextWide(const char *s, int len, bool unicodeMode, int codePage=0) : VarBuffer<wchar_t, stackBufferLength>(len) { if (unicodeMode) { tlen = UTF16FromUTF8(s, len, buffer, len); } else { // Support Asian string display in 9x English tlen = ::MultiByteToWideChar(codePage, 0, s, len, buffer, len); } } }; typedef VarBuffer<XYPOSITION, stackBufferLength> TextPositions; #ifdef SCI_NAMESPACE namespace Scintilla { #endif class SurfaceGDI : public Surface { bool unicodeMode; HDC hdc; bool hdcOwned; HPEN pen; HPEN penOld; HBRUSH brush; HBRUSH brushOld; HFONT font; HFONT fontOld; HBITMAP bitmap; HBITMAP bitmapOld; int maxWidthMeasure; int maxLenText; int codePage; // If 9x OS and current code page is same as ANSI code page. bool win9xACPSame; void BrushColor(ColourDesired back); void SetFont(Font &font_); // Private so SurfaceGDI objects can not be copied SurfaceGDI(const SurfaceGDI &); SurfaceGDI &operator=(const SurfaceGDI &); public: SurfaceGDI(); virtual ~SurfaceGDI(); void Init(WindowID wid); void Init(SurfaceID sid, WindowID wid); void InitPixMap(int width, int height, Surface *surface_, WindowID wid); void Release(); bool Initialised(); void PenColour(ColourDesired fore); int LogPixelsY(); int DeviceHeightFont(int points); void MoveTo(int x_, int y_); void LineTo(int x_, int y_); void Polygon(Point *pts, int npts, ColourDesired fore, ColourDesired back); void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back); void FillRectangle(PRectangle rc, ColourDesired back); void FillRectangle(PRectangle rc, Surface &surfacePattern); void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back); void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, ColourDesired outline, int alphaOutline, int flags); void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage); void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back); void Copy(PRectangle rc, Point from, Surface &surfaceSource); void DrawTextCommon(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, UINT fuOptions); void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back); void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back); void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore); void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions); XYPOSITION WidthText(Font &font_, const char *s, int len); XYPOSITION WidthChar(Font &font_, char ch); XYPOSITION Ascent(Font &font_); XYPOSITION Descent(Font &font_); XYPOSITION InternalLeading(Font &font_); XYPOSITION ExternalLeading(Font &font_); XYPOSITION Height(Font &font_); XYPOSITION AverageCharWidth(Font &font_); void SetClip(PRectangle rc); void FlushCachedState(); void SetUnicodeMode(bool unicodeMode_); void SetDBCSMode(int codePage_); }; #ifdef SCI_NAMESPACE } //namespace Scintilla #endif SurfaceGDI::SurfaceGDI() : unicodeMode(false), hdc(0), hdcOwned(false), pen(0), penOld(0), brush(0), brushOld(0), font(0), fontOld(0), bitmap(0), bitmapOld(0) { // Windows 9x has only a 16 bit coordinate system so break after 30000 pixels maxWidthMeasure = IsNT() ? INT_MAX : 30000; // There appears to be a 16 bit string length limit in GDI on NT and a limit of // 8192 characters on Windows 95. maxLenText = IsNT() ? 65535 : 8192; codePage = 0; win9xACPSame = false; } SurfaceGDI::~SurfaceGDI() { Release(); } void SurfaceGDI::Release() { if (penOld) { ::SelectObject(reinterpret_cast<HDC>(hdc), penOld); ::DeleteObject(pen); penOld = 0; } pen = 0; if (brushOld) { ::SelectObject(reinterpret_cast<HDC>(hdc), brushOld); ::DeleteObject(brush); brushOld = 0; } brush = 0; if (fontOld) { // Fonts are not deleted as they are owned by a Font object ::SelectObject(reinterpret_cast<HDC>(hdc), fontOld); fontOld = 0; } font = 0; if (bitmapOld) { ::SelectObject(reinterpret_cast<HDC>(hdc), bitmapOld); ::DeleteObject(bitmap); bitmapOld = 0; } bitmap = 0; if (hdcOwned) { ::DeleteDC(reinterpret_cast<HDC>(hdc)); hdc = 0; hdcOwned = false; } } bool SurfaceGDI::Initialised() { return hdc != 0; } void SurfaceGDI::Init(WindowID) { Release(); hdc = ::CreateCompatibleDC(NULL); hdcOwned = true; ::SetTextAlign(reinterpret_cast<HDC>(hdc), TA_BASELINE); } void SurfaceGDI::Init(SurfaceID sid, WindowID) { Release(); hdc = reinterpret_cast<HDC>(sid); ::SetTextAlign(reinterpret_cast<HDC>(hdc), TA_BASELINE); } void SurfaceGDI::InitPixMap(int width, int height, Surface *surface_, WindowID) { Release(); hdc = ::CreateCompatibleDC(static_cast<SurfaceGDI *>(surface_)->hdc); hdcOwned = true; bitmap = ::CreateCompatibleBitmap(static_cast<SurfaceGDI *>(surface_)->hdc, width, height); bitmapOld = static_cast<HBITMAP>(::SelectObject(hdc, bitmap)); ::SetTextAlign(reinterpret_cast<HDC>(hdc), TA_BASELINE); } void SurfaceGDI::PenColour(ColourDesired fore) { if (pen) { ::SelectObject(hdc, penOld); ::DeleteObject(pen); pen = 0; penOld = 0; } pen = ::CreatePen(0,1,fore.AsLong()); penOld = static_cast<HPEN>(::SelectObject(reinterpret_cast<HDC>(hdc), pen)); } void SurfaceGDI::BrushColor(ColourDesired back) { if (brush) { ::SelectObject(hdc, brushOld); ::DeleteObject(brush); brush = 0; brushOld = 0; } // Only ever want pure, non-dithered brushes ColourDesired colourNearest = ::GetNearestColor(hdc, back.AsLong()); brush = ::CreateSolidBrush(colourNearest.AsLong()); brushOld = static_cast<HBRUSH>(::SelectObject(hdc, brush)); } void SurfaceGDI::SetFont(Font &font_) { if (font_.GetID() != font) { FormatAndMetrics *pfm = reinterpret_cast<FormatAndMetrics *>(font_.GetID()); PLATFORM_ASSERT(pfm->technology == SCWIN_TECH_GDI); if (fontOld) { ::SelectObject(hdc, pfm->hfont); } else { fontOld = static_cast<HFONT>(::SelectObject(hdc, pfm->hfont)); } font = reinterpret_cast<HFONT>(pfm->hfont); } } int SurfaceGDI::LogPixelsY() { return ::GetDeviceCaps(hdc, LOGPIXELSY); } int SurfaceGDI::DeviceHeightFont(int points) { return ::MulDiv(points, LogPixelsY(), 72); } void SurfaceGDI::MoveTo(int x_, int y_) { ::MoveToEx(hdc, x_, y_, 0); } void SurfaceGDI::LineTo(int x_, int y_) { ::LineTo(hdc, x_, y_); } void SurfaceGDI::Polygon(Point *pts, int npts, ColourDesired fore, ColourDesired back) { PenColour(fore); BrushColor(back); std::vector<POINT> outline; for (int i=0;i<npts;i++) { POINT pt = {static_cast<LONG>(pts[i].x), static_cast<LONG>(pts[i].y)}; outline.push_back(pt); } ::Polygon(hdc, &outline[0], npts); } void SurfaceGDI::RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) { PenColour(fore); BrushColor(back); ::Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); } void SurfaceGDI::FillRectangle(PRectangle rc, ColourDesired back) { // Using ExtTextOut rather than a FillRect ensures that no dithering occurs. // There is no need to allocate a brush either. RECT rcw = RectFromPRectangle(rc); ::SetBkColor(hdc, back.AsLong()); ::ExtTextOut(hdc, rc.left, rc.top, ETO_OPAQUE, &rcw, TEXT(""), 0, NULL); } void SurfaceGDI::FillRectangle(PRectangle rc, Surface &surfacePattern) { HBRUSH br; if (static_cast<SurfaceGDI &>(surfacePattern).bitmap) br = ::CreatePatternBrush(static_cast<SurfaceGDI &>(surfacePattern).bitmap); else // Something is wrong so display in red br = ::CreateSolidBrush(RGB(0xff, 0, 0)); RECT rcw = RectFromPRectangle(rc); ::FillRect(hdc, &rcw, br); ::DeleteObject(br); } void SurfaceGDI::RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back) { PenColour(fore); BrushColor(back); ::RoundRect(hdc, rc.left + 1, rc.top, rc.right - 1, rc.bottom, 8, 8); } // Plot a point into a DWORD buffer symetrically to all 4 qudrants static void AllFour(DWORD *pixels, int width, int height, int x, int y, DWORD val) { pixels[y*width+x] = val; pixels[y*width+width-1-x] = val; pixels[(height-1-y)*width+x] = val; pixels[(height-1-y)*width+width-1-x] = val; } #ifndef AC_SRC_OVER #define AC_SRC_OVER 0x00 #endif #ifndef AC_SRC_ALPHA #define AC_SRC_ALPHA 0x01 #endif static DWORD dwordFromBGRA(byte b, byte g, byte r, byte a) { union { byte pixVal[4]; DWORD val; } converter; converter.pixVal[0] = b; converter.pixVal[1] = g; converter.pixVal[2] = r; converter.pixVal[3] = a; return converter.val; } void SurfaceGDI::AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, ColourDesired outline, int alphaOutline, int /* flags*/ ) { if (AlphaBlendFn && rc.Width() > 0) { HDC hMemDC = ::CreateCompatibleDC(reinterpret_cast<HDC>(hdc)); int width = rc.Width(); int height = rc.Height(); // Ensure not distorted too much by corners when small cornerSize = Platform::Minimum(cornerSize, (Platform::Minimum(width, height) / 2) - 2); BITMAPINFO bpih = {sizeof(BITMAPINFOHEADER), width, height, 1, 32, BI_RGB, 0, 0, 0, 0, 0}; void *image = 0; HBITMAP hbmMem = CreateDIBSection(reinterpret_cast<HDC>(hMemDC), &bpih, DIB_RGB_COLORS, &image, NULL, 0); if (hbmMem) { HBITMAP hbmOld = SelectBitmap(hMemDC, hbmMem); DWORD valEmpty = dwordFromBGRA(0,0,0,0); DWORD valFill = dwordFromBGRA( static_cast<byte>(GetBValue(fill.AsLong()) * alphaFill / 255), static_cast<byte>(GetGValue(fill.AsLong()) * alphaFill / 255), static_cast<byte>(GetRValue(fill.AsLong()) * alphaFill / 255), static_cast<byte>(alphaFill)); DWORD valOutline = dwordFromBGRA( static_cast<byte>(GetBValue(outline.AsLong()) * alphaOutline / 255), static_cast<byte>(GetGValue(outline.AsLong()) * alphaOutline / 255), static_cast<byte>(GetRValue(outline.AsLong()) * alphaOutline / 255), static_cast<byte>(alphaOutline)); DWORD *pixels = reinterpret_cast<DWORD *>(image); for (int y=0; y<height; y++) { for (int x=0; x<width; x++) { if ((x==0) || (x==width-1) || (y == 0) || (y == height-1)) { pixels[y*width+x] = valOutline; } else { pixels[y*width+x] = valFill; } } } for (int c=0;c<cornerSize; c++) { for (int x=0;x<c+1; x++) { AllFour(pixels, width, height, x, c-x, valEmpty); } } for (int x=1;x<cornerSize; x++) { AllFour(pixels, width, height, x, cornerSize-x, valOutline); } BLENDFUNCTION merge = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; AlphaBlendFn(reinterpret_cast<HDC>(hdc), rc.left, rc.top, width, height, hMemDC, 0, 0, width, height, merge); SelectBitmap(hMemDC, hbmOld); ::DeleteObject(hbmMem); } ::DeleteDC(hMemDC); } else { BrushColor(outline); RECT rcw = RectFromPRectangle(rc); FrameRect(hdc, &rcw, brush); } } void SurfaceGDI::DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) { if (AlphaBlendFn && rc.Width() > 0) { HDC hMemDC = ::CreateCompatibleDC(reinterpret_cast<HDC>(hdc)); if (rc.Width() > width) rc.left += static_cast<int>((rc.Width() - width) / 2); rc.right = rc.left + width; if (rc.Height() > height) rc.top += static_cast<int>((rc.Height() - height) / 2); rc.bottom = rc.top + height; BITMAPINFO bpih = {sizeof(BITMAPINFOHEADER), width, height, 1, 32, BI_RGB, 0, 0, 0, 0, 0}; unsigned char *image = 0; HBITMAP hbmMem = CreateDIBSection(reinterpret_cast<HDC>(hMemDC), &bpih, DIB_RGB_COLORS, reinterpret_cast<void **>(&image), NULL, 0); if (hbmMem) { HBITMAP hbmOld = SelectBitmap(hMemDC, hbmMem); for (int y=height-1; y>=0; y--) { for (int x=0; x<width; x++) { unsigned char *pixel = image + (y*width+x) * 4; unsigned char alpha = pixelsImage[3]; // Input is RGBA, output is BGRA with premultiplied alpha pixel[2] = static_cast<unsigned char>((*pixelsImage++) * alpha / 255); pixel[1] = static_cast<unsigned char>((*pixelsImage++) * alpha / 255); pixel[0] = static_cast<unsigned char>((*pixelsImage++) * alpha / 255); pixel[3] = static_cast<unsigned char>(*pixelsImage++); } } BLENDFUNCTION merge = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; AlphaBlendFn(reinterpret_cast<HDC>(hdc), rc.left, rc.top, rc.Width(), rc.Height(), hMemDC, 0, 0, width, height, merge); SelectBitmap(hMemDC, hbmOld); ::DeleteObject(hbmMem); } ::DeleteDC(hMemDC); } } void SurfaceGDI::Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) { PenColour(fore); BrushColor(back); ::Ellipse(hdc, rc.left, rc.top, rc.right, rc.bottom); } void SurfaceGDI::Copy(PRectangle rc, Point from, Surface &surfaceSource) { ::BitBlt(hdc, rc.left, rc.top, rc.Width(), rc.Height(), static_cast<SurfaceGDI &>(surfaceSource).hdc, from.x, from.y, SRCCOPY); } typedef VarBuffer<int, stackBufferLength> TextPositionsI; void SurfaceGDI::DrawTextCommon(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, UINT fuOptions) { SetFont(font_); RECT rcw = RectFromPRectangle(rc); SIZE sz={0,0}; int pos = 0; int x = rc.left; // Text drawing may fail if the text is too big. // If it does fail, slice up into segments and draw each segment. const int maxSegmentLength = 0x200; if ((!unicodeMode) && (IsNT() || (codePage==0) || win9xACPSame)) { // Use ANSI calls int lenDraw = Platform::Minimum(len, maxLenText); if (!::ExtTextOutA(hdc, x, ybase, fuOptions, &rcw, s, lenDraw, NULL)) { while (lenDraw > pos) { int seglen = Platform::Minimum(maxSegmentLength, lenDraw - pos); if (!::ExtTextOutA(hdc, x, ybase, fuOptions, &rcw, s+pos, seglen, NULL)) { PLATFORM_ASSERT(false); return; } ::GetTextExtentPoint32A(hdc, s+pos, seglen, &sz); x += sz.cx; pos += seglen; } } } else { // Use Unicode calls const TextWide tbuf(s, len, unicodeMode, codePage); if (!::ExtTextOutW(hdc, x, ybase, fuOptions, &rcw, tbuf.buffer, tbuf.tlen, NULL)) { while (tbuf.tlen > pos) { int seglen = Platform::Minimum(maxSegmentLength, tbuf.tlen - pos); if (!::ExtTextOutW(hdc, x, ybase, fuOptions, &rcw, tbuf.buffer+pos, seglen, NULL)) { PLATFORM_ASSERT(false); return; } ::GetTextExtentPoint32W(hdc, tbuf.buffer+pos, seglen, &sz); x += sz.cx; pos += seglen; } } } } void SurfaceGDI::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) { ::SetTextColor(hdc, fore.AsLong()); ::SetBkColor(hdc, back.AsLong()); DrawTextCommon(rc, font_, ybase, s, len, ETO_OPAQUE); } void SurfaceGDI::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) { ::SetTextColor(hdc, fore.AsLong()); ::SetBkColor(hdc, back.AsLong()); DrawTextCommon(rc, font_, ybase, s, len, ETO_OPAQUE | ETO_CLIPPED); } void SurfaceGDI::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore) { // Avoid drawing spaces in transparent mode for (int i=0;i<len;i++) { if (s[i] != ' ') { ::SetTextColor(hdc, fore.AsLong()); ::SetBkMode(hdc, TRANSPARENT); DrawTextCommon(rc, font_, ybase, s, len, 0); ::SetBkMode(hdc, OPAQUE); return; } } } XYPOSITION SurfaceGDI::WidthText(Font &font_, const char *s, int len) { SetFont(font_); SIZE sz={0,0}; if ((!unicodeMode) && (IsNT() || (codePage==0) || win9xACPSame)) { ::GetTextExtentPoint32A(hdc, s, Platform::Minimum(len, maxLenText), &sz); } else { const TextWide tbuf(s, len, unicodeMode, codePage); ::GetTextExtentPoint32W(hdc, tbuf.buffer, tbuf.tlen, &sz); } return sz.cx; } void SurfaceGDI::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) { SetFont(font_); SIZE sz={0,0}; int fit = 0; if (unicodeMode) { const TextWide tbuf(s, len, unicodeMode, codePage); TextPositionsI poses(tbuf.tlen); fit = tbuf.tlen; if (!::GetTextExtentExPointW(hdc, tbuf.buffer, tbuf.tlen, maxWidthMeasure, &fit, poses.buffer, &sz)) { // Likely to have failed because on Windows 9x where function not available // So measure the character widths by measuring each initial substring // Turns a linear operation into a qudratic but seems fast enough on test files for (int widthSS=0; widthSS < tbuf.tlen; widthSS++) { ::GetTextExtentPoint32W(hdc, tbuf.buffer, widthSS+1, &sz); poses.buffer[widthSS] = sz.cx; } } // Map the widths given for UTF-16 characters back onto the UTF-8 input string int ui=0; const unsigned char *us = reinterpret_cast<const unsigned char *>(s); int i=0; while (ui<fit) { unsigned char uch = us[i]; unsigned int lenChar = 1; if (uch >= (0x80 + 0x40 + 0x20 + 0x10)) { lenChar = 4; ui++; } else if (uch >= (0x80 + 0x40 + 0x20)) { lenChar = 3; } else if (uch >= (0x80)) { lenChar = 2; } for (unsigned int bytePos=0; (bytePos<lenChar) && (i<len); bytePos++) { positions[i++] = poses.buffer[ui]; } ui++; } int lastPos = 0; if (i > 0) lastPos = positions[i-1]; while (i<len) { positions[i++] = lastPos; } } else if (IsNT() || (codePage==0) || win9xACPSame) { // Zero positions to avoid random behaviour on failure. memset(positions, 0, len * sizeof(*positions)); // len may be larger than platform supports so loop over segments small enough for platform int startOffset = 0; while (len > 0) { int lenBlock = Platform::Minimum(len, maxLenText); TextPositionsI poses(len); if (!::GetTextExtentExPointA(hdc, s, lenBlock, maxWidthMeasure, &fit, poses.buffer, &sz)) { // Eeek - a NULL DC or other foolishness could cause this. return; } else if (fit < lenBlock) { // For some reason, such as an incomplete DBCS character // Not all the positions are filled in so make them equal to end. if (fit == 0) poses.buffer[fit++] = 0; for (int i = fit;i<lenBlock;i++) poses.buffer[i] = poses.buffer[fit-1]; } for (int i=0;i<lenBlock;i++) positions[i] = poses.buffer[i] + startOffset; startOffset = poses.buffer[lenBlock-1]; len -= lenBlock; positions += lenBlock; s += lenBlock; } } else { // Support Asian string display in 9x English const TextWide tbuf(s, len, unicodeMode, codePage); TextPositionsI poses(tbuf.tlen); for (int widthSS=0; widthSS<tbuf.tlen; widthSS++) { ::GetTextExtentPoint32W(hdc, tbuf.buffer, widthSS+1, &sz); poses.buffer[widthSS] = sz.cx; } int ui = 0; for (int i=0;i<len;) { if (::IsDBCSLeadByteEx(codePage, s[i])) { positions[i] = poses.buffer[ui]; positions[i+1] = poses.buffer[ui]; i += 2; } else { positions[i] = poses.buffer[ui]; i++; } ui++; } } } XYPOSITION SurfaceGDI::WidthChar(Font &font_, char ch) { SetFont(font_); SIZE sz; ::GetTextExtentPoint32A(hdc, &ch, 1, &sz); return sz.cx; } XYPOSITION SurfaceGDI::Ascent(Font &font_) { SetFont(font_); TEXTMETRIC tm; ::GetTextMetrics(hdc, &tm); return tm.tmAscent; } XYPOSITION SurfaceGDI::Descent(Font &font_) { SetFont(font_); TEXTMETRIC tm; ::GetTextMetrics(hdc, &tm); return tm.tmDescent; } XYPOSITION SurfaceGDI::InternalLeading(Font &font_) { SetFont(font_); TEXTMETRIC tm; ::GetTextMetrics(hdc, &tm); return tm.tmInternalLeading; } XYPOSITION SurfaceGDI::ExternalLeading(Font &font_) { SetFont(font_); TEXTMETRIC tm; ::GetTextMetrics(hdc, &tm); return tm.tmExternalLeading; } XYPOSITION SurfaceGDI::Height(Font &font_) { SetFont(font_); TEXTMETRIC tm; ::GetTextMetrics(hdc, &tm); return tm.tmHeight; } XYPOSITION SurfaceGDI::AverageCharWidth(Font &font_) { SetFont(font_); TEXTMETRIC tm; ::GetTextMetrics(hdc, &tm); return tm.tmAveCharWidth; } void SurfaceGDI::SetClip(PRectangle rc) { ::IntersectClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom); } void SurfaceGDI::FlushCachedState() { pen = 0; brush = 0; font = 0; } void SurfaceGDI::SetUnicodeMode(bool unicodeMode_) { unicodeMode=unicodeMode_; } void SurfaceGDI::SetDBCSMode(int codePage_) { // No action on window as automatically handled by system. codePage = codePage_; win9xACPSame = !IsNT() && ((unsigned int)codePage == ::GetACP()); } #if defined(USE_D2D) #ifdef SCI_NAMESPACE namespace Scintilla { #endif class SurfaceD2D : public Surface { bool unicodeMode; int x, y; int codePage; ID2D1RenderTarget *pRenderTarget; bool ownRenderTarget; int clipsActive; IDWriteTextFormat *pTextFormat; FLOAT yAscent; FLOAT yDescent; FLOAT yInternalLeading; ID2D1SolidColorBrush *pBrush; int logPixelsY; float dpiScaleX; float dpiScaleY; void SetFont(Font &font_); // Private so SurfaceD2D objects can not be copied SurfaceD2D(const SurfaceD2D &); SurfaceD2D &operator=(const SurfaceD2D &); public: SurfaceD2D(); virtual ~SurfaceD2D(); void SetScale(); void Init(WindowID wid); void Init(SurfaceID sid, WindowID wid); void InitPixMap(int width, int height, Surface *surface_, WindowID wid); void Release(); bool Initialised(); HRESULT FlushDrawing(); void PenColour(ColourDesired fore); void D2DPenColour(ColourDesired fore, int alpha=255); int LogPixelsY(); int DeviceHeightFont(int points); void MoveTo(int x_, int y_); void LineTo(int x_, int y_); void Polygon(Point *pts, int npts, ColourDesired fore, ColourDesired back); void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back); void FillRectangle(PRectangle rc, ColourDesired back); void FillRectangle(PRectangle rc, Surface &surfacePattern); void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back); void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, ColourDesired outline, int alphaOutline, int flags); void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage); void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back); void Copy(PRectangle rc, Point from, Surface &surfaceSource); void DrawTextCommon(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, UINT fuOptions); void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back); void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back); void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore); void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions); XYPOSITION WidthText(Font &font_, const char *s, int len); XYPOSITION WidthChar(Font &font_, char ch); XYPOSITION Ascent(Font &font_); XYPOSITION Descent(Font &font_); XYPOSITION InternalLeading(Font &font_); XYPOSITION ExternalLeading(Font &font_); XYPOSITION Height(Font &font_); XYPOSITION AverageCharWidth(Font &font_); void SetClip(PRectangle rc); void FlushCachedState(); void SetUnicodeMode(bool unicodeMode_); void SetDBCSMode(int codePage_); }; #ifdef SCI_NAMESPACE } //namespace Scintilla #endif SurfaceD2D::SurfaceD2D() : unicodeMode(false), x(0), y(0) { codePage = 0; pRenderTarget = NULL; ownRenderTarget = false; clipsActive = 0; // From selected font pTextFormat = NULL; yAscent = 2; yDescent = 1; yInternalLeading = 0; pBrush = NULL; logPixelsY = 72; dpiScaleX = 1.0; dpiScaleY = 1.0; } SurfaceD2D::~SurfaceD2D() { Release(); } void SurfaceD2D::Release() { if (pBrush) { pBrush->Release(); pBrush = 0; } if (pRenderTarget) { while (clipsActive) { pRenderTarget->PopAxisAlignedClip(); clipsActive--; } if (ownRenderTarget) { pRenderTarget->Release(); } pRenderTarget = 0; } } void SurfaceD2D::SetScale() { HDC hdcMeasure = ::CreateCompatibleDC(NULL); logPixelsY = ::GetDeviceCaps(hdcMeasure, LOGPIXELSY); dpiScaleX = ::GetDeviceCaps(hdcMeasure, LOGPIXELSX) / 96.0f; dpiScaleY = logPixelsY / 96.0f; ::DeleteDC(hdcMeasure); } bool SurfaceD2D::Initialised() { return pRenderTarget != 0; } HRESULT SurfaceD2D::FlushDrawing() { return pRenderTarget->Flush(); } void SurfaceD2D::Init(WindowID /* wid */) { Release(); SetScale(); } void SurfaceD2D::Init(SurfaceID sid, WindowID) { Release(); SetScale(); pRenderTarget = reinterpret_cast<ID2D1RenderTarget *>(sid); } void SurfaceD2D::InitPixMap(int width, int height, Surface *surface_, WindowID) { Release(); SetScale(); SurfaceD2D *psurfOther = static_cast<SurfaceD2D *>(surface_); ID2D1BitmapRenderTarget *pCompatibleRenderTarget = NULL; D2D1_SIZE_F desiredSize = D2D1::SizeF(width, height); D2D1_PIXEL_FORMAT desiredFormat = psurfOther->pRenderTarget->GetPixelFormat(); desiredFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE; HRESULT hr = psurfOther->pRenderTarget->CreateCompatibleRenderTarget( &desiredSize, NULL, &desiredFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &pCompatibleRenderTarget); if (SUCCEEDED(hr)) { pRenderTarget = pCompatibleRenderTarget; pRenderTarget->BeginDraw(); ownRenderTarget = true; } } void SurfaceD2D::PenColour(ColourDesired fore) { D2DPenColour(fore); } void SurfaceD2D::D2DPenColour(ColourDesired fore, int alpha) { if (pRenderTarget) { D2D_COLOR_F col; col.r = (fore.AsLong() & 0xff) / 255.0; col.g = ((fore.AsLong() & 0xff00) >> 8) / 255.0; col.b = (fore.AsLong() >> 16) / 255.0; col.a = alpha / 255.0; if (pBrush) { pBrush->SetColor(col); } else { HRESULT hr = pRenderTarget->CreateSolidColorBrush(col, &pBrush); if (!SUCCEEDED(hr) && pBrush) { pBrush->Release(); pBrush = 0; } } } } void SurfaceD2D::SetFont(Font &font_) { FormatAndMetrics *pfm = reinterpret_cast<FormatAndMetrics *>(font_.GetID()); PLATFORM_ASSERT(pfm->technology == SCWIN_TECH_DIRECTWRITE); pTextFormat = pfm->pTextFormat; yAscent = pfm->yAscent; yDescent = pfm->yDescent; yInternalLeading = pfm->yInternalLeading; if (pRenderTarget) { pRenderTarget->SetTextAntialiasMode(DWriteMapFontQuality(pfm->extraFontFlag)); } } int SurfaceD2D::LogPixelsY() { return logPixelsY; } int SurfaceD2D::DeviceHeightFont(int points) { return ::MulDiv(points, LogPixelsY(), 72); } void SurfaceD2D::MoveTo(int x_, int y_) { x = x_; y = y_; } static int Delta(int difference) { if (difference < 0) return -1; else if (difference > 0) return 1; else return 0; } static int RoundFloat(float f) { return int(f+0.5); } void SurfaceD2D::LineTo(int x_, int y_) { if (pRenderTarget) { int xDiff = x_ - x; int xDelta = Delta(xDiff); int yDiff = y_ - y; int yDelta = Delta(yDiff); if ((xDiff == 0) || (yDiff == 0)) { // Horizontal or vertical lines can be more precisely drawn as a filled rectangle int xEnd = x_ - xDelta; int left = Platform::Minimum(x, xEnd); int width = abs(x - xEnd) + 1; int yEnd = y_ - yDelta; int top = Platform::Minimum(y, yEnd); int height = abs(y - yEnd) + 1; D2D1_RECT_F rectangle1 = D2D1::RectF(left, top, left+width, top+height); pRenderTarget->FillRectangle(&rectangle1, pBrush); } else if ((abs(xDiff) == abs(yDiff))) { // 45 degree slope pRenderTarget->DrawLine(D2D1::Point2F(x + 0.5, y + 0.5), D2D1::Point2F(x_ + 0.5 - xDelta, y_ + 0.5 - yDelta), pBrush); } else { // Line has a different slope so difficult to avoid last pixel pRenderTarget->DrawLine(D2D1::Point2F(x + 0.5, y + 0.5), D2D1::Point2F(x_ + 0.5, y_ + 0.5), pBrush); } x = x_; y = y_; } } void SurfaceD2D::Polygon(Point *pts, int npts, ColourDesired fore, ColourDesired back) { if (pRenderTarget) { ID2D1Factory *pFactory = 0; pRenderTarget->GetFactory(&pFactory); ID2D1PathGeometry *geometry=0; HRESULT hr = pFactory->CreatePathGeometry(&geometry); if (SUCCEEDED(hr)) { ID2D1GeometrySink *sink = 0; hr = geometry->Open(&sink); if (SUCCEEDED(hr)) { sink->BeginFigure(D2D1::Point2F(pts[0].x + 0.5f, pts[0].y + 0.5f), D2D1_FIGURE_BEGIN_FILLED); for (size_t i=1; i<static_cast<size_t>(npts); i++) { sink->AddLine(D2D1::Point2F(pts[i].x + 0.5f, pts[i].y + 0.5f)); } sink->EndFigure(D2D1_FIGURE_END_CLOSED); sink->Close(); sink->Release(); D2DPenColour(back); pRenderTarget->FillGeometry(geometry,pBrush); D2DPenColour(fore); pRenderTarget->DrawGeometry(geometry,pBrush); } geometry->Release(); } } } void SurfaceD2D::RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back) { if (pRenderTarget) { D2D1_RECT_F rectangle1 = D2D1::RectF(RoundFloat(rc.left) + 0.5, rc.top+0.5, RoundFloat(rc.right) - 0.5, rc.bottom-0.5); D2DPenColour(back); pRenderTarget->FillRectangle(&rectangle1, pBrush); D2DPenColour(fore); pRenderTarget->DrawRectangle(&rectangle1, pBrush); } } void SurfaceD2D::FillRectangle(PRectangle rc, ColourDesired back) { if (pRenderTarget) { D2DPenColour(back); D2D1_RECT_F rectangle1 = D2D1::RectF(RoundFloat(rc.left), rc.top, RoundFloat(rc.right), rc.bottom); pRenderTarget->FillRectangle(&rectangle1, pBrush); } } void SurfaceD2D::FillRectangle(PRectangle rc, Surface &surfacePattern) { SurfaceD2D &surfOther = static_cast<SurfaceD2D &>(surfacePattern); surfOther.FlushDrawing(); ID2D1Bitmap *pBitmap = NULL; ID2D1BitmapRenderTarget *pCompatibleRenderTarget = reinterpret_cast<ID2D1BitmapRenderTarget *>( surfOther.pRenderTarget); HRESULT hr = pCompatibleRenderTarget->GetBitmap(&pBitmap); if (SUCCEEDED(hr)) { ID2D1BitmapBrush *pBitmapBrush = NULL; D2D1_BITMAP_BRUSH_PROPERTIES brushProperties = D2D1::BitmapBrushProperties(D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR); // Create the bitmap brush. hr = pRenderTarget->CreateBitmapBrush(pBitmap, brushProperties, &pBitmapBrush); pBitmap->Release(); if (SUCCEEDED(hr)) { pRenderTarget->FillRectangle( D2D1::RectF(rc.left, rc.top, rc.right, rc.bottom), pBitmapBrush); pBitmapBrush->Release(); } } } void SurfaceD2D::RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back) { if (pRenderTarget) { D2D1_ROUNDED_RECT roundedRectFill = D2D1::RoundedRect( D2D1::RectF(rc.left+1.0, rc.top+1.0, rc.right-1.0, rc.bottom-1.0), 8, 8); D2DPenColour(back); pRenderTarget->FillRoundedRectangle(roundedRectFill, pBrush); D2D1_ROUNDED_RECT roundedRect = D2D1::RoundedRect( D2D1::RectF(rc.left + 0.5, rc.top+0.5, rc.right - 0.5, rc.bottom-0.5), 8, 8); D2DPenColour(fore); pRenderTarget->DrawRoundedRectangle(roundedRect, pBrush); } } void SurfaceD2D::AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, ColourDesired outline, int alphaOutline, int /* flags*/ ) { if (pRenderTarget) { if (cornerSize == 0) { // When corner size is zero, draw square rectangle to prevent blurry pixels at corners D2D1_RECT_F rectFill = D2D1::RectF(RoundFloat(rc.left) + 1.0, rc.top + 1.0, RoundFloat(rc.right) - 1.0, rc.bottom - 1.0); D2DPenColour(fill, alphaFill); pRenderTarget->FillRectangle(rectFill, pBrush); D2D1_RECT_F rectOutline = D2D1::RectF(RoundFloat(rc.left) + 0.5, rc.top + 0.5, RoundFloat(rc.right) - 0.5, rc.bottom - 0.5); D2DPenColour(outline, alphaOutline); pRenderTarget->DrawRectangle(rectOutline, pBrush); } else { D2D1_ROUNDED_RECT roundedRectFill = D2D1::RoundedRect( D2D1::RectF(RoundFloat(rc.left) + 1.0, rc.top + 1.0, RoundFloat(rc.right) - 1.0, rc.bottom - 1.0), cornerSize, cornerSize); D2DPenColour(fill, alphaFill); pRenderTarget->FillRoundedRectangle(roundedRectFill, pBrush); D2D1_ROUNDED_RECT roundedRect = D2D1::RoundedRect( D2D1::RectF(RoundFloat(rc.left) + 0.5, rc.top + 0.5, RoundFloat(rc.right) - 0.5, rc.bottom - 0.5), cornerSize, cornerSize); D2DPenColour(outline, alphaOutline); pRenderTarget->DrawRoundedRectangle(roundedRect, pBrush); } } } void SurfaceD2D::DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) { if (pRenderTarget) { if (rc.Width() > width) rc.left += static_cast<int>((rc.Width() - width) / 2); rc.right = rc.left + width; if (rc.Height() > height) rc.top += static_cast<int>((rc.Height() - height) / 2); rc.bottom = rc.top + height; std::vector<unsigned char> image(height * width * 4); for (int y=0; y<height; y++) { for (int x=0; x<width; x++) { unsigned char *pixel = &image[0] + (y*width+x) * 4; unsigned char alpha = pixelsImage[3]; // Input is RGBA, output is BGRA with premultiplied alpha pixel[2] = (*pixelsImage++) * alpha / 255; pixel[1] = (*pixelsImage++) * alpha / 255; pixel[0] = (*pixelsImage++) * alpha / 255; pixel[3] = *pixelsImage++; } } ID2D1Bitmap *bitmap = 0; D2D1_SIZE_U size = D2D1::SizeU(width, height); D2D1_BITMAP_PROPERTIES props = {{DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED}, 72.0, 72.0}; HRESULT hr = pRenderTarget->CreateBitmap(size, &image[0], width * 4, &props, &bitmap); if (SUCCEEDED(hr)) { D2D1_RECT_F rcDestination = {rc.left, rc.top, rc.right, rc.bottom}; pRenderTarget->DrawBitmap(bitmap, rcDestination); } bitmap->Release(); } } void SurfaceD2D::Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back) { if (pRenderTarget) { FLOAT radius = rc.Width() / 2.0f - 1.0f; D2D1_ELLIPSE ellipse = D2D1::Ellipse( D2D1::Point2F((rc.left + rc.right) / 2.0f, (rc.top + rc.bottom) / 2.0f), radius,radius); PenColour(back); pRenderTarget->FillEllipse(ellipse, pBrush); PenColour(fore); pRenderTarget->DrawEllipse(ellipse, pBrush); } } void SurfaceD2D::Copy(PRectangle rc, Point from, Surface &surfaceSource) { SurfaceD2D &surfOther = static_cast<SurfaceD2D &>(surfaceSource); surfOther.FlushDrawing(); ID2D1BitmapRenderTarget *pCompatibleRenderTarget = reinterpret_cast<ID2D1BitmapRenderTarget *>( surfOther.pRenderTarget); ID2D1Bitmap *pBitmap = NULL; HRESULT hr = pCompatibleRenderTarget->GetBitmap(&pBitmap); if (SUCCEEDED(hr)) { D2D1_RECT_F rcDestination = {rc.left, rc.top, rc.right, rc.bottom}; D2D1_RECT_F rcSource = {from.x, from.y, from.x + rc.Width(), from.y + rc.Height()}; pRenderTarget->DrawBitmap(pBitmap, rcDestination, 1.0f, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, rcSource); pRenderTarget->Flush(); pBitmap->Release(); } } void SurfaceD2D::DrawTextCommon(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, UINT fuOptions) { SetFont(font_); // Use Unicode calls const TextWide tbuf(s, len, unicodeMode, codePage); if (pRenderTarget && pTextFormat && pBrush) { if (fuOptions & ETO_CLIPPED) { D2D1_RECT_F rcClip = {rc.left, rc.top, rc.right, rc.bottom}; pRenderTarget->PushAxisAlignedClip(rcClip, D2D1_ANTIALIAS_MODE_ALIASED); } // Explicitly creating a text layout appears a little faster IDWriteTextLayout *pTextLayout; HRESULT hr = pIDWriteFactory->CreateTextLayout(tbuf.buffer, tbuf.tlen, pTextFormat, rc.Width(), rc.Height(), &pTextLayout); if (SUCCEEDED(hr)) { D2D1_POINT_2F origin = {rc.left, ybase-yAscent}; pRenderTarget->DrawTextLayout(origin, pTextLayout, pBrush, D2D1_DRAW_TEXT_OPTIONS_NONE); pTextLayout->Release(); } if (fuOptions & ETO_CLIPPED) { pRenderTarget->PopAxisAlignedClip(); } } } void SurfaceD2D::DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) { if (pRenderTarget) { FillRectangle(rc, back); D2DPenColour(fore); DrawTextCommon(rc, font_, ybase, s, len, ETO_OPAQUE); } } void SurfaceD2D::DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back) { if (pRenderTarget) { FillRectangle(rc, back); D2DPenColour(fore); DrawTextCommon(rc, font_, ybase, s, len, ETO_OPAQUE | ETO_CLIPPED); } } void SurfaceD2D::DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore) { // Avoid drawing spaces in transparent mode for (int i=0;i<len;i++) { if (s[i] != ' ') { if (pRenderTarget) { D2DPenColour(fore); DrawTextCommon(rc, font_, ybase, s, len, 0); } return; } } } XYPOSITION SurfaceD2D::WidthText(Font &font_, const char *s, int len) { FLOAT width = 1.0; SetFont(font_); const TextWide tbuf(s, len, unicodeMode, codePage); if (pIDWriteFactory && pTextFormat) { // Create a layout IDWriteTextLayout *pTextLayout = 0; HRESULT hr = pIDWriteFactory->CreateTextLayout(tbuf.buffer, tbuf.tlen, pTextFormat, 1000.0, 1000.0, &pTextLayout); if (SUCCEEDED(hr)) { DWRITE_TEXT_METRICS textMetrics; pTextLayout->GetMetrics(&textMetrics); width = textMetrics.widthIncludingTrailingWhitespace; pTextLayout->Release(); } } return width; } void SurfaceD2D::MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions) { SetFont(font_); int fit = 0; const TextWide tbuf(s, len, unicodeMode, codePage); TextPositions poses(tbuf.tlen); fit = tbuf.tlen; const int clusters = 1000; DWRITE_CLUSTER_METRICS clusterMetrics[clusters]; UINT32 count = 0; if (pIDWriteFactory && pTextFormat) { SetFont(font_); // Create a layout IDWriteTextLayout *pTextLayout = 0; HRESULT hr = pIDWriteFactory->CreateTextLayout(tbuf.buffer, tbuf.tlen, pTextFormat, 10000.0, 1000.0, &pTextLayout); if (!SUCCEEDED(hr)) return; // For now, assuming WCHAR == cluster pTextLayout->GetClusterMetrics(clusterMetrics, clusters, &count); FLOAT position = 0.0f; size_t ti=0; for (size_t ci=0;ci<count;ci++) { position += clusterMetrics[ci].width; for (size_t inCluster=0; inCluster<clusterMetrics[ci].length; inCluster++) { //poses.buffer[ti++] = int(position + 0.5); poses.buffer[ti++] = position; } } PLATFORM_ASSERT(ti == static_cast<size_t>(tbuf.tlen)); pTextLayout->Release(); } if (unicodeMode) { // Map the widths given for UTF-16 characters back onto the UTF-8 input string int ui=0; const unsigned char *us = reinterpret_cast<const unsigned char *>(s); int i=0; while (ui<fit) { unsigned char uch = us[i]; unsigned int lenChar = 1; if (uch >= (0x80 + 0x40 + 0x20 + 0x10)) { lenChar = 4; ui++; } else if (uch >= (0x80 + 0x40 + 0x20)) { lenChar = 3; } else if (uch >= (0x80)) { lenChar = 2; } for (unsigned int bytePos=0; (bytePos<lenChar) && (i<len); bytePos++) { positions[i++] = poses.buffer[ui]; } ui++; } int lastPos = 0; if (i > 0) lastPos = positions[i-1]; while (i<len) { positions[i++] = lastPos; } } else if (codePage == 0) { // One character per position PLATFORM_ASSERT(len == tbuf.tlen); for (size_t kk=0;kk<static_cast<size_t>(len);kk++) { positions[kk] = poses.buffer[kk]; } } else { // May be more than one byte per position int ui = 0; for (int i=0;i<len;) { if (::IsDBCSLeadByteEx(codePage, s[i])) { positions[i] = poses.buffer[ui]; positions[i+1] = poses.buffer[ui]; i += 2; } else { positions[i] = poses.buffer[ui]; i++; } ui++; } } } XYPOSITION SurfaceD2D::WidthChar(Font &font_, char ch) { FLOAT width = 1.0; SetFont(font_); if (pIDWriteFactory && pTextFormat) { // Create a layout IDWriteTextLayout *pTextLayout = 0; const WCHAR wch = ch; HRESULT hr = pIDWriteFactory->CreateTextLayout(&wch, 1, pTextFormat, 1000.0, 1000.0, &pTextLayout); if (SUCCEEDED(hr)) { DWRITE_TEXT_METRICS textMetrics; pTextLayout->GetMetrics(&textMetrics); width = textMetrics.widthIncludingTrailingWhitespace; pTextLayout->Release(); } } return width; } XYPOSITION SurfaceD2D::Ascent(Font &font_) { SetFont(font_); return ceil(yAscent); } XYPOSITION SurfaceD2D::Descent(Font &font_) { SetFont(font_); return ceil(yDescent); } XYPOSITION SurfaceD2D::InternalLeading(Font &font_) { SetFont(font_); return floor(yInternalLeading); } XYPOSITION SurfaceD2D::ExternalLeading(Font &) { // Not implemented, always return one return 1; } XYPOSITION SurfaceD2D::Height(Font &font_) { return Ascent(font_) + Descent(font_); } XYPOSITION SurfaceD2D::AverageCharWidth(Font &font_) { FLOAT width = 1.0; SetFont(font_); if (pIDWriteFactory && pTextFormat) { // Create a layout IDWriteTextLayout *pTextLayout = 0; const WCHAR wszAllAlpha[] = L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; HRESULT hr = pIDWriteFactory->CreateTextLayout(wszAllAlpha, static_cast<UINT32>(wcslen(wszAllAlpha)), pTextFormat, 1000.0, 1000.0, &pTextLayout); if (SUCCEEDED(hr)) { DWRITE_TEXT_METRICS textMetrics; pTextLayout->GetMetrics(&textMetrics); width = textMetrics.width / wcslen(wszAllAlpha); pTextLayout->Release(); } } return width; } void SurfaceD2D::SetClip(PRectangle rc) { if (pRenderTarget) { D2D1_RECT_F rcClip = {rc.left, rc.top, rc.right, rc.bottom}; pRenderTarget->PushAxisAlignedClip(rcClip, D2D1_ANTIALIAS_MODE_ALIASED); clipsActive++; } } void SurfaceD2D::FlushCachedState() { } void SurfaceD2D::SetUnicodeMode(bool unicodeMode_) { unicodeMode=unicodeMode_; } void SurfaceD2D::SetDBCSMode(int codePage_) { // No action on window as automatically handled by system. codePage = codePage_; } #endif Surface *Surface::Allocate(int technology) { #if defined(USE_D2D) if (technology == SCWIN_TECH_GDI) return new SurfaceGDI; else return new SurfaceD2D; #else return new SurfaceGDI; #endif } Window::~Window() { } void Window::Destroy() { if (wid) ::DestroyWindow(reinterpret_cast<HWND>(wid)); wid = 0; } bool Window::HasFocus() { return ::GetFocus() == wid; } PRectangle Window::GetPosition() { RECT rc; ::GetWindowRect(reinterpret_cast<HWND>(wid), &rc); return PRectangle(rc.left, rc.top, rc.right, rc.bottom); } void Window::SetPosition(PRectangle rc) { ::SetWindowPos(reinterpret_cast<HWND>(wid), 0, rc.left, rc.top, rc.Width(), rc.Height(), SWP_NOZORDER|SWP_NOACTIVATE); } static RECT RectFromMonitor(HMONITOR hMonitor) { if (GetMonitorInfoFn) { MONITORINFO mi = {0}; mi.cbSize = sizeof(mi); if (GetMonitorInfoFn(hMonitor, &mi)) { return mi.rcWork; } } RECT rc = {0, 0, 0, 0}; ::SystemParametersInfoA(SPI_GETWORKAREA, 0, &rc, 0); return rc; } void Window::SetPositionRelative(PRectangle rc, Window w) { LONG style = ::GetWindowLong(reinterpret_cast<HWND>(wid), GWL_STYLE); if (style & WS_POPUP) { POINT ptOther = {0, 0}; ::ClientToScreen(reinterpret_cast<HWND>(w.GetID()), &ptOther); rc.Move(ptOther.x, ptOther.y); RECT rcMonitor = RectFromPRectangle(rc); HMONITOR hMonitor = NULL; if (MonitorFromRectFn) hMonitor = MonitorFromRectFn(&rcMonitor, MONITOR_DEFAULTTONEAREST); // If hMonitor is NULL, that's just the main screen anyways. //::GetMonitorInfo(hMonitor, &mi); RECT rcWork = RectFromMonitor(hMonitor); if (rcWork.left < rcWork.right) { // Now clamp our desired rectangle to fit inside the work area // This way, the menu will fit wholly on one screen. An improvement even // if you don't have a second monitor on the left... Menu's appears half on // one screen and half on the other are just U.G.L.Y.! if (rc.right > rcWork.right) rc.Move(rcWork.right - rc.right, 0); if (rc.bottom > rcWork.bottom) rc.Move(0, rcWork.bottom - rc.bottom); if (rc.left < rcWork.left) rc.Move(rcWork.left - rc.left, 0); if (rc.top < rcWork.top) rc.Move(0, rcWork.top - rc.top); } } SetPosition(rc); } PRectangle Window::GetClientPosition() { RECT rc={0,0,0,0}; if (wid) ::GetClientRect(reinterpret_cast<HWND>(wid), &rc); return PRectangle(rc.left, rc.top, rc.right, rc.bottom); } void Window::Show(bool show) { if (show) ::ShowWindow(reinterpret_cast<HWND>(wid), SW_SHOWNOACTIVATE); else ::ShowWindow(reinterpret_cast<HWND>(wid), SW_HIDE); } void Window::InvalidateAll() { ::InvalidateRect(reinterpret_cast<HWND>(wid), NULL, FALSE); } void Window::InvalidateRectangle(PRectangle rc) { RECT rcw = RectFromPRectangle(rc); ::InvalidateRect(reinterpret_cast<HWND>(wid), &rcw, FALSE); } static LRESULT Window_SendMessage(Window *w, UINT msg, WPARAM wParam=0, LPARAM lParam=0) { return ::SendMessage(reinterpret_cast<HWND>(w->GetID()), msg, wParam, lParam); } void Window::SetFont(Font &font) { Window_SendMessage(this, WM_SETFONT, reinterpret_cast<WPARAM>(font.GetID()), 0); } static void FlipBitmap(HBITMAP bitmap, int width, int height) { HDC hdc = ::CreateCompatibleDC(NULL); if (hdc != NULL) { HGDIOBJ prevBmp = ::SelectObject(hdc, bitmap); ::StretchBlt(hdc, width - 1, 0, -width, height, hdc, 0, 0, width, height, SRCCOPY); ::SelectObject(hdc, prevBmp); ::DeleteDC(hdc); } } static HCURSOR GetReverseArrowCursor() { if (reverseArrowCursor != NULL) return reverseArrowCursor; ::EnterCriticalSection(&crPlatformLock); HCURSOR cursor = reverseArrowCursor; if (cursor == NULL) { cursor = ::LoadCursor(NULL, IDC_ARROW); ICONINFO info; if (::GetIconInfo(cursor, &info)) { BITMAP bmp; if (::GetObject(info.hbmMask, sizeof(bmp), &bmp)) { FlipBitmap(info.hbmMask, bmp.bmWidth, bmp.bmHeight); if (info.hbmColor != NULL) FlipBitmap(info.hbmColor, bmp.bmWidth, bmp.bmHeight); info.xHotspot = (DWORD)bmp.bmWidth - 1 - info.xHotspot; reverseArrowCursor = ::CreateIconIndirect(&info); if (reverseArrowCursor != NULL) cursor = reverseArrowCursor; } ::DeleteObject(info.hbmMask); if (info.hbmColor != NULL) ::DeleteObject(info.hbmColor); } } ::LeaveCriticalSection(&crPlatformLock); return cursor; } void Window::SetCursor(Cursor curs) { switch (curs) { case cursorText: ::SetCursor(::LoadCursor(NULL,IDC_IBEAM)); break; case cursorUp: ::SetCursor(::LoadCursor(NULL,IDC_UPARROW)); break; case cursorWait: ::SetCursor(::LoadCursor(NULL,IDC_WAIT)); break; case cursorHoriz: ::SetCursor(::LoadCursor(NULL,IDC_SIZEWE)); break; case cursorVert: ::SetCursor(::LoadCursor(NULL,IDC_SIZENS)); break; case cursorHand: ::SetCursor(::LoadCursor(NULL,IDC_HAND)); break; case cursorReverseArrow: ::SetCursor(GetReverseArrowCursor()); break; case cursorArrow: case cursorInvalid: // Should not occur, but just in case. ::SetCursor(::LoadCursor(NULL,IDC_ARROW)); break; } } void Window::SetTitle(const char *s) { ::SetWindowTextA(reinterpret_cast<HWND>(wid), s); } /* Returns rectangle of monitor pt is on, both rect and pt are in Window's coordinates */ PRectangle Window::GetMonitorRect(Point pt) { // MonitorFromPoint and GetMonitorInfo are not available on Windows 95 and NT 4. PRectangle rcPosition = GetPosition(); POINT ptDesktop = {static_cast<LONG>(pt.x + rcPosition.left), static_cast<LONG>(pt.y + rcPosition.top)}; HMONITOR hMonitor = NULL; if (MonitorFromPointFn) hMonitor = MonitorFromPointFn(ptDesktop, MONITOR_DEFAULTTONEAREST); RECT rcWork = RectFromMonitor(hMonitor); if (rcWork.left < rcWork.right) { PRectangle rcMonitor( rcWork.left - rcPosition.left, rcWork.top - rcPosition.top, rcWork.right - rcPosition.left, rcWork.bottom - rcPosition.top); return rcMonitor; } else { return PRectangle(); } } struct ListItemData { const char *text; int pixId; }; #define _ROUND2(n,pow2) \ ( ( (n) + (pow2) - 1) & ~((pow2) - 1) ) class LineToItem { char *words; int wordsCount; int wordsSize; ListItemData *data; int len; int count; private: void FreeWords() { delete []words; words = NULL; wordsCount = 0; wordsSize = 0; } char *AllocWord(const char *word); public: LineToItem() : words(NULL), wordsCount(0), wordsSize(0), data(NULL), len(0), count(0) { } ~LineToItem() { Clear(); } void Clear() { FreeWords(); delete []data; data = NULL; len = 0; count = 0; } ListItemData *Append(const char *text, int value); ListItemData Get(int index) const { if (index >= 0 && index < count) { return data[index]; } else { ListItemData missing = {"", -1}; return missing; } } int Count() const { return count; } ListItemData *AllocItem(); void SetWords(char *s) { words = s; // N.B. will be deleted on destruction } }; char *LineToItem::AllocWord(const char *text) { int chars = static_cast<int>(strlen(text) + 1); int newCount = wordsCount + chars; if (newCount > wordsSize) { wordsSize = _ROUND2(newCount * 2, 8192); char *wordsNew = new char[wordsSize]; memcpy(wordsNew, words, wordsCount); int offset = wordsNew - words; for (int i=0; i<count; i++) data[i].text += offset; delete []words; words = wordsNew; } char *s = &words[wordsCount]; wordsCount = newCount; strncpy(s, text, chars); return s; } ListItemData *LineToItem::AllocItem() { if (count >= len) { int lenNew = _ROUND2((count+1) * 2, 1024); ListItemData *dataNew = new ListItemData[lenNew]; memcpy(dataNew, data, count * sizeof(ListItemData)); delete []data; data = dataNew; len = lenNew; } ListItemData *item = &data[count]; count++; return item; } ListItemData *LineToItem::Append(const char *text, int imageIndex) { ListItemData *item = AllocItem(); item->text = AllocWord(text); item->pixId = imageIndex; return item; } const TCHAR ListBoxX_ClassName[] = TEXT("ListBoxX"); ListBox::ListBox() { } ListBox::~ListBox() { } class ListBoxX : public ListBox { int lineHeight; FontID fontCopy; int technology; RGBAImageSet images; LineToItem lti; HWND lb; bool unicodeMode; int desiredVisibleRows; unsigned int maxItemCharacters; unsigned int aveCharWidth; Window *parent; int ctrlID; CallBackAction doubleClickAction; void *doubleClickActionData; const char *widestItem; unsigned int maxCharWidth; int resizeHit; PRectangle rcPreSize; Point dragOffset; Point location; // Caret location at which the list is opened int wheelDelta; // mouse wheel residue HWND GetHWND() const; void AppendListItem(const char *startword, const char *numword); void AdjustWindowRect(PRectangle *rc) const; int ItemHeight() const; int MinClientWidth() const; int TextOffset() const; Point GetClientExtent() const; POINT MinTrackSize() const; POINT MaxTrackSize() const; void SetRedraw(bool on); void OnDoubleClick(); void ResizeToCursor(); void StartResize(WPARAM); int NcHitTest(WPARAM, LPARAM) const; void CentreItem(int); void Paint(HDC); static LRESULT PASCAL ControlWndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam); static const Point ItemInset; // Padding around whole item static const Point TextInset; // Padding around text static const Point ImageInset; // Padding around image public: ListBoxX() : lineHeight(10), fontCopy(0), technology(0), lb(0), unicodeMode(false), desiredVisibleRows(5), maxItemCharacters(0), aveCharWidth(8), parent(NULL), ctrlID(0), doubleClickAction(NULL), doubleClickActionData(NULL), widestItem(NULL), maxCharWidth(1), resizeHit(0), wheelDelta(0) { } virtual ~ListBoxX() { if (fontCopy) { ::DeleteObject(fontCopy); fontCopy = 0; } } virtual void SetFont(Font &font); virtual void Create(Window &parent, int ctrlID, Point location_, int lineHeight_, bool unicodeMode_, int technology_); virtual void SetAverageCharWidth(int width); virtual void SetVisibleRows(int rows); virtual int GetVisibleRows() const; virtual PRectangle GetDesiredRect(); virtual int CaretFromEdge(); virtual void Clear(); virtual void Append(char *s, int type = -1); virtual int Length(); virtual void Select(int n); virtual int GetSelection(); virtual int Find(const char *prefix); virtual void GetValue(int n, char *value, int len); virtual void RegisterImage(int type, const char *xpm_data); virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage); virtual void ClearRegisteredImages(); virtual void SetDoubleClickAction(CallBackAction action, void *data) { doubleClickAction = action; doubleClickActionData = data; } virtual void SetList(const char *list, char separator, char typesep); void Draw(DRAWITEMSTRUCT *pDrawItem); LRESULT WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam); static LRESULT PASCAL StaticWndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam); }; const Point ListBoxX::ItemInset(0, 0); const Point ListBoxX::TextInset(2, 0); const Point ListBoxX::ImageInset(1, 0); ListBox *ListBox::Allocate() { ListBoxX *lb = new ListBoxX(); return lb; } void ListBoxX::Create(Window &parent_, int ctrlID_, Point location_, int lineHeight_, bool unicodeMode_, int technology_) { parent = &parent_; ctrlID = ctrlID_; location = location_; lineHeight = lineHeight_; unicodeMode = unicodeMode_; technology = technology_; HWND hwndParent = reinterpret_cast<HWND>(parent->GetID()); HINSTANCE hinstanceParent = GetWindowInstance(hwndParent); // Window created as popup so not clipped within parent client area wid = ::CreateWindowEx( WS_EX_WINDOWEDGE, ListBoxX_ClassName, TEXT(""), WS_POPUP | WS_THICKFRAME, 100,100, 150,80, hwndParent, NULL, hinstanceParent, this); POINT locationw = {static_cast<LONG>(location.x), static_cast<LONG>(location.y)}; ::MapWindowPoints(hwndParent, NULL, &locationw, 1); location = Point(locationw.x, locationw.y); } void ListBoxX::SetFont(Font &font) { if (font.GetID()) { if (fontCopy) { ::DeleteObject(fontCopy); fontCopy = 0; } FormatAndMetrics *pfm = reinterpret_cast<FormatAndMetrics *>(font.GetID()); fontCopy = pfm->HFont(); ::SendMessage(lb, WM_SETFONT, reinterpret_cast<WPARAM>(fontCopy), 0); } } void ListBoxX::SetAverageCharWidth(int width) { aveCharWidth = width; } void ListBoxX::SetVisibleRows(int rows) { desiredVisibleRows = rows; } int ListBoxX::GetVisibleRows() const { return desiredVisibleRows; } HWND ListBoxX::GetHWND() const { return reinterpret_cast<HWND>(GetID()); } PRectangle ListBoxX::GetDesiredRect() { PRectangle rcDesired = GetPosition(); int rows = Length(); if ((rows == 0) || (rows > desiredVisibleRows)) rows = desiredVisibleRows; rcDesired.bottom = rcDesired.top + ItemHeight() * rows; int width = MinClientWidth(); HDC hdc = ::GetDC(lb); HFONT oldFont = SelectFont(hdc, fontCopy); SIZE textSize = {0, 0}; int len = static_cast<int>(widestItem ? strlen(widestItem) : 0); if (unicodeMode) { const TextWide tbuf(widestItem, len, unicodeMode); ::GetTextExtentPoint32W(hdc, tbuf.buffer, tbuf.tlen, &textSize); } else { ::GetTextExtentPoint32A(hdc, widestItem, len, &textSize); } TEXTMETRIC tm; ::GetTextMetrics(hdc, &tm); maxCharWidth = tm.tmMaxCharWidth; SelectFont(hdc, oldFont); ::ReleaseDC(lb, hdc); int widthDesired = Platform::Maximum(textSize.cx, (len + 1) * tm.tmAveCharWidth); if (width < widthDesired) width = widthDesired; rcDesired.right = rcDesired.left + TextOffset() + width + (TextInset.x * 2); if (Length() > rows) rcDesired.right += ::GetSystemMetrics(SM_CXVSCROLL); AdjustWindowRect(&rcDesired); return rcDesired; } int ListBoxX::TextOffset() const { int pixWidth = images.GetWidth(); return pixWidth == 0 ? ItemInset.x : ItemInset.x + pixWidth + (ImageInset.x * 2); } int ListBoxX::CaretFromEdge() { PRectangle rc; AdjustWindowRect(&rc); return TextOffset() + TextInset.x + (0 - rc.left) - 1; } void ListBoxX::Clear() { ::SendMessage(lb, LB_RESETCONTENT, 0, 0); maxItemCharacters = 0; widestItem = NULL; lti.Clear(); } void ListBoxX::Append(char *s, int type) { int index = ::SendMessage(lb, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>(s)); if (index < 0) return; ListItemData *newItem = lti.Append(s, type); unsigned int len = static_cast<unsigned int>(strlen(s)); if (maxItemCharacters < len) { maxItemCharacters = len; widestItem = newItem->text; } } int ListBoxX::Length() { return lti.Count(); } void ListBoxX::Select(int n) { // We are going to scroll to centre on the new selection and then select it, so disable // redraw to avoid flicker caused by a painting new selection twice in unselected and then // selected states SetRedraw(false); CentreItem(n); ::SendMessage(lb, LB_SETCURSEL, n, 0); SetRedraw(true); } int ListBoxX::GetSelection() { return ::SendMessage(lb, LB_GETCURSEL, 0, 0); } // This is not actually called at present int ListBoxX::Find(const char *) { return LB_ERR; } void ListBoxX::GetValue(int n, char *value, int len) { ListItemData item = lti.Get(n); strncpy(value, item.text, len); value[len-1] = '\0'; } void ListBoxX::RegisterImage(int type, const char *xpm_data) { XPM xpmImage(xpm_data); images.Add(type, new RGBAImage(xpmImage)); } void ListBoxX::RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) { images.Add(type, new RGBAImage(width, height, 1.0, pixelsImage)); } void ListBoxX::ClearRegisteredImages() { images.Clear(); } void ListBoxX::Draw(DRAWITEMSTRUCT *pDrawItem) { if ((pDrawItem->itemAction == ODA_SELECT) || (pDrawItem->itemAction == ODA_DRAWENTIRE)) { RECT rcBox = pDrawItem->rcItem; rcBox.left += TextOffset(); if (pDrawItem->itemState & ODS_SELECTED) { RECT rcImage = pDrawItem->rcItem; rcImage.right = rcBox.left; // The image is not highlighted ::FillRect(pDrawItem->hDC, &rcImage, reinterpret_cast<HBRUSH>(COLOR_WINDOW+1)); ::FillRect(pDrawItem->hDC, &rcBox, reinterpret_cast<HBRUSH>(COLOR_HIGHLIGHT+1)); ::SetBkColor(pDrawItem->hDC, ::GetSysColor(COLOR_HIGHLIGHT)); ::SetTextColor(pDrawItem->hDC, ::GetSysColor(COLOR_HIGHLIGHTTEXT)); } else { ::FillRect(pDrawItem->hDC, &pDrawItem->rcItem, reinterpret_cast<HBRUSH>(COLOR_WINDOW+1)); ::SetBkColor(pDrawItem->hDC, ::GetSysColor(COLOR_WINDOW)); ::SetTextColor(pDrawItem->hDC, ::GetSysColor(COLOR_WINDOWTEXT)); } ListItemData item = lti.Get(pDrawItem->itemID); int pixId = item.pixId; const char *text = item.text; int len = static_cast<int>(strlen(text)); RECT rcText = rcBox; ::InsetRect(&rcText, TextInset.x, TextInset.y); if (unicodeMode) { const TextWide tbuf(text, len, unicodeMode); ::DrawTextW(pDrawItem->hDC, tbuf.buffer, tbuf.tlen, &rcText, DT_NOPREFIX|DT_END_ELLIPSIS|DT_SINGLELINE|DT_NOCLIP); } else { ::DrawTextA(pDrawItem->hDC, text, len, &rcText, DT_NOPREFIX|DT_END_ELLIPSIS|DT_SINGLELINE|DT_NOCLIP); } if (pDrawItem->itemState & ODS_SELECTED) { ::DrawFocusRect(pDrawItem->hDC, &rcBox); } // Draw the image, if any RGBAImage *pimage = images.Get(pixId); if (pimage) { Surface *surfaceItem = Surface::Allocate(technology); if (surfaceItem) { if (technology == SCWIN_TECH_GDI) { surfaceItem->Init(pDrawItem->hDC, pDrawItem->hwndItem); int left = pDrawItem->rcItem.left + ItemInset.x + ImageInset.x; PRectangle rcImage(left, pDrawItem->rcItem.top, left + images.GetWidth(), pDrawItem->rcItem.bottom); surfaceItem->DrawRGBAImage(rcImage, pimage->GetWidth(), pimage->GetHeight(), pimage->Pixels()); delete surfaceItem; ::SetTextAlign(pDrawItem->hDC, TA_TOP); } else { #if defined(USE_D2D) D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties( D2D1_RENDER_TARGET_TYPE_DEFAULT, D2D1::PixelFormat( DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE), 0, 0, D2D1_RENDER_TARGET_USAGE_NONE, D2D1_FEATURE_LEVEL_DEFAULT ); ID2D1DCRenderTarget *pDCRT = 0; HRESULT hr = pD2DFactory->CreateDCRenderTarget(&props, &pDCRT); if (SUCCEEDED(hr)) { RECT rcWindow; GetClientRect(pDrawItem->hwndItem, &rcWindow); hr = pDCRT->BindDC(pDrawItem->hDC, &rcWindow); if (SUCCEEDED(hr)) { surfaceItem->Init(pDCRT, pDrawItem->hwndItem); pDCRT->BeginDraw(); int left = pDrawItem->rcItem.left + ItemInset.x + ImageInset.x; PRectangle rcImage(left, pDrawItem->rcItem.top, left + images.GetWidth(), pDrawItem->rcItem.bottom); surfaceItem->DrawRGBAImage(rcImage, pimage->GetWidth(), pimage->GetHeight(), pimage->Pixels()); delete surfaceItem; pDCRT->EndDraw(); pDCRT->Release(); } } #endif } } } } } void ListBoxX::AppendListItem(const char *startword, const char *numword) { ListItemData *item = lti.AllocItem(); item->text = startword; if (numword) { int pixId = 0; char ch; while ((ch = *++numword) != '\0') { pixId = 10 * pixId + (ch - '0'); } item->pixId = pixId; } else { item->pixId = -1; } unsigned int len = static_cast<unsigned int>(strlen(item->text)); if (maxItemCharacters < len) { maxItemCharacters = len; widestItem = item->text; } } void ListBoxX::SetList(const char *list, char separator, char typesep) { // Turn off redraw while populating the list - this has a significant effect, even if // the listbox is not visible. SetRedraw(false); Clear(); size_t size = strlen(list); char *words = new char[size+1]; lti.SetWords(words); memcpy(words, list, size+1); char *startword = words; char *numword = NULL; for (size_t i=0; i < size; i++) { if (words[i] == separator) { words[i] = '\0'; if (numword) *numword = '\0'; AppendListItem(startword, numword); startword = words + i + 1; numword = NULL; } else if (words[i] == typesep) { numword = words + i; } } if (startword) { if (numword) *numword = '\0'; AppendListItem(startword, numword); } // Finally populate the listbox itself with the correct number of items int count = lti.Count(); ::SendMessage(lb, LB_INITSTORAGE, count, 0); for (int j=0; j<count; j++) { ::SendMessage(lb, LB_ADDSTRING, 0, j+1); } SetRedraw(true); } void ListBoxX::AdjustWindowRect(PRectangle *rc) const { RECT rcw = RectFromPRectangle(*rc); ::AdjustWindowRectEx(&rcw, WS_THICKFRAME, false, WS_EX_WINDOWEDGE); *rc = PRectangle(rcw.left, rcw.top, rcw.right, rcw.bottom); } int ListBoxX::ItemHeight() const { int itemHeight = lineHeight + (TextInset.y * 2); int pixHeight = images.GetHeight() + (ImageInset.y * 2); if (itemHeight < pixHeight) { itemHeight = pixHeight; } return itemHeight; } int ListBoxX::MinClientWidth() const { return 12 * (aveCharWidth+aveCharWidth/3); } POINT ListBoxX::MinTrackSize() const { PRectangle rc(0, 0, MinClientWidth(), ItemHeight()); AdjustWindowRect(&rc); POINT ret = {static_cast<LONG>(rc.Width()), static_cast<LONG>(rc.Height())}; return ret; } POINT ListBoxX::MaxTrackSize() const { PRectangle rc(0, 0, maxCharWidth * maxItemCharacters + TextInset.x * 2 + TextOffset() + ::GetSystemMetrics(SM_CXVSCROLL), ItemHeight() * lti.Count()); AdjustWindowRect(&rc); POINT ret = {static_cast<LONG>(rc.Width()), static_cast<LONG>(rc.Height())}; return ret; } void ListBoxX::SetRedraw(bool on) { ::SendMessage(lb, WM_SETREDRAW, static_cast<BOOL>(on), 0); if (on) ::InvalidateRect(lb, NULL, TRUE); } void ListBoxX::ResizeToCursor() { PRectangle rc = GetPosition(); POINT ptw; ::GetCursorPos(&ptw); Point pt(ptw.x, ptw.y); pt.x += dragOffset.x; pt.y += dragOffset.y; switch (resizeHit) { case HTLEFT: rc.left = pt.x; break; case HTRIGHT: rc.right = pt.x; break; case HTTOP: rc.top = pt.y; break; case HTTOPLEFT: rc.top = pt.y; rc.left = pt.x; break; case HTTOPRIGHT: rc.top = pt.y; rc.right = pt.x; break; case HTBOTTOM: rc.bottom = pt.y; break; case HTBOTTOMLEFT: rc.bottom = pt.y; rc.left = pt.x; break; case HTBOTTOMRIGHT: rc.bottom = pt.y; rc.right = pt.x; break; } POINT ptMin = MinTrackSize(); POINT ptMax = MaxTrackSize(); // We don't allow the left edge to move at present, but just in case rc.left = Platform::Maximum(Platform::Minimum(rc.left, rcPreSize.right - ptMin.x), rcPreSize.right - ptMax.x); rc.top = Platform::Maximum(Platform::Minimum(rc.top, rcPreSize.bottom - ptMin.y), rcPreSize.bottom - ptMax.y); rc.right = Platform::Maximum(Platform::Minimum(rc.right, rcPreSize.left + ptMax.x), rcPreSize.left + ptMin.x); rc.bottom = Platform::Maximum(Platform::Minimum(rc.bottom, rcPreSize.top + ptMax.y), rcPreSize.top + ptMin.y); SetPosition(rc); } void ListBoxX::StartResize(WPARAM hitCode) { rcPreSize = GetPosition(); POINT cursorPos; ::GetCursorPos(&cursorPos); switch (hitCode) { case HTRIGHT: case HTBOTTOM: case HTBOTTOMRIGHT: dragOffset.x = rcPreSize.right - cursorPos.x; dragOffset.y = rcPreSize.bottom - cursorPos.y; break; case HTTOPRIGHT: dragOffset.x = rcPreSize.right - cursorPos.x; dragOffset.y = rcPreSize.top - cursorPos.y; break; // Note that the current hit test code prevents the left edge cases ever firing // as we don't want the left edge to be moveable case HTLEFT: case HTTOP: case HTTOPLEFT: dragOffset.x = rcPreSize.left - cursorPos.x; dragOffset.y = rcPreSize.top - cursorPos.y; break; case HTBOTTOMLEFT: dragOffset.x = rcPreSize.left - cursorPos.x; dragOffset.y = rcPreSize.bottom - cursorPos.y; break; default: return; } ::SetCapture(GetHWND()); resizeHit = hitCode; } int ListBoxX::NcHitTest(WPARAM wParam, LPARAM lParam) const { int hit = ::DefWindowProc(GetHWND(), WM_NCHITTEST, wParam, lParam); // There is an apparent bug in the DefWindowProc hit test code whereby it will // return HTTOPXXX if the window in question is shorter than the default // window caption height + frame, even if one is hovering over the bottom edge of // the frame, so workaround that here if (hit >= HTTOP && hit <= HTTOPRIGHT) { int minHeight = GetSystemMetrics(SM_CYMINTRACK); PRectangle rc = const_cast<ListBoxX*>(this)->GetPosition(); int yPos = GET_Y_LPARAM(lParam); if ((rc.Height() < minHeight) && (yPos > ((rc.top + rc.bottom)/2))) { hit += HTBOTTOM - HTTOP; } } // Nerver permit resizing that moves the left edge. Allow movement of top or bottom edge // depending on whether the list is above or below the caret switch (hit) { case HTLEFT: case HTTOPLEFT: case HTBOTTOMLEFT: hit = HTERROR; break; case HTTOP: case HTTOPRIGHT: { PRectangle rc = const_cast<ListBoxX*>(this)->GetPosition(); // Valid only if caret below list if (location.y < rc.top) hit = HTERROR; } break; case HTBOTTOM: case HTBOTTOMRIGHT: { PRectangle rc = const_cast<ListBoxX*>(this)->GetPosition(); // Valid only if caret above list if (rc.bottom < location.y) hit = HTERROR; } break; } return hit; } void ListBoxX::OnDoubleClick() { if (doubleClickAction != NULL) { doubleClickAction(doubleClickActionData); } } Point ListBoxX::GetClientExtent() const { PRectangle rc = const_cast<ListBoxX*>(this)->GetClientPosition(); return Point(rc.Width(), rc.Height()); } void ListBoxX::CentreItem(int n) { // If below mid point, scroll up to centre, but with more items below if uneven if (n >= 0) { Point extent = GetClientExtent(); int visible = extent.y/ItemHeight(); if (visible < Length()) { int top = ::SendMessage(lb, LB_GETTOPINDEX, 0, 0); int half = (visible - 1) / 2; if (n > (top + half)) ::SendMessage(lb, LB_SETTOPINDEX, n - half , 0); } } } // Performs a double-buffered paint operation to avoid flicker void ListBoxX::Paint(HDC hDC) { Point extent = GetClientExtent(); HBITMAP hBitmap = ::CreateCompatibleBitmap(hDC, extent.x, extent.y); HDC bitmapDC = ::CreateCompatibleDC(hDC); HBITMAP hBitmapOld = SelectBitmap(bitmapDC, hBitmap); // The list background is mainly erased during painting, but can be a small // unpainted area when at the end of a non-integrally sized list with a // vertical scroll bar RECT rc = { 0, 0, static_cast<LONG>(extent.x), static_cast<LONG>(extent.y) }; ::FillRect(bitmapDC, &rc, reinterpret_cast<HBRUSH>(COLOR_WINDOW+1)); // Paint the entire client area and vertical scrollbar ::SendMessage(lb, WM_PRINT, reinterpret_cast<WPARAM>(bitmapDC), PRF_CLIENT|PRF_NONCLIENT); ::BitBlt(hDC, 0, 0, extent.x, extent.y, bitmapDC, 0, 0, SRCCOPY); // Select a stock brush to prevent warnings from BoundsChecker ::SelectObject(bitmapDC, GetStockFont(WHITE_BRUSH)); SelectBitmap(bitmapDC, hBitmapOld); ::DeleteDC(bitmapDC); ::DeleteObject(hBitmap); } LRESULT PASCAL ListBoxX::ControlWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { try { switch (uMsg) { case WM_ERASEBKGND: return TRUE; case WM_PAINT: { PAINTSTRUCT ps; HDC hDC = ::BeginPaint(hWnd, &ps); ListBoxX *lbx = reinterpret_cast<ListBoxX *>(PointerFromWindow(::GetParent(hWnd))); if (lbx) lbx->Paint(hDC); ::EndPaint(hWnd, &ps); } return 0; case WM_MOUSEACTIVATE: // This prevents the view activating when the scrollbar is clicked return MA_NOACTIVATE; case WM_LBUTTONDOWN: { // We must take control of selection to prevent the ListBox activating // the popup LRESULT lResult = ::SendMessage(hWnd, LB_ITEMFROMPOINT, 0, lParam); int item = LOWORD(lResult); if (HIWORD(lResult) == 0 && item >= 0) { ::SendMessage(hWnd, LB_SETCURSEL, item, 0); } } return 0; case WM_LBUTTONUP: return 0; case WM_LBUTTONDBLCLK: { ListBoxX *lbx = reinterpret_cast<ListBoxX *>(PointerFromWindow(::GetParent(hWnd))); if (lbx) { lbx->OnDoubleClick(); } } return 0; case WM_MBUTTONDOWN: // disable the scroll wheel button click action return 0; } WNDPROC prevWndProc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(hWnd, GWLP_USERDATA)); if (prevWndProc) { return ::CallWindowProc(prevWndProc, hWnd, uMsg, wParam, lParam); } else { return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } } catch (...) { } return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } LRESULT ListBoxX::WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { switch (iMessage) { case WM_CREATE: { HINSTANCE hinstanceParent = GetWindowInstance(reinterpret_cast<HWND>(parent->GetID())); // Note that LBS_NOINTEGRALHEIGHT is specified to fix cosmetic issue when resizing the list // but has useful side effect of speeding up list population significantly lb = ::CreateWindowEx( 0, TEXT("listbox"), TEXT(""), WS_CHILD | WS_VSCROLL | WS_VISIBLE | LBS_OWNERDRAWFIXED | LBS_NODATA | LBS_NOINTEGRALHEIGHT, 0, 0, 150,80, hWnd, reinterpret_cast<HMENU>(ctrlID), hinstanceParent, 0); WNDPROC prevWndProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(lb, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(ControlWndProc))); ::SetWindowLongPtr(lb, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(prevWndProc)); } break; case WM_SIZE: if (lb) { SetRedraw(false); ::SetWindowPos(lb, 0, 0,0, LOWORD(lParam), HIWORD(lParam), SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE); // Ensure the selection remains visible CentreItem(GetSelection()); SetRedraw(true); } break; case WM_PAINT: { PAINTSTRUCT ps; ::BeginPaint(hWnd, &ps); ::EndPaint(hWnd, &ps); } break; case WM_COMMAND: // This is not actually needed now - the registered double click action is used // directly to action a choice from the list. ::SendMessage(reinterpret_cast<HWND>(parent->GetID()), iMessage, wParam, lParam); break; case WM_MEASUREITEM: { MEASUREITEMSTRUCT *pMeasureItem = reinterpret_cast<MEASUREITEMSTRUCT *>(lParam); pMeasureItem->itemHeight = static_cast<unsigned int>(ItemHeight()); } break; case WM_DRAWITEM: Draw(reinterpret_cast<DRAWITEMSTRUCT *>(lParam)); break; case WM_DESTROY: lb = 0; ::SetWindowLong(hWnd, 0, 0); return ::DefWindowProc(hWnd, iMessage, wParam, lParam); case WM_ERASEBKGND: // To reduce flicker we can elide background erasure since this window is // completely covered by its child. return TRUE; case WM_GETMINMAXINFO: { MINMAXINFO *minMax = reinterpret_cast<MINMAXINFO*>(lParam); minMax->ptMaxTrackSize = MaxTrackSize(); minMax->ptMinTrackSize = MinTrackSize(); } break; case WM_MOUSEACTIVATE: return MA_NOACTIVATE; case WM_NCHITTEST: return NcHitTest(wParam, lParam); case WM_NCLBUTTONDOWN: // We have to implement our own window resizing because the DefWindowProc // implementation insists on activating the resized window StartResize(wParam); return 0; case WM_MOUSEMOVE: { if (resizeHit == 0) { return ::DefWindowProc(hWnd, iMessage, wParam, lParam); } else { ResizeToCursor(); } } break; case WM_LBUTTONUP: case WM_CANCELMODE: if (resizeHit != 0) { resizeHit = 0; ::ReleaseCapture(); } return ::DefWindowProc(hWnd, iMessage, wParam, lParam); case WM_MOUSEWHEEL: wheelDelta -= static_cast<short>(HIWORD(wParam)); if (abs(wheelDelta) >= WHEEL_DELTA) { int nRows = GetVisibleRows(); int linesToScroll = 1; if (nRows > 1) { linesToScroll = nRows - 1; } if (linesToScroll > 3) { linesToScroll = 3; } linesToScroll *= (wheelDelta / WHEEL_DELTA); int top = ::SendMessage(lb, LB_GETTOPINDEX, 0, 0) + linesToScroll; if (top < 0) { top = 0; } ::SendMessage(lb, LB_SETTOPINDEX, top, 0); // update wheel delta residue if (wheelDelta >= 0) wheelDelta = wheelDelta % WHEEL_DELTA; else wheelDelta = - (-wheelDelta % WHEEL_DELTA); } break; default: return ::DefWindowProc(hWnd, iMessage, wParam, lParam); } return 0; } LRESULT PASCAL ListBoxX::StaticWndProc( HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { if (iMessage == WM_CREATE) { CREATESTRUCT *pCreate = reinterpret_cast<CREATESTRUCT *>(lParam); SetWindowPointer(hWnd, pCreate->lpCreateParams); } // Find C++ object associated with window. ListBoxX *lbx = reinterpret_cast<ListBoxX *>(PointerFromWindow(hWnd)); if (lbx) { return lbx->WndProc(hWnd, iMessage, wParam, lParam); } else { return ::DefWindowProc(hWnd, iMessage, wParam, lParam); } } static bool ListBoxX_Register() { WNDCLASSEX wndclassc; wndclassc.cbSize = sizeof(wndclassc); // We need CS_HREDRAW and CS_VREDRAW because of the ellipsis that might be drawn for // truncated items in the list and the appearance/disappearance of the vertical scroll bar. // The list repaint is double-buffered to avoid the flicker this would otherwise cause. wndclassc.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW; wndclassc.cbClsExtra = 0; wndclassc.cbWndExtra = sizeof(ListBoxX *); wndclassc.hInstance = hinstPlatformRes; wndclassc.hIcon = NULL; wndclassc.hbrBackground = NULL; wndclassc.lpszMenuName = NULL; wndclassc.lpfnWndProc = ListBoxX::StaticWndProc; wndclassc.hCursor = ::LoadCursor(NULL, IDC_ARROW); wndclassc.lpszClassName = ListBoxX_ClassName; wndclassc.hIconSm = 0; return ::RegisterClassEx(&wndclassc) != 0; } bool ListBoxX_Unregister() { return ::UnregisterClass(ListBoxX_ClassName, hinstPlatformRes) != 0; } Menu::Menu() : mid(0) { } void Menu::CreatePopUp() { Destroy(); mid = ::CreatePopupMenu(); } void Menu::Destroy() { if (mid) ::DestroyMenu(reinterpret_cast<HMENU>(mid)); mid = 0; } void Menu::Show(Point pt, Window &w) { ::TrackPopupMenu(reinterpret_cast<HMENU>(mid), 0, pt.x - 4, pt.y, 0, reinterpret_cast<HWND>(w.GetID()), NULL); Destroy(); } static bool initialisedET = false; static bool usePerformanceCounter = false; static LARGE_INTEGER frequency; ElapsedTime::ElapsedTime() { if (!initialisedET) { usePerformanceCounter = ::QueryPerformanceFrequency(&frequency) != 0; initialisedET = true; } if (usePerformanceCounter) { LARGE_INTEGER timeVal; ::QueryPerformanceCounter(&timeVal); bigBit = timeVal.HighPart; littleBit = timeVal.LowPart; } else { bigBit = clock(); } } double ElapsedTime::Duration(bool reset) { double result; long endBigBit; long endLittleBit; if (usePerformanceCounter) { LARGE_INTEGER lEnd; ::QueryPerformanceCounter(&lEnd); endBigBit = lEnd.HighPart; endLittleBit = lEnd.LowPart; LARGE_INTEGER lBegin; lBegin.HighPart = bigBit; lBegin.LowPart = littleBit; double elapsed = lEnd.QuadPart - lBegin.QuadPart; result = elapsed / static_cast<double>(frequency.QuadPart); } else { endBigBit = clock(); endLittleBit = 0; double elapsed = endBigBit - bigBit; result = elapsed / CLOCKS_PER_SEC; } if (reset) { bigBit = endBigBit; littleBit = endLittleBit; } return result; } class DynamicLibraryImpl : public DynamicLibrary { protected: HMODULE h; public: DynamicLibraryImpl(const char *modulePath) { h = ::LoadLibraryA(modulePath); } virtual ~DynamicLibraryImpl() { if (h != NULL) ::FreeLibrary(h); } // Use GetProcAddress to get a pointer to the relevant function. virtual Function FindFunction(const char *name) { if (h != NULL) { // C++ standard doesn't like casts betwen function pointers and void pointers so use a union union { FARPROC fp; Function f; } fnConv; fnConv.fp = ::GetProcAddress(h, name); return fnConv.f; } else return NULL; } virtual bool IsValid() { return h != NULL; } }; DynamicLibrary *DynamicLibrary::Load(const char *modulePath) { return static_cast<DynamicLibrary *>(new DynamicLibraryImpl(modulePath)); } ColourDesired Platform::Chrome() { return ::GetSysColor(COLOR_3DFACE); } ColourDesired Platform::ChromeHighlight() { return ::GetSysColor(COLOR_3DHIGHLIGHT); } const char *Platform::DefaultFont() { return "Verdana"; } int Platform::DefaultFontSize() { return 8; } unsigned int Platform::DoubleClickTime() { return ::GetDoubleClickTime(); } bool Platform::MouseButtonBounce() { return false; } void Platform::DebugDisplay(const char *s) { ::OutputDebugStringA(s); } bool Platform::IsKeyDown(int key) { return (::GetKeyState(key) & 0x80000000) != 0; } long Platform::SendScintilla(WindowID w, unsigned int msg, unsigned long wParam, long lParam) { return ::SendMessage(reinterpret_cast<HWND>(w), msg, wParam, lParam); } long Platform::SendScintillaPointer(WindowID w, unsigned int msg, unsigned long wParam, void *lParam) { return ::SendMessage(reinterpret_cast<HWND>(w), msg, wParam, reinterpret_cast<LPARAM>(lParam)); } bool Platform::IsDBCSLeadByte(int codePage, char ch) { return ::IsDBCSLeadByteEx(codePage, ch) != 0; } int Platform::DBCSCharLength(int codePage, const char *s) { return (::IsDBCSLeadByteEx(codePage, s[0]) != 0) ? 2 : 1; } int Platform::DBCSCharMaxLength() { return 2; } // These are utility functions not really tied to a platform int Platform::Minimum(int a, int b) { if (a < b) return a; else return b; } int Platform::Maximum(int a, int b) { if (a > b) return a; else return b; } //#define TRACE #ifdef TRACE void Platform::DebugPrintf(const char *format, ...) { char buffer[2000]; va_list pArguments; va_start(pArguments, format); vsprintf(buffer,format,pArguments); va_end(pArguments); Platform::DebugDisplay(buffer); } #else void Platform::DebugPrintf(const char *, ...) { } #endif static bool assertionPopUps = true; bool Platform::ShowAssertionPopUps(bool assertionPopUps_) { bool ret = assertionPopUps; assertionPopUps = assertionPopUps_; return ret; } void Platform::Assert(const char *c, const char *file, int line) { char buffer[2000]; sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line); if (assertionPopUps) { int idButton = ::MessageBoxA(0, buffer, "Assertion failure", MB_ABORTRETRYIGNORE|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL); if (idButton == IDRETRY) { ::DebugBreak(); } else if (idButton == IDIGNORE) { // all OK } else { abort(); } } else { strcat(buffer, "\r\n"); Platform::DebugDisplay(buffer); ::DebugBreak(); abort(); } } int Platform::Clamp(int val, int minVal, int maxVal) { if (val > maxVal) val = maxVal; if (val < minVal) val = minVal; return val; } void Platform_Initialise(void *hInstance) { OSVERSIONINFO osv = {sizeof(OSVERSIONINFO),0,0,0,0,TEXT("")}; ::GetVersionEx(&osv); onNT = osv.dwPlatformId == VER_PLATFORM_WIN32_NT; ::InitializeCriticalSection(&crPlatformLock); hinstPlatformRes = reinterpret_cast<HINSTANCE>(hInstance); // This may be called from DllMain, in which case the call to LoadLibrary // is bad because it can upset the DLL load order. if (!hDLLImage) { hDLLImage = ::LoadLibrary(TEXT("Msimg32")); } if (hDLLImage) { AlphaBlendFn = (AlphaBlendSig)::GetProcAddress(hDLLImage, "AlphaBlend"); } if (!hDLLUser32) { hDLLUser32 = ::LoadLibrary(TEXT("User32")); } if (hDLLUser32) { MonitorFromPointFn = (MonitorFromPointSig)::GetProcAddress(hDLLUser32, "MonitorFromPoint"); MonitorFromRectFn = (MonitorFromRectSig)::GetProcAddress(hDLLUser32, "MonitorFromRect"); GetMonitorInfoFn = (GetMonitorInfoSig)::GetProcAddress(hDLLUser32, "GetMonitorInfoA"); } ListBoxX_Register(); } void Platform_Finalise() { if (reverseArrowCursor != NULL) ::DestroyCursor(reverseArrowCursor); ListBoxX_Unregister(); ::DeleteCriticalSection(&crPlatformLock); } |
Added win32/PlatWin.h.
> > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// Scintilla source code edit control /** @file PlatWin.h ** Implementation of platform facilities on Windows. **/ // Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. extern bool IsNT(); extern void Platform_Initialise(void *hInstance); extern void Platform_Finalise(); #if defined(USE_D2D) extern bool LoadD2D(); extern ID2D1Factory *pD2DFactory; extern IDWriteFactory *pIDWriteFactory; #endif |
Added win32/SciTE.properties.
> > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
command.build.SConstruct=scons.bat . command.name.1.SConstruct=scons clean command.1.SConstruct=scons.bat --clean . command.build.*.mak=nmake -f $(FileNameExt) DEBUG=1 QUIET=1 command.name.1.*.mak=nmake clean command.1.*.mak=nmake -f $(FileNameExt) clean command.name.2.*.mak=Borland Make command.2.*.mak=make -f $(FileNameExt) command.subsystem.2.*.mak=0 command.name.3.*.mak=make clean command.3.*.mak=make -f $(FileNameExt) clean command.name.4.*.mak=make debug command.4.*.mak=make DEBUG=1 -f $(FileNameExt) command.name.5.*.mak=nmake debug command.5.*.mak=nmake DEBUG=1 -f $(FileNameExt) # SciTE.properties is the per directory local options file and can be used to override # settings made in SciTEGlobal.properties command.build.*.cxx=nmake -f scintilla.mak DEBUG=1 QUIET=1 command.build.*.h=nmake -f scintilla.mak DEBUG=1 QUIET=1 command.build.*.rc=nmake -f scintilla.mak DEBUG=1 QUIET=1 |
Added win32/ScintRes.rc.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
// Resource file for Scintilla // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <windows.h> #define VERSION_SCINTILLA "3.3.0" #define VERSION_WORDS 3, 3, 0, 0 VS_VERSION_INFO VERSIONINFO FILEVERSION VERSION_WORDS PRODUCTVERSION VERSION_WORDS FILEFLAGSMASK 0x3fL FILEFLAGS 0 FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_APP FILESUBTYPE VFT2_UNKNOWN BEGIN BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Neil Hodgson neilh@scintilla.org\0" VALUE "FileDescription", "Scintilla.DLL - a Source Editing Component\0" VALUE "FileVersion", VERSION_SCINTILLA "\0" VALUE "InternalName", "Scintilla\0" VALUE "LegalCopyright", "Copyright 1998-2012 by Neil Hodgson\0" VALUE "OriginalFilename", "Scintilla.DLL\0" VALUE "ProductName", "Scintilla\0" VALUE "ProductVersion", VERSION_SCINTILLA "\0" END END END |
Added win32/Scintilla.def.
> > |
1 2 |
EXPORTS Scintilla_DirectFunction |
Added win32/ScintillaWin.cxx.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 |
// Scintilla source code edit control /** @file ScintillaWin.cxx ** Windows specific subclass of ScintillaBase. **/ // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org> // The License.txt file describes the conditions under which this software may be distributed. #include <new> #include <stdlib.h> #include <string.h> #include <stdio.h> #include <ctype.h> #include <assert.h> #include <limits.h> #include <string> #include <vector> #include <map> #undef _WIN32_WINNT #define _WIN32_WINNT 0x0500 #undef WINVER #define WINVER 0x0500 #include <windows.h> #include <commctrl.h> #include <richedit.h> #include <windowsx.h> #if defined(NTDDI_WIN7) && !defined(DISABLE_D2D) #define USE_D2D 1 #endif #if defined(USE_D2D) #include <d2d1.h> #include <dwrite.h> #endif #include "Platform.h" #include "ILexer.h" #include "Scintilla.h" #ifdef SCI_LEXER #include "SciLexer.h" #include "LexerModule.h" #endif #include "SplitVector.h" #include "Partitioning.h" #include "RunStyles.h" #include "ContractionState.h" #include "CellBuffer.h" #include "CallTip.h" #include "KeyMap.h" #include "Indicator.h" #include "XPM.h" #include "LineMarker.h" #include "Style.h" #include "AutoComplete.h" #include "ViewStyle.h" #include "CharClassify.h" #include "Decoration.h" #include "Document.h" #include "Selection.h" #include "PositionCache.h" #include "Editor.h" #include "ScintillaBase.h" #include "UniConversion.h" #include "PlatWin.h" #ifdef SCI_LEXER #include "ExternalLexer.h" #endif #ifndef SPI_GETWHEELSCROLLLINES #define SPI_GETWHEELSCROLLLINES 104 #endif #ifndef WM_UNICHAR #define WM_UNICHAR 0x0109 #endif #ifndef UNICODE_NOCHAR #define UNICODE_NOCHAR 0xFFFF #endif #ifndef WM_IME_STARTCOMPOSITION #include <imm.h> #endif #include <commctrl.h> #ifndef __DMC__ #include <zmouse.h> #endif #include <ole2.h> #ifndef MK_ALT #define MK_ALT 32 #endif #define SC_WIN_IDLE 5001 typedef BOOL (WINAPI *TrackMouseEventSig)(LPTRACKMOUSEEVENT); // GCC has trouble with the standard COM ABI so do it the old C way with explicit vtables. const TCHAR scintillaClassName[] = TEXT("Scintilla"); const TCHAR callClassName[] = TEXT("CallTip"); #ifdef SCI_NAMESPACE using namespace Scintilla; #endif // Take care of 32/64 bit pointers #ifdef GetWindowLongPtr static void *PointerFromWindow(HWND hWnd) { return reinterpret_cast<void *>(::GetWindowLongPtr(hWnd, 0)); } static void SetWindowPointer(HWND hWnd, void *ptr) { ::SetWindowLongPtr(hWnd, 0, reinterpret_cast<LONG_PTR>(ptr)); } static void SetWindowID(HWND hWnd, int identifier) { ::SetWindowLongPtr(hWnd, GWLP_ID, identifier); } #else static void *PointerFromWindow(HWND hWnd) { return reinterpret_cast<void *>(::GetWindowLong(hWnd, 0)); } static void SetWindowPointer(HWND hWnd, void *ptr) { ::SetWindowLong(hWnd, 0, reinterpret_cast<LONG>(ptr)); } static void SetWindowID(HWND hWnd, int identifier) { ::SetWindowLong(hWnd, GWL_ID, identifier); } #endif class ScintillaWin; // Forward declaration for COM interface subobjects typedef void VFunction(void); /** */ class FormatEnumerator { public: VFunction **vtbl; int ref; int pos; CLIPFORMAT formats[2]; int formatsLen; FormatEnumerator(int pos_, CLIPFORMAT formats_[], int formatsLen_); }; /** */ class DropSource { public: VFunction **vtbl; ScintillaWin *sci; DropSource(); }; /** */ class DataObject { public: VFunction **vtbl; ScintillaWin *sci; DataObject(); }; /** */ class DropTarget { public: VFunction **vtbl; ScintillaWin *sci; DropTarget(); }; /** */ class ScintillaWin : public ScintillaBase { bool lastKeyDownConsumed; bool capturedMouse; bool trackedMouseLeave; TrackMouseEventSig TrackMouseEventFn; unsigned int linesPerScroll; ///< Intellimouse support int wheelDelta; ///< Wheel delta from roll HRGN hRgnUpdate; bool hasOKText; CLIPFORMAT cfColumnSelect; CLIPFORMAT cfLineSelect; HRESULT hrOle; DropSource ds; DataObject dob; DropTarget dt; static HINSTANCE hInstance; #if defined(USE_D2D) ID2D1HwndRenderTarget *pRenderTarget; bool renderTargetValid; #endif ScintillaWin(HWND hwnd); ScintillaWin(const ScintillaWin &); virtual ~ScintillaWin(); ScintillaWin &operator=(const ScintillaWin &); virtual void Initialise(); virtual void Finalise(); void EnsureRenderTarget(); void DropRenderTarget(); HWND MainHWND(); static sptr_t DirectFunction( ScintillaWin *sci, UINT iMessage, uptr_t wParam, sptr_t lParam); static sptr_t PASCAL SWndProc( HWND hWnd, UINT iMessage, WPARAM wParam, sptr_t lParam); static sptr_t PASCAL CTWndProc( HWND hWnd, UINT iMessage, WPARAM wParam, sptr_t lParam); enum { invalidTimerID, standardTimerID, idleTimerID }; virtual bool DragThreshold(Point ptStart, Point ptNow); virtual void StartDrag(); sptr_t WndPaint(uptr_t wParam); sptr_t HandleComposition(uptr_t wParam, sptr_t lParam); UINT CodePageOfDocument(); virtual bool ValidCodePage(int codePage) const; virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); virtual bool SetIdle(bool on); virtual void SetTicking(bool on); virtual void SetMouseCapture(bool on); virtual bool HaveMouseCapture(); virtual void SetTrackMouseLeaveEvent(bool on); virtual bool PaintContains(PRectangle rc); virtual void ScrollText(int linesToMove); virtual void UpdateSystemCaret(); virtual void SetVerticalScrollPos(); virtual void SetHorizontalScrollPos(); virtual bool ModifyScrollBars(int nMax, int nPage); virtual void NotifyChange(); virtual void NotifyFocus(bool focus); virtual void SetCtrlID(int identifier); virtual int GetCtrlID(); virtual void NotifyParent(SCNotification scn); virtual void NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt); virtual CaseFolder *CaseFolderForEncoding(); virtual std::string CaseMapString(const std::string &s, int caseMapping); virtual void Copy(); virtual void CopyAllowLine(); virtual bool CanPaste(); virtual void Paste(); virtual void CreateCallTipWindow(PRectangle rc); virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true); virtual void ClaimSelection(); // DBCS void ImeStartComposition(); void ImeEndComposition(); void AddCharBytes(char b0, char b1); void GetIntelliMouseParameters(); virtual void CopyToClipboard(const SelectionText &selectedText); void ScrollMessage(WPARAM wParam); void HorizontalScrollMessage(WPARAM wParam); void FullPaint(); void FullPaintDC(HDC dc); bool IsCompatibleDC(HDC dc); DWORD EffectFromState(DWORD grfKeyState); virtual int SetScrollInfo(int nBar, LPCSCROLLINFO lpsi, BOOL bRedraw); virtual bool GetScrollInfo(int nBar, LPSCROLLINFO lpsi); void ChangeScrollPos(int barType, int pos); void InsertPasteText(const char *text, int len, SelectionPosition selStart, bool isRectangular, bool isLine); public: // Public for benefit of Scintilla_DirectFunction virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); /// Implement IUnknown STDMETHODIMP QueryInterface(REFIID riid, PVOID *ppv); STDMETHODIMP_(ULONG)AddRef(); STDMETHODIMP_(ULONG)Release(); /// Implement IDropTarget STDMETHODIMP DragEnter(LPDATAOBJECT pIDataSource, DWORD grfKeyState, POINTL pt, PDWORD pdwEffect); STDMETHODIMP DragOver(DWORD grfKeyState, POINTL pt, PDWORD pdwEffect); STDMETHODIMP DragLeave(); STDMETHODIMP Drop(LPDATAOBJECT pIDataSource, DWORD grfKeyState, POINTL pt, PDWORD pdwEffect); /// Implement important part of IDataObject STDMETHODIMP GetData(FORMATETC *pFEIn, STGMEDIUM *pSTM); static bool Register(HINSTANCE hInstance_); static bool Unregister(); friend class DropSource; friend class DataObject; friend class DropTarget; bool DragIsRectangularOK(CLIPFORMAT fmt) { return drag.rectangular && (fmt == cfColumnSelect); } private: // For use in creating a system caret bool HasCaretSizeChanged(); BOOL CreateSystemCaret(); BOOL DestroySystemCaret(); HBITMAP sysCaretBitmap; int sysCaretWidth; int sysCaretHeight; bool keysAlwaysUnicode; }; HINSTANCE ScintillaWin::hInstance = 0; ScintillaWin::ScintillaWin(HWND hwnd) { lastKeyDownConsumed = false; capturedMouse = false; trackedMouseLeave = false; TrackMouseEventFn = 0; linesPerScroll = 0; wheelDelta = 0; // Wheel delta from roll hRgnUpdate = 0; hasOKText = false; // There does not seem to be a real standard for indicating that the clipboard // contains a rectangular selection, so copy Developer Studio. cfColumnSelect = static_cast<CLIPFORMAT>( ::RegisterClipboardFormat(TEXT("MSDEVColumnSelect"))); // Likewise for line-copy (copies a full line when no text is selected) cfLineSelect = static_cast<CLIPFORMAT>( ::RegisterClipboardFormat(TEXT("MSDEVLineSelect"))); hrOle = E_FAIL; wMain = hwnd; dob.sci = this; ds.sci = this; dt.sci = this; sysCaretBitmap = 0; sysCaretWidth = 0; sysCaretHeight = 0; #if defined(USE_D2D) pRenderTarget = 0; renderTargetValid = true; #endif keysAlwaysUnicode = false; caret.period = ::GetCaretBlinkTime(); if (caret.period < 0) caret.period = 0; Initialise(); } ScintillaWin::~ScintillaWin() {} void ScintillaWin::Initialise() { // Initialize COM. If the app has already done this it will have // no effect. If the app hasnt, we really shouldnt ask them to call // it just so this internal feature works. hrOle = ::OleInitialize(NULL); // Find TrackMouseEvent which is available on Windows > 95 HMODULE user32 = ::GetModuleHandle(TEXT("user32.dll")); if (user32) TrackMouseEventFn = (TrackMouseEventSig)::GetProcAddress(user32, "TrackMouseEvent"); if (TrackMouseEventFn == NULL) { // Windows 95 has an emulation in comctl32.dll:_TrackMouseEvent HMODULE commctrl32 = ::LoadLibrary(TEXT("comctl32.dll")); if (commctrl32 != NULL) { TrackMouseEventFn = (TrackMouseEventSig) ::GetProcAddress(commctrl32, "_TrackMouseEvent"); } } } void ScintillaWin::Finalise() { ScintillaBase::Finalise(); SetTicking(false); SetIdle(false); DropRenderTarget(); ::RevokeDragDrop(MainHWND()); if (SUCCEEDED(hrOle)) { ::OleUninitialize(); } } void ScintillaWin::EnsureRenderTarget() { #if defined(USE_D2D) if (!renderTargetValid) { DropRenderTarget(); renderTargetValid = true; } if (pD2DFactory && !pRenderTarget) { RECT rc; HWND hw = MainHWND(); GetClientRect(hw, &rc); D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top); // Create a Direct2D render target. #if 1 pD2DFactory->CreateHwndRenderTarget( D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, D2D1::PixelFormat(), 96.0, 96.0), D2D1::HwndRenderTargetProperties(hw, size), &pRenderTarget); #else pD2DFactory->CreateHwndRenderTarget( D2D1::RenderTargetProperties( D2D1_RENDER_TARGET_TYPE_DEFAULT , D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), 96.0f, 96.0f, D2D1_RENDER_TARGET_USAGE_NONE, D2D1_FEATURE_LEVEL_DEFAULT), D2D1::HwndRenderTargetProperties(hw, size), &pRenderTarget); #endif // Pixmaps were created to be compatible with previous render target so // need to be recreated. DropGraphics(false); } #endif } void ScintillaWin::DropRenderTarget() { #if defined(USE_D2D) if (pRenderTarget) { pRenderTarget->Release(); pRenderTarget = 0; } #endif } HWND ScintillaWin::MainHWND() { return reinterpret_cast<HWND>(wMain.GetID()); } bool ScintillaWin::DragThreshold(Point ptStart, Point ptNow) { int xMove = abs(ptStart.x - ptNow.x); int yMove = abs(ptStart.y - ptNow.y); return (xMove > ::GetSystemMetrics(SM_CXDRAG)) || (yMove > ::GetSystemMetrics(SM_CYDRAG)); } void ScintillaWin::StartDrag() { inDragDrop = ddDragging; DWORD dwEffect = 0; dropWentOutside = true; IDataObject *pDataObject = reinterpret_cast<IDataObject *>(&dob); IDropSource *pDropSource = reinterpret_cast<IDropSource *>(&ds); //Platform::DebugPrintf("About to DoDragDrop %x %x\n", pDataObject, pDropSource); HRESULT hr = ::DoDragDrop( pDataObject, pDropSource, DROPEFFECT_COPY | DROPEFFECT_MOVE, &dwEffect); //Platform::DebugPrintf("DoDragDrop = %x\n", hr); if (SUCCEEDED(hr)) { if ((hr == DRAGDROP_S_DROP) && (dwEffect == DROPEFFECT_MOVE) && dropWentOutside) { // Remove dragged out text ClearSelection(); } } inDragDrop = ddNone; SetDragPosition(SelectionPosition(invalidPosition)); } // Avoid warnings everywhere for old style casts by concentrating them here static WORD LoWord(DWORD l) { return LOWORD(l); } static WORD HiWord(DWORD l) { return HIWORD(l); } static int InputCodePage() { HKL inputLocale = ::GetKeyboardLayout(0); LANGID inputLang = LOWORD(inputLocale); char sCodePage[10]; int res = ::GetLocaleInfoA(MAKELCID(inputLang, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, sCodePage, sizeof(sCodePage)); if (!res) return 0; return atoi(sCodePage); } #ifndef VK_OEM_2 static const int VK_OEM_2=0xbf; static const int VK_OEM_3=0xc0; static const int VK_OEM_4=0xdb; static const int VK_OEM_5=0xdc; static const int VK_OEM_6=0xdd; #endif /** Map the key codes to their equivalent SCK_ form. */ static int KeyTranslate(int keyIn) { //PLATFORM_ASSERT(!keyIn); switch (keyIn) { case VK_DOWN: return SCK_DOWN; case VK_UP: return SCK_UP; case VK_LEFT: return SCK_LEFT; case VK_RIGHT: return SCK_RIGHT; case VK_HOME: return SCK_HOME; case VK_END: return SCK_END; case VK_PRIOR: return SCK_PRIOR; case VK_NEXT: return SCK_NEXT; case VK_DELETE: return SCK_DELETE; case VK_INSERT: return SCK_INSERT; case VK_ESCAPE: return SCK_ESCAPE; case VK_BACK: return SCK_BACK; case VK_TAB: return SCK_TAB; case VK_RETURN: return SCK_RETURN; case VK_ADD: return SCK_ADD; case VK_SUBTRACT: return SCK_SUBTRACT; case VK_DIVIDE: return SCK_DIVIDE; case VK_LWIN: return SCK_WIN; case VK_RWIN: return SCK_RWIN; case VK_APPS: return SCK_MENU; case VK_OEM_2: return '/'; case VK_OEM_3: return '`'; case VK_OEM_4: return '['; case VK_OEM_5: return '\\'; case VK_OEM_6: return ']'; default: return keyIn; } } LRESULT ScintillaWin::WndPaint(uptr_t wParam) { //ElapsedTime et; // Redirect assertions to debug output and save current state bool assertsPopup = Platform::ShowAssertionPopUps(false); paintState = painting; PAINTSTRUCT ps; PAINTSTRUCT *pps; bool IsOcxCtrl = (wParam != 0); // if wParam != 0, it contains // a PAINSTRUCT* from the OCX // Removed since this interferes with reporting other assertions as it occurs repeatedly //PLATFORM_ASSERT(hRgnUpdate == NULL); hRgnUpdate = ::CreateRectRgn(0, 0, 0, 0); if (IsOcxCtrl) { pps = reinterpret_cast<PAINTSTRUCT*>(wParam); } else { ::GetUpdateRgn(MainHWND(), hRgnUpdate, FALSE); pps = &ps; ::BeginPaint(MainHWND(), pps); } if (technology == SC_TECHNOLOGY_DEFAULT) { AutoSurface surfaceWindow(pps->hdc, this); if (surfaceWindow) { rcPaint = PRectangle(pps->rcPaint.left, pps->rcPaint.top, pps->rcPaint.right, pps->rcPaint.bottom); PRectangle rcClient = GetClientRectangle(); paintingAllText = rcPaint.Contains(rcClient); Paint(surfaceWindow, rcPaint); surfaceWindow->Release(); } } else { #if defined(USE_D2D) EnsureRenderTarget(); AutoSurface surfaceWindow(pRenderTarget, this); if (surfaceWindow) { pRenderTarget->BeginDraw(); rcPaint = PRectangle(pps->rcPaint.left, pps->rcPaint.top, pps->rcPaint.right, pps->rcPaint.bottom); PRectangle rcClient = GetClientRectangle(); paintingAllText = rcPaint.Contains(rcClient); Paint(surfaceWindow, rcPaint); surfaceWindow->Release(); HRESULT hr = pRenderTarget->EndDraw(); if (hr == D2DERR_RECREATE_TARGET) { DropRenderTarget(); } } #endif } if (hRgnUpdate) { ::DeleteRgn(hRgnUpdate); hRgnUpdate = 0; } if (!IsOcxCtrl) ::EndPaint(MainHWND(), pps); if (paintState == paintAbandoned) { // Painting area was insufficient to cover new styling or brace highlight positions FullPaint(); } paintState = notPainting; // Restore debug output state Platform::ShowAssertionPopUps(assertsPopup); //Platform::DebugPrintf("Paint took %g\n", et.Duration()); return 0l; } sptr_t ScintillaWin::HandleComposition(uptr_t wParam, sptr_t lParam) { #ifdef __DMC__ // Digital Mars compiler does not include Imm library return 0; #else if (lParam & GCS_RESULTSTR) { HIMC hIMC = ::ImmGetContext(MainHWND()); if (hIMC) { const int maxLenInputIME = 200; wchar_t wcs[maxLenInputIME]; LONG bytes = ::ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, wcs, (maxLenInputIME-1)*2); int wides = bytes / 2; if (IsUnicodeMode()) { char utfval[maxLenInputIME * 3]; unsigned int len = UTF8Length(wcs, wides); UTF8FromUTF16(wcs, wides, utfval, len); utfval[len] = '\0'; AddCharUTF(utfval, len); } else { char dbcsval[maxLenInputIME * 2]; int size = ::WideCharToMultiByte(InputCodePage(), 0, wcs, wides, dbcsval, sizeof(dbcsval) - 1, 0, 0); for (int i=0; i<size; i++) { AddChar(dbcsval[i]); } } // Set new position after converted Point pos = PointMainCaret(); COMPOSITIONFORM CompForm; CompForm.dwStyle = CFS_POINT; CompForm.ptCurrentPos.x = pos.x; CompForm.ptCurrentPos.y = pos.y; ::ImmSetCompositionWindow(hIMC, &CompForm); ::ImmReleaseContext(MainHWND(), hIMC); } return 0; } return ::DefWindowProc(MainHWND(), WM_IME_COMPOSITION, wParam, lParam); #endif } // Translate message IDs from WM_* and EM_* to SCI_* so can partly emulate Windows Edit control static unsigned int SciMessageFromEM(unsigned int iMessage) { switch (iMessage) { case EM_CANPASTE: return SCI_CANPASTE; case EM_CANUNDO: return SCI_CANUNDO; case EM_EMPTYUNDOBUFFER: return SCI_EMPTYUNDOBUFFER; case EM_FINDTEXTEX: return SCI_FINDTEXT; case EM_FORMATRANGE: return SCI_FORMATRANGE; case EM_GETFIRSTVISIBLELINE: return SCI_GETFIRSTVISIBLELINE; case EM_GETLINECOUNT: return SCI_GETLINECOUNT; case EM_GETSELTEXT: return SCI_GETSELTEXT; case EM_GETTEXTRANGE: return SCI_GETTEXTRANGE; case EM_HIDESELECTION: return SCI_HIDESELECTION; case EM_LINEINDEX: return SCI_POSITIONFROMLINE; case EM_LINESCROLL: return SCI_LINESCROLL; case EM_REPLACESEL: return SCI_REPLACESEL; case EM_SCROLLCARET: return SCI_SCROLLCARET; case EM_SETREADONLY: return SCI_SETREADONLY; case WM_CLEAR: return SCI_CLEAR; case WM_COPY: return SCI_COPY; case WM_CUT: return SCI_CUT; case WM_GETTEXT: return SCI_GETTEXT; case WM_SETTEXT: return SCI_SETTEXT; case WM_GETTEXTLENGTH: return SCI_GETTEXTLENGTH; case WM_PASTE: return SCI_PASTE; case WM_UNDO: return SCI_UNDO; } return iMessage; } static UINT CodePageFromCharSet(DWORD characterSet, UINT documentCodePage) { if (documentCodePage == SC_CP_UTF8) { // The system calls here are a little slow so avoid if known case. return SC_CP_UTF8; } CHARSETINFO ci = { 0, 0, { { 0, 0, 0, 0 }, { 0, 0 } } }; BOOL bci = ::TranslateCharsetInfo(reinterpret_cast<DWORD*>(static_cast<uptr_t>(characterSet)), &ci, TCI_SRCCHARSET); UINT cp; if (bci) cp = ci.ciACP; else cp = documentCodePage; CPINFO cpi; if (!IsValidCodePage(cp) && !GetCPInfo(cp, &cpi)) cp = CP_ACP; return cp; } UINT ScintillaWin::CodePageOfDocument() { return CodePageFromCharSet(vs.styles[STYLE_DEFAULT].characterSet, pdoc->dbcsCodePage); } sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { try { //Platform::DebugPrintf("S M:%x WP:%x L:%x\n", iMessage, wParam, lParam); iMessage = SciMessageFromEM(iMessage); switch (iMessage) { case WM_CREATE: ctrlID = ::GetDlgCtrlID(reinterpret_cast<HWND>(wMain.GetID())); // Get Intellimouse scroll line parameters GetIntelliMouseParameters(); ::RegisterDragDrop(MainHWND(), reinterpret_cast<IDropTarget *>(&dt)); break; case WM_COMMAND: Command(LoWord(wParam)); break; case WM_PAINT: return WndPaint(wParam); case WM_PRINTCLIENT: { HDC hdc = reinterpret_cast<HDC>(wParam); if (!IsCompatibleDC(hdc)) { return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); } FullPaintDC(hdc); } break; case WM_VSCROLL: ScrollMessage(wParam); break; case WM_HSCROLL: HorizontalScrollMessage(wParam); break; case WM_SIZE: { #if defined(USE_D2D) if (paintState == notPainting) { DropRenderTarget(); } else { renderTargetValid = false; } #endif //Platform::DebugPrintf("Scintilla WM_SIZE %d %d\n", LoWord(lParam), HiWord(lParam)); ChangeSize(); } break; case WM_MOUSEWHEEL: // if autocomplete list active then send mousewheel message to it if (ac.Active()) { HWND hWnd = reinterpret_cast<HWND>(ac.lb->GetID()); ::SendMessage(hWnd, iMessage, wParam, lParam); break; } // Don't handle datazoom. // (A good idea for datazoom would be to "fold" or "unfold" details. // i.e. if datazoomed out only class structures are visible, when datazooming in the control // structures appear, then eventually the individual statements...) if (wParam & MK_SHIFT) { return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); } // Either SCROLL or ZOOM. We handle the wheel steppings calculation wheelDelta -= static_cast<short>(HiWord(wParam)); if (abs(wheelDelta) >= WHEEL_DELTA && linesPerScroll > 0) { int linesToScroll = linesPerScroll; if (linesPerScroll == WHEEL_PAGESCROLL) linesToScroll = LinesOnScreen() - 1; if (linesToScroll == 0) { linesToScroll = 1; } linesToScroll *= (wheelDelta / WHEEL_DELTA); if (wheelDelta >= 0) wheelDelta = wheelDelta % WHEEL_DELTA; else wheelDelta = - (-wheelDelta % WHEEL_DELTA); if (wParam & MK_CONTROL) { // Zoom! We play with the font sizes in the styles. // Number of steps/line is ignored, we just care if sizing up or down if (linesToScroll < 0) { KeyCommand(SCI_ZOOMIN); } else { KeyCommand(SCI_ZOOMOUT); } } else { // Scroll ScrollTo(topLine + linesToScroll); } } return 0; case WM_TIMER: if (wParam == standardTimerID && timer.ticking) { Tick(); } else if (wParam == idleTimerID && idler.state) { SendMessage(MainHWND(), SC_WIN_IDLE, 0, 1); } else { return 1; } break; case SC_WIN_IDLE: // wParam=dwTickCountInitial, or 0 to initialize. lParam=bSkipUserInputTest if (idler.state) { if (lParam || (WAIT_TIMEOUT == MsgWaitForMultipleObjects(0, 0, 0, 0, QS_INPUT|QS_HOTKEY))) { if (Idle()) { // User input was given priority above, but all events do get a turn. Other // messages, notifications, etc. will get interleaved with the idle messages. // However, some things like WM_PAINT are a lower priority, and will not fire // when there's a message posted. So, several times a second, we stop and let // the low priority events have a turn (after which the timer will fire again). DWORD dwCurrent = GetTickCount(); DWORD dwStart = wParam ? wParam : dwCurrent; const DWORD maxWorkTime = 50; if (dwCurrent >= dwStart && dwCurrent > maxWorkTime && dwCurrent - maxWorkTime < dwStart) PostMessage(MainHWND(), SC_WIN_IDLE, dwStart, 0); } else { SetIdle(false); } } } break; case WM_GETMINMAXINFO: return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); case WM_LBUTTONDOWN: { #ifndef __DMC__ // Digital Mars compiler does not include Imm library // For IME, set the composition string as the result string. HIMC hIMC = ::ImmGetContext(MainHWND()); ::ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0); ::ImmReleaseContext(MainHWND(), hIMC); #endif // //Platform::DebugPrintf("Buttdown %d %x %x %x %x %x\n",iMessage, wParam, lParam, // Platform::IsKeyDown(VK_SHIFT), // Platform::IsKeyDown(VK_CONTROL), // Platform::IsKeyDown(VK_MENU)); ::SetFocus(MainHWND()); ButtonDown(Point::FromLong(lParam), ::GetMessageTime(), (wParam & MK_SHIFT) != 0, (wParam & MK_CONTROL) != 0, Platform::IsKeyDown(VK_MENU)); } break; case WM_MOUSEMOVE: SetTrackMouseLeaveEvent(true); ButtonMove(Point::FromLong(lParam)); break; case WM_MOUSELEAVE: SetTrackMouseLeaveEvent(false); MouseLeave(); return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); case WM_LBUTTONUP: ButtonUp(Point::FromLong(lParam), ::GetMessageTime(), (wParam & MK_CONTROL) != 0); break; case WM_RBUTTONDOWN: ::SetFocus(MainHWND()); if (!PointInSelection(Point::FromLong(lParam))) { CancelModes(); SetEmptySelection(PositionFromLocation(Point::FromLong(lParam))); } break; case WM_SETCURSOR: if (LoWord(lParam) == HTCLIENT) { if (inDragDrop == ddDragging) { DisplayCursor(Window::cursorUp); } else { // Display regular (drag) cursor over selection POINT pt; if (0 != ::GetCursorPos(&pt)) { ::ScreenToClient(MainHWND(), &pt); if (PointInSelMargin(Point(pt.x, pt.y))) { DisplayCursor(GetMarginCursor(Point(pt.x, pt.y))); } else if (PointInSelection(Point(pt.x, pt.y)) && !SelectionEmpty()) { DisplayCursor(Window::cursorArrow); } else if (PointIsHotspot(Point(pt.x, pt.y))) { DisplayCursor(Window::cursorHand); } else { DisplayCursor(Window::cursorText); } } } return TRUE; } else { return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); } case WM_CHAR: if (((wParam >= 128) || !iscntrl(wParam)) || !lastKeyDownConsumed) { if (::IsWindowUnicode(MainHWND()) || keysAlwaysUnicode) { wchar_t wcs[2] = {static_cast<wchar_t>(wParam), 0}; if (IsUnicodeMode()) { // For a wide character version of the window: char utfval[4]; unsigned int len = UTF8Length(wcs, 1); UTF8FromUTF16(wcs, 1, utfval, len); AddCharUTF(utfval, len); } else { UINT cpDest = CodePageOfDocument(); char inBufferCP[20]; int size = ::WideCharToMultiByte(cpDest, 0, wcs, 1, inBufferCP, sizeof(inBufferCP) - 1, 0, 0); inBufferCP[size] = '\0'; AddCharUTF(inBufferCP, size); } } else { if (IsUnicodeMode()) { AddCharBytes('\0', LOBYTE(wParam)); } else { AddChar(LOBYTE(wParam)); } } } return 0; case WM_UNICHAR: if (wParam == UNICODE_NOCHAR) { return IsUnicodeMode() ? 1 : 0; } else if (lastKeyDownConsumed) { return 1; } else { if (IsUnicodeMode()) { char utfval[4]; wchar_t wcs[2] = {static_cast<wchar_t>(wParam), 0}; unsigned int len = UTF8Length(wcs, 1); UTF8FromUTF16(wcs, 1, utfval, len); AddCharUTF(utfval, len); return 1; } else { return 0; } } case WM_SYSKEYDOWN: case WM_KEYDOWN: { //Platform::DebugPrintf("S keydown %d %x %x %x %x\n",iMessage, wParam, lParam, ::IsKeyDown(VK_SHIFT), ::IsKeyDown(VK_CONTROL)); lastKeyDownConsumed = false; int ret = KeyDown(KeyTranslate(wParam), Platform::IsKeyDown(VK_SHIFT), Platform::IsKeyDown(VK_CONTROL), Platform::IsKeyDown(VK_MENU), &lastKeyDownConsumed); if (!ret && !lastKeyDownConsumed) { return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); } break; } case WM_IME_KEYDOWN: return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); case WM_KEYUP: //Platform::DebugPrintf("S keyup %d %x %x\n",iMessage, wParam, lParam); return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); case WM_SETTINGCHANGE: //Platform::DebugPrintf("Setting Changed\n"); InvalidateStyleData(); // Get Intellimouse scroll line parameters GetIntelliMouseParameters(); break; case WM_GETDLGCODE: return DLGC_HASSETSEL | DLGC_WANTALLKEYS; case WM_KILLFOCUS: { HWND wOther = reinterpret_cast<HWND>(wParam); HWND wThis = MainHWND(); HWND wCT = reinterpret_cast<HWND>(ct.wCallTip.GetID()); if (!wParam || !(::IsChild(wThis, wOther) || (wOther == wCT))) { SetFocusState(false); DestroySystemCaret(); } } break; case WM_SETFOCUS: SetFocusState(true); DestroySystemCaret(); CreateSystemCaret(); break; case WM_SYSCOLORCHANGE: //Platform::DebugPrintf("Setting Changed\n"); InvalidateStyleData(); break; case WM_IME_STARTCOMPOSITION: // dbcs ImeStartComposition(); return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); case WM_IME_ENDCOMPOSITION: // dbcs ImeEndComposition(); return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); case WM_IME_COMPOSITION: return HandleComposition(wParam, lParam); case WM_IME_CHAR: { AddCharBytes(HIBYTE(wParam), LOBYTE(wParam)); return 0; } case WM_CONTEXTMENU: if (displayPopupMenu) { Point pt = Point::FromLong(lParam); if ((pt.x == -1) && (pt.y == -1)) { // Caused by keyboard so display menu near caret pt = PointMainCaret(); POINT spt = {static_cast<int>(pt.x), static_cast<int>(pt.y)}; ::ClientToScreen(MainHWND(), &spt); pt = Point(spt.x, spt.y); } ContextMenu(pt); return 0; } return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); case WM_INPUTLANGCHANGE: //::SetThreadLocale(LOWORD(lParam)); return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); case WM_INPUTLANGCHANGEREQUEST: return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); case WM_ERASEBKGND: return 1; // Avoid any background erasure as whole window painted. case WM_CAPTURECHANGED: capturedMouse = false; return 0; // These are not handled in Scintilla and its faster to dispatch them here. // Also moves time out to here so profile doesn't count lots of empty message calls. case WM_MOVE: case WM_MOUSEACTIVATE: case WM_NCHITTEST: case WM_NCCALCSIZE: case WM_NCPAINT: case WM_NCMOUSEMOVE: case WM_NCLBUTTONDOWN: case WM_IME_SETCONTEXT: case WM_IME_NOTIFY: case WM_SYSCOMMAND: case WM_WINDOWPOSCHANGING: case WM_WINDOWPOSCHANGED: return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); case EM_LINEFROMCHAR: if (static_cast<int>(wParam) < 0) { wParam = SelectionStart().Position(); } return pdoc->LineFromPosition(wParam); case EM_EXLINEFROMCHAR: return pdoc->LineFromPosition(lParam); case EM_GETSEL: if (wParam) { *reinterpret_cast<int *>(wParam) = SelectionStart().Position(); } if (lParam) { *reinterpret_cast<int *>(lParam) = SelectionEnd().Position(); } return MAKELONG(SelectionStart().Position(), SelectionEnd().Position()); case EM_EXGETSEL: { if (lParam == 0) { return 0; } Sci_CharacterRange *pCR = reinterpret_cast<Sci_CharacterRange *>(lParam); pCR->cpMin = SelectionStart().Position(); pCR->cpMax = SelectionEnd().Position(); } break; case EM_SETSEL: { int nStart = static_cast<int>(wParam); int nEnd = static_cast<int>(lParam); if (nStart == 0 && nEnd == -1) { nEnd = pdoc->Length(); } if (nStart == -1) { nStart = nEnd; // Remove selection } if (nStart > nEnd) { SetSelection(nEnd, nStart); } else { SetSelection(nStart, nEnd); } EnsureCaretVisible(); } break; case EM_EXSETSEL: { if (lParam == 0) { return 0; } Sci_CharacterRange *pCR = reinterpret_cast<Sci_CharacterRange *>(lParam); sel.selType = Selection::selStream; if (pCR->cpMin == 0 && pCR->cpMax == -1) { SetSelection(pCR->cpMin, pdoc->Length()); } else { SetSelection(pCR->cpMin, pCR->cpMax); } EnsureCaretVisible(); return pdoc->LineFromPosition(SelectionStart().Position()); } case SCI_GETDIRECTFUNCTION: return reinterpret_cast<sptr_t>(DirectFunction); case SCI_GETDIRECTPOINTER: return reinterpret_cast<sptr_t>(this); case SCI_GRABFOCUS: ::SetFocus(MainHWND()); break; case SCI_SETKEYSUNICODE: keysAlwaysUnicode = wParam != 0; break; case SCI_GETKEYSUNICODE: return keysAlwaysUnicode; case SCI_SETTECHNOLOGY: if ((wParam == SC_TECHNOLOGY_DEFAULT) || (wParam == SC_TECHNOLOGY_DIRECTWRITE)) { if (technology != static_cast<int>(wParam)) { if (static_cast<int>(wParam) == SC_TECHNOLOGY_DIRECTWRITE) { #if defined(USE_D2D) if (!LoadD2D()) // Failed to load Direct2D or DirectWrite so no effect return 0; #else return 0; #endif } technology = wParam; // Invalidate all cached information including layout. DropGraphics(true); InvalidateStyleRedraw(); } } break; #ifdef SCI_LEXER case SCI_LOADLEXERLIBRARY: LexerManager::GetInstance()->Load(reinterpret_cast<const char *>(lParam)); break; #endif default: return ScintillaBase::WndProc(iMessage, wParam, lParam); } } catch (std::bad_alloc &) { errorStatus = SC_STATUS_BADALLOC; } catch (...) { errorStatus = SC_STATUS_FAILURE; } return 0l; } bool ScintillaWin::ValidCodePage(int codePage) const { return codePage == 0 || codePage == SC_CP_UTF8 || codePage == 932 || codePage == 936 || codePage == 949 || codePage == 950 || codePage == 1361; } sptr_t ScintillaWin::DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam); } void ScintillaWin::SetTicking(bool on) { if (timer.ticking != on) { timer.ticking = on; if (timer.ticking) { timer.tickerID = ::SetTimer(MainHWND(), standardTimerID, timer.tickSize, NULL) ? reinterpret_cast<TickerID>(standardTimerID) : 0; } else { ::KillTimer(MainHWND(), reinterpret_cast<uptr_t>(timer.tickerID)); timer.tickerID = 0; } } timer.ticksToWait = caret.period; } bool ScintillaWin::SetIdle(bool on) { // On Win32 the Idler is implemented as a Timer on the Scintilla window. This // takes advantage of the fact that WM_TIMER messages are very low priority, // and are only posted when the message queue is empty, i.e. during idle time. if (idler.state != on) { if (on) { idler.idlerID = ::SetTimer(MainHWND(), idleTimerID, 10, NULL) ? reinterpret_cast<IdlerID>(idleTimerID) : 0; } else { ::KillTimer(MainHWND(), reinterpret_cast<uptr_t>(idler.idlerID)); idler.idlerID = 0; } idler.state = idler.idlerID != 0; } return idler.state; } void ScintillaWin::SetMouseCapture(bool on) { if (mouseDownCaptures) { if (on) { ::SetCapture(MainHWND()); } else { ::ReleaseCapture(); } } capturedMouse = on; } bool ScintillaWin::HaveMouseCapture() { // Cannot just see if GetCapture is this window as the scroll bar also sets capture for the window return capturedMouse; //return capturedMouse && (::GetCapture() == MainHWND()); } void ScintillaWin::SetTrackMouseLeaveEvent(bool on) { if (on && TrackMouseEventFn && !trackedMouseLeave) { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(tme); tme.dwFlags = TME_LEAVE; tme.hwndTrack = MainHWND(); TrackMouseEventFn(&tme); } trackedMouseLeave = on; } bool ScintillaWin::PaintContains(PRectangle rc) { bool contains = true; if ((paintState == painting) && (!rc.Empty())) { if (!rcPaint.Contains(rc)) { contains = false; } else { // In bounding rectangle so check more accurately using region HRGN hRgnRange = ::CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom); if (hRgnRange) { HRGN hRgnDest = ::CreateRectRgn(0, 0, 0, 0); if (hRgnDest) { int combination = ::CombineRgn(hRgnDest, hRgnRange, hRgnUpdate, RGN_DIFF); if (combination != NULLREGION) { contains = false; } ::DeleteRgn(hRgnDest); } ::DeleteRgn(hRgnRange); } } } return contains; } void ScintillaWin::ScrollText(int /* linesToMove */) { //Platform::DebugPrintf("ScintillaWin::ScrollText %d\n", linesToMove); //::ScrollWindow(MainHWND(), 0, // vs.lineHeight * linesToMove, 0, 0); //::UpdateWindow(MainHWND()); Redraw(); } void ScintillaWin::UpdateSystemCaret() { if (hasFocus) { if (HasCaretSizeChanged()) { DestroySystemCaret(); CreateSystemCaret(); } Point pos = PointMainCaret(); ::SetCaretPos(pos.x, pos.y); } } int ScintillaWin::SetScrollInfo(int nBar, LPCSCROLLINFO lpsi, BOOL bRedraw) { return ::SetScrollInfo(MainHWND(), nBar, lpsi, bRedraw); } bool ScintillaWin::GetScrollInfo(int nBar, LPSCROLLINFO lpsi) { return ::GetScrollInfo(MainHWND(), nBar, lpsi) ? true : false; } // Change the scroll position but avoid repaint if changing to same value void ScintillaWin::ChangeScrollPos(int barType, int pos) { SCROLLINFO sci = { sizeof(sci), 0, 0, 0, 0, 0, 0 }; sci.fMask = SIF_POS; GetScrollInfo(barType, &sci); if (sci.nPos != pos) { DwellEnd(true); sci.nPos = pos; SetScrollInfo(barType, &sci, TRUE); } } void ScintillaWin::SetVerticalScrollPos() { ChangeScrollPos(SB_VERT, topLine); } void ScintillaWin::SetHorizontalScrollPos() { ChangeScrollPos(SB_HORZ, xOffset); } bool ScintillaWin::ModifyScrollBars(int nMax, int nPage) { bool modified = false; SCROLLINFO sci = { sizeof(sci), 0, 0, 0, 0, 0, 0 }; sci.fMask = SIF_PAGE | SIF_RANGE; GetScrollInfo(SB_VERT, &sci); int vertEndPreferred = nMax; if (!verticalScrollBarVisible) nPage = vertEndPreferred + 1; if ((sci.nMin != 0) || (sci.nMax != vertEndPreferred) || (sci.nPage != static_cast<unsigned int>(nPage)) || (sci.nPos != 0)) { sci.fMask = SIF_PAGE | SIF_RANGE; sci.nMin = 0; sci.nMax = vertEndPreferred; sci.nPage = nPage; sci.nPos = 0; sci.nTrackPos = 1; SetScrollInfo(SB_VERT, &sci, TRUE); modified = true; } PRectangle rcText = GetTextRectangle(); int horizEndPreferred = scrollWidth; if (horizEndPreferred < 0) horizEndPreferred = 0; unsigned int pageWidth = rcText.Width(); if (!horizontalScrollBarVisible || (wrapState != eWrapNone)) pageWidth = horizEndPreferred + 1; sci.fMask = SIF_PAGE | SIF_RANGE; GetScrollInfo(SB_HORZ, &sci); if ((sci.nMin != 0) || (sci.nMax != horizEndPreferred) || (sci.nPage != pageWidth) || (sci.nPos != 0)) { sci.fMask = SIF_PAGE | SIF_RANGE; sci.nMin = 0; sci.nMax = horizEndPreferred; sci.nPage = pageWidth; sci.nPos = 0; sci.nTrackPos = 1; SetScrollInfo(SB_HORZ, &sci, TRUE); modified = true; if (scrollWidth < static_cast<int>(pageWidth)) { HorizontalScrollTo(0); } } return modified; } void ScintillaWin::NotifyChange() { ::SendMessage(::GetParent(MainHWND()), WM_COMMAND, MAKELONG(GetCtrlID(), SCEN_CHANGE), reinterpret_cast<LPARAM>(MainHWND())); } void ScintillaWin::NotifyFocus(bool focus) { ::SendMessage(::GetParent(MainHWND()), WM_COMMAND, MAKELONG(GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), reinterpret_cast<LPARAM>(MainHWND())); } void ScintillaWin::SetCtrlID(int identifier) { ::SetWindowID(reinterpret_cast<HWND>(wMain.GetID()), identifier); } int ScintillaWin::GetCtrlID() { return ::GetDlgCtrlID(reinterpret_cast<HWND>(wMain.GetID())); } void ScintillaWin::NotifyParent(SCNotification scn) { scn.nmhdr.hwndFrom = MainHWND(); scn.nmhdr.idFrom = GetCtrlID(); ::SendMessage(::GetParent(MainHWND()), WM_NOTIFY, GetCtrlID(), reinterpret_cast<LPARAM>(&scn)); } void ScintillaWin::NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt) { //Platform::DebugPrintf("ScintillaWin Double click 0\n"); ScintillaBase::NotifyDoubleClick(pt, shift, ctrl, alt); // Send myself a WM_LBUTTONDBLCLK, so the container can handle it too. ::SendMessage(MainHWND(), WM_LBUTTONDBLCLK, shift ? MK_SHIFT : 0, MAKELPARAM(pt.x, pt.y)); } class CaseFolderUTF8 : public CaseFolderTable { // Allocate the expandable storage here so that it does not need to be reallocated // for each call to Fold. std::vector<wchar_t> utf16Mixed; std::vector<wchar_t> utf16Folded; public: CaseFolderUTF8() { StandardASCII(); } virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) { if ((lenMixed == 1) && (sizeFolded > 0)) { folded[0] = mapping[static_cast<unsigned char>(mixed[0])]; return 1; } else { if (lenMixed > utf16Mixed.size()) { utf16Mixed.resize(lenMixed + 8); } size_t nUtf16Mixed = ::MultiByteToWideChar(65001, 0, mixed, static_cast<int>(lenMixed), &utf16Mixed[0], static_cast<int>(utf16Mixed.size())); if (nUtf16Mixed == 0) { // Failed to convert -> bad UTF-8 folded[0] = '\0'; return 1; } if (nUtf16Mixed * 4 > utf16Folded.size()) { // Maximum folding expansion factor of 4 utf16Folded.resize(nUtf16Mixed * 4 + 8); } int lenFlat = ::LCMapStringW(LOCALE_SYSTEM_DEFAULT, LCMAP_LINGUISTIC_CASING | LCMAP_LOWERCASE, &utf16Mixed[0], static_cast<int>(nUtf16Mixed), &utf16Folded[0], static_cast<int>(utf16Folded.size())); size_t lenOut = UTF8Length(&utf16Folded[0], lenFlat); if (lenOut < sizeFolded) { UTF8FromUTF16(&utf16Folded[0], lenFlat, folded, static_cast<int>(lenOut)); return lenOut; } else { return 0; } } } }; class CaseFolderDBCS : public CaseFolderTable { // Allocate the expandable storage here so that it does not need to be reallocated // for each call to Fold. std::vector<wchar_t> utf16Mixed; std::vector<wchar_t> utf16Folded; UINT cp; public: CaseFolderDBCS(UINT cp_) : cp(cp_) { StandardASCII(); } virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) { if ((lenMixed == 1) && (sizeFolded > 0)) { folded[0] = mapping[static_cast<unsigned char>(mixed[0])]; return 1; } else { if (lenMixed > utf16Mixed.size()) { utf16Mixed.resize(lenMixed + 8); } size_t nUtf16Mixed = ::MultiByteToWideChar(cp, 0, mixed, static_cast<int>(lenMixed), &utf16Mixed[0], static_cast<int>(utf16Mixed.size())); if (nUtf16Mixed == 0) { // Failed to convert -> bad input folded[0] = '\0'; return 1; } if (nUtf16Mixed * 4 > utf16Folded.size()) { // Maximum folding expansion factor of 4 utf16Folded.resize(nUtf16Mixed * 4 + 8); } int lenFlat = ::LCMapStringW(LOCALE_SYSTEM_DEFAULT, LCMAP_LINGUISTIC_CASING | LCMAP_LOWERCASE, &utf16Mixed[0], static_cast<int>(nUtf16Mixed), &utf16Folded[0], static_cast<int>(utf16Folded.size())); size_t lenOut = ::WideCharToMultiByte(cp, 0, &utf16Folded[0], lenFlat, NULL, 0, NULL, 0); if (lenOut < sizeFolded) { ::WideCharToMultiByte(cp, 0, &utf16Folded[0], lenFlat, folded, static_cast<int>(lenOut), NULL, 0); return lenOut; } else { return 0; } } } }; CaseFolder *ScintillaWin::CaseFolderForEncoding() { UINT cpDest = CodePageOfDocument(); if (cpDest == SC_CP_UTF8) { return new CaseFolderUTF8(); } else { if (pdoc->dbcsCodePage == 0) { CaseFolderTable *pcf = new CaseFolderTable(); pcf->StandardASCII(); // Only for single byte encodings UINT cpDoc = CodePageOfDocument(); for (int i=0x80; i<0x100; i++) { char sCharacter[2] = "A"; sCharacter[0] = static_cast<char>(i); wchar_t wCharacter[20]; unsigned int lengthUTF16 = ::MultiByteToWideChar(cpDoc, 0, sCharacter, 1, wCharacter, sizeof(wCharacter)/sizeof(wCharacter[0])); if (lengthUTF16 == 1) { wchar_t wLower[20]; int charsConverted = ::LCMapStringW(LOCALE_SYSTEM_DEFAULT, LCMAP_LINGUISTIC_CASING | LCMAP_LOWERCASE, wCharacter, lengthUTF16, wLower, sizeof(wLower)/sizeof(wLower[0])); char sCharacterLowered[20]; unsigned int lengthConverted = ::WideCharToMultiByte(cpDoc, 0, wLower, charsConverted, sCharacterLowered, sizeof(sCharacterLowered), NULL, 0); if ((lengthConverted == 1) && (sCharacter[0] != sCharacterLowered[0])) { pcf->SetTranslation(sCharacter[0], sCharacterLowered[0]); } } } return pcf; } else { return new CaseFolderDBCS(cpDest); } } } std::string ScintillaWin::CaseMapString(const std::string &s, int caseMapping) { if (s.size() == 0) return std::string(); if (caseMapping == cmSame) return s; UINT cpDoc = CodePageOfDocument(); unsigned int lengthUTF16 = ::MultiByteToWideChar(cpDoc, 0, s.c_str(), static_cast<int>(s.size()), NULL, 0); if (lengthUTF16 == 0) // Failed to convert return s; DWORD mapFlags = LCMAP_LINGUISTIC_CASING | ((caseMapping == cmUpper) ? LCMAP_UPPERCASE : LCMAP_LOWERCASE); // Many conversions performed by search function are short so optimize this case. enum { shortSize=20 }; if (s.size() > shortSize) { // Use dynamic allocations for long strings // Change text to UTF-16 std::vector<wchar_t> vwcText(lengthUTF16); ::MultiByteToWideChar(cpDoc, 0, s.c_str(), static_cast<int>(s.size()), &vwcText[0], lengthUTF16); // Change case int charsConverted = ::LCMapStringW(LOCALE_SYSTEM_DEFAULT, mapFlags, &vwcText[0], lengthUTF16, NULL, 0); std::vector<wchar_t> vwcConverted(charsConverted); ::LCMapStringW(LOCALE_SYSTEM_DEFAULT, mapFlags, &vwcText[0], lengthUTF16, &vwcConverted[0], charsConverted); // Change back to document encoding unsigned int lengthConverted = ::WideCharToMultiByte(cpDoc, 0, &vwcConverted[0], static_cast<int>(vwcConverted.size()), NULL, 0, NULL, 0); std::vector<char> vcConverted(lengthConverted); ::WideCharToMultiByte(cpDoc, 0, &vwcConverted[0], static_cast<int>(vwcConverted.size()), &vcConverted[0], static_cast<int>(vcConverted.size()), NULL, 0); return std::string(&vcConverted[0], vcConverted.size()); } else { // Use static allocations for short strings as much faster // A factor of 15 for single character strings // Change text to UTF-16 wchar_t vwcText[shortSize]; ::MultiByteToWideChar(cpDoc, 0, s.c_str(), static_cast<int>(s.size()), vwcText, lengthUTF16); // Change case int charsConverted = ::LCMapStringW(LOCALE_SYSTEM_DEFAULT, mapFlags, vwcText, lengthUTF16, NULL, 0); // Full mapping may produce up to 3 characters per input character wchar_t vwcConverted[shortSize*3]; ::LCMapStringW(LOCALE_SYSTEM_DEFAULT, mapFlags, vwcText, lengthUTF16, vwcConverted, charsConverted); // Change back to document encoding unsigned int lengthConverted = ::WideCharToMultiByte(cpDoc, 0, vwcConverted, charsConverted, NULL, 0, NULL, 0); // Each UTF-16 code unit may need up to 3 bytes in UTF-8 char vcConverted[shortSize * 3 * 3]; ::WideCharToMultiByte(cpDoc, 0, vwcConverted, charsConverted, vcConverted, lengthConverted, NULL, 0); return std::string(vcConverted, lengthConverted); } } void ScintillaWin::Copy() { //Platform::DebugPrintf("Copy\n"); if (!sel.Empty()) { SelectionText selectedText; CopySelectionRange(&selectedText); CopyToClipboard(selectedText); } } void ScintillaWin::CopyAllowLine() { SelectionText selectedText; CopySelectionRange(&selectedText, true); CopyToClipboard(selectedText); } bool ScintillaWin::CanPaste() { if (!Editor::CanPaste()) return false; if (::IsClipboardFormatAvailable(CF_TEXT)) return true; if (IsUnicodeMode()) return ::IsClipboardFormatAvailable(CF_UNICODETEXT) != 0; return false; } class GlobalMemory { HGLOBAL hand; public: void *ptr; GlobalMemory() : hand(0), ptr(0) { } GlobalMemory(HGLOBAL hand_) : hand(hand_), ptr(0) { if (hand) { ptr = ::GlobalLock(hand); } } ~GlobalMemory() { PLATFORM_ASSERT(!ptr); } void Allocate(size_t bytes) { hand = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, bytes); if (hand) { ptr = ::GlobalLock(hand); } } HGLOBAL Unlock() { PLATFORM_ASSERT(ptr); HGLOBAL handCopy = hand; ::GlobalUnlock(hand); ptr = 0; hand = 0; return handCopy; } void SetClip(UINT uFormat) { ::SetClipboardData(uFormat, Unlock()); } operator bool() const { return ptr != 0; } SIZE_T Size() { return ::GlobalSize(hand); } }; void ScintillaWin::InsertPasteText(const char *text, int len, SelectionPosition selStart, bool isRectangular, bool isLine) { if (isRectangular) { PasteRectangular(selStart, text, len); } else { char *convertedText = 0; if (convertPastes) { // Convert line endings of the paste into our local line-endings mode convertedText = Document::TransformLineEnds(&len, text, len, pdoc->eolMode); text = convertedText; } if (isLine) { int insertPos = pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())); pdoc->InsertString(insertPos, text, len); // add the newline if necessary if ((len > 0) && (text[len-1] != '\n' && text[len-1] != '\r')) { const char *endline = StringFromEOLMode(pdoc->eolMode); pdoc->InsertString(insertPos + len, endline, static_cast<int>(strlen(endline))); len += static_cast<int>(strlen(endline)); } if (sel.MainCaret() == insertPos) { SetEmptySelection(sel.MainCaret() + len); } } else { InsertPaste(selStart, text, len); } delete []convertedText; } } void ScintillaWin::Paste() { if (!::OpenClipboard(MainHWND())) return; UndoGroup ug(pdoc); bool isLine = SelectionEmpty() && (::IsClipboardFormatAvailable(cfLineSelect) != 0); ClearSelection(multiPasteMode == SC_MULTIPASTE_EACH); SelectionPosition selStart = sel.IsRectangular() ? sel.Rectangular().Start() : sel.Range(sel.Main()).Start(); bool isRectangular = ::IsClipboardFormatAvailable(cfColumnSelect) != 0; // Always use CF_UNICODETEXT if available GlobalMemory memUSelection(::GetClipboardData(CF_UNICODETEXT)); if (memUSelection) { wchar_t *uptr = static_cast<wchar_t *>(memUSelection.ptr); if (uptr) { unsigned int len; char *putf; // Default Scintilla behaviour in Unicode mode if (IsUnicodeMode()) { unsigned int bytes = memUSelection.Size(); len = UTF8Length(uptr, bytes / 2); putf = new char[len + 1]; UTF8FromUTF16(uptr, bytes / 2, putf, len); } else { // CF_UNICODETEXT available, but not in Unicode mode // Convert from Unicode to current Scintilla code page UINT cpDest = CodePageOfDocument(); len = ::WideCharToMultiByte(cpDest, 0, uptr, -1, NULL, 0, NULL, NULL) - 1; // subtract 0 terminator putf = new char[len + 1]; ::WideCharToMultiByte(cpDest, 0, uptr, -1, putf, len + 1, NULL, NULL); } InsertPasteText(putf, len, selStart, isRectangular, isLine); delete []putf; } memUSelection.Unlock(); } else { // CF_UNICODETEXT not available, paste ANSI text GlobalMemory memSelection(::GetClipboardData(CF_TEXT)); if (memSelection) { char *ptr = static_cast<char *>(memSelection.ptr); if (ptr) { unsigned int bytes = memSelection.Size(); unsigned int len = bytes; for (unsigned int i = 0; i < bytes; i++) { if ((len == bytes) && (0 == ptr[i])) len = i; } // In Unicode mode, convert clipboard text to UTF-8 if (IsUnicodeMode()) { wchar_t *uptr = new wchar_t[len+1]; unsigned int ulen = ::MultiByteToWideChar(CP_ACP, 0, ptr, len, uptr, len+1); unsigned int mlen = UTF8Length(uptr, ulen); char *putf = new char[mlen + 1]; if (putf) { // CP_UTF8 not available on Windows 95, so use UTF8FromUTF16() UTF8FromUTF16(uptr, ulen, putf, mlen); } delete []uptr; if (putf) { InsertPasteText(putf, mlen, selStart, isRectangular, isLine); delete []putf; } } else { InsertPasteText(ptr, len, selStart, isRectangular, isLine); } } memSelection.Unlock(); } } ::CloseClipboard(); Redraw(); } void ScintillaWin::CreateCallTipWindow(PRectangle) { if (!ct.wCallTip.Created()) { ct.wCallTip = ::CreateWindow(callClassName, TEXT("ACallTip"), WS_POPUP, 100, 100, 150, 20, MainHWND(), 0, GetWindowInstance(MainHWND()), this); ct.wDraw = ct.wCallTip; } } void ScintillaWin::AddToPopUp(const char *label, int cmd, bool enabled) { HMENU hmenuPopup = reinterpret_cast<HMENU>(popup.GetID()); if (!label[0]) ::AppendMenuA(hmenuPopup, MF_SEPARATOR, 0, ""); else if (enabled) ::AppendMenuA(hmenuPopup, MF_STRING, cmd, label); else ::AppendMenuA(hmenuPopup, MF_STRING | MF_DISABLED | MF_GRAYED, cmd, label); } void ScintillaWin::ClaimSelection() { // Windows does not have a primary selection } /// Implement IUnknown STDMETHODIMP_(ULONG)FormatEnumerator_AddRef(FormatEnumerator *fe); STDMETHODIMP FormatEnumerator_QueryInterface(FormatEnumerator *fe, REFIID riid, PVOID *ppv) { //Platform::DebugPrintf("EFE QI"); *ppv = NULL; if (riid == IID_IUnknown) *ppv = reinterpret_cast<IEnumFORMATETC *>(fe); if (riid == IID_IEnumFORMATETC) *ppv = reinterpret_cast<IEnumFORMATETC *>(fe); if (!*ppv) return E_NOINTERFACE; FormatEnumerator_AddRef(fe); return S_OK; } STDMETHODIMP_(ULONG)FormatEnumerator_AddRef(FormatEnumerator *fe) { return ++fe->ref; } STDMETHODIMP_(ULONG)FormatEnumerator_Release(FormatEnumerator *fe) { fe->ref--; if (fe->ref > 0) return fe->ref; delete fe; return 0; } /// Implement IEnumFORMATETC STDMETHODIMP FormatEnumerator_Next(FormatEnumerator *fe, ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched) { //Platform::DebugPrintf("EFE Next %d %d", fe->pos, celt); if (rgelt == NULL) return E_POINTER; // We only support one format, so this is simple. unsigned int putPos = 0; while ((fe->pos < fe->formatsLen) && (putPos < celt)) { rgelt->cfFormat = fe->formats[fe->pos]; rgelt->ptd = 0; rgelt->dwAspect = DVASPECT_CONTENT; rgelt->lindex = -1; rgelt->tymed = TYMED_HGLOBAL; fe->pos++; putPos++; } if (pceltFetched) *pceltFetched = putPos; return putPos ? S_OK : S_FALSE; } STDMETHODIMP FormatEnumerator_Skip(FormatEnumerator *fe, ULONG celt) { fe->pos += celt; return S_OK; } STDMETHODIMP FormatEnumerator_Reset(FormatEnumerator *fe) { fe->pos = 0; return S_OK; } STDMETHODIMP FormatEnumerator_Clone(FormatEnumerator *fe, IEnumFORMATETC **ppenum) { FormatEnumerator *pfe; try { pfe = new FormatEnumerator(fe->pos, fe->formats, fe->formatsLen); } catch (...) { return E_OUTOFMEMORY; } return FormatEnumerator_QueryInterface(pfe, IID_IEnumFORMATETC, reinterpret_cast<void **>(ppenum)); } static VFunction *vtFormatEnumerator[] = { (VFunction *)(FormatEnumerator_QueryInterface), (VFunction *)(FormatEnumerator_AddRef), (VFunction *)(FormatEnumerator_Release), (VFunction *)(FormatEnumerator_Next), (VFunction *)(FormatEnumerator_Skip), (VFunction *)(FormatEnumerator_Reset), (VFunction *)(FormatEnumerator_Clone) }; FormatEnumerator::FormatEnumerator(int pos_, CLIPFORMAT formats_[], int formatsLen_) { vtbl = vtFormatEnumerator; ref = 0; // First QI adds first reference... pos = pos_; formatsLen = formatsLen_; for (int i=0; i<formatsLen; i++) formats[i] = formats_[i]; } /// Implement IUnknown STDMETHODIMP DropSource_QueryInterface(DropSource *ds, REFIID riid, PVOID *ppv) { return ds->sci->QueryInterface(riid, ppv); } STDMETHODIMP_(ULONG)DropSource_AddRef(DropSource *ds) { return ds->sci->AddRef(); } STDMETHODIMP_(ULONG)DropSource_Release(DropSource *ds) { return ds->sci->Release(); } /// Implement IDropSource STDMETHODIMP DropSource_QueryContinueDrag(DropSource *, BOOL fEsc, DWORD grfKeyState) { if (fEsc) return DRAGDROP_S_CANCEL; if (!(grfKeyState & MK_LBUTTON)) return DRAGDROP_S_DROP; return S_OK; } STDMETHODIMP DropSource_GiveFeedback(DropSource *, DWORD) { return DRAGDROP_S_USEDEFAULTCURSORS; } static VFunction *vtDropSource[] = { (VFunction *)(DropSource_QueryInterface), (VFunction *)(DropSource_AddRef), (VFunction *)(DropSource_Release), (VFunction *)(DropSource_QueryContinueDrag), (VFunction *)(DropSource_GiveFeedback) }; DropSource::DropSource() { vtbl = vtDropSource; sci = 0; } /// Implement IUnkown STDMETHODIMP DataObject_QueryInterface(DataObject *pd, REFIID riid, PVOID *ppv) { //Platform::DebugPrintf("DO QI %x\n", pd); return pd->sci->QueryInterface(riid, ppv); } STDMETHODIMP_(ULONG)DataObject_AddRef(DataObject *pd) { return pd->sci->AddRef(); } STDMETHODIMP_(ULONG)DataObject_Release(DataObject *pd) { return pd->sci->Release(); } /// Implement IDataObject STDMETHODIMP DataObject_GetData(DataObject *pd, FORMATETC *pFEIn, STGMEDIUM *pSTM) { return pd->sci->GetData(pFEIn, pSTM); } STDMETHODIMP DataObject_GetDataHere(DataObject *, FORMATETC *, STGMEDIUM *) { //Platform::DebugPrintf("DOB GetDataHere\n"); return E_NOTIMPL; } STDMETHODIMP DataObject_QueryGetData(DataObject *pd, FORMATETC *pFE) { if (pd->sci->DragIsRectangularOK(pFE->cfFormat) && pFE->ptd == 0 && (pFE->dwAspect & DVASPECT_CONTENT) != 0 && pFE->lindex == -1 && (pFE->tymed & TYMED_HGLOBAL) != 0 ) { return S_OK; } bool formatOK = (pFE->cfFormat == CF_TEXT) || ((pFE->cfFormat == CF_UNICODETEXT) && pd->sci->IsUnicodeMode()); if (!formatOK || pFE->ptd != 0 || (pFE->dwAspect & DVASPECT_CONTENT) == 0 || pFE->lindex != -1 || (pFE->tymed & TYMED_HGLOBAL) == 0 ) { //Platform::DebugPrintf("DOB QueryGetData No %x\n",pFE->cfFormat); //return DATA_E_FORMATETC; return S_FALSE; } //Platform::DebugPrintf("DOB QueryGetData OK %x\n",pFE->cfFormat); return S_OK; } STDMETHODIMP DataObject_GetCanonicalFormatEtc(DataObject *pd, FORMATETC *, FORMATETC *pFEOut) { //Platform::DebugPrintf("DOB GetCanon\n"); if (pd->sci->IsUnicodeMode()) pFEOut->cfFormat = CF_UNICODETEXT; else pFEOut->cfFormat = CF_TEXT; pFEOut->ptd = 0; pFEOut->dwAspect = DVASPECT_CONTENT; pFEOut->lindex = -1; pFEOut->tymed = TYMED_HGLOBAL; return S_OK; } STDMETHODIMP DataObject_SetData(DataObject *, FORMATETC *, STGMEDIUM *, BOOL) { //Platform::DebugPrintf("DOB SetData\n"); return E_FAIL; } STDMETHODIMP DataObject_EnumFormatEtc(DataObject *pd, DWORD dwDirection, IEnumFORMATETC **ppEnum) { try { //Platform::DebugPrintf("DOB EnumFormatEtc %d\n", dwDirection); if (dwDirection != DATADIR_GET) { *ppEnum = 0; return E_FAIL; } FormatEnumerator *pfe; if (pd->sci->IsUnicodeMode()) { CLIPFORMAT formats[] = {CF_UNICODETEXT, CF_TEXT}; pfe = new FormatEnumerator(0, formats, 2); } else { CLIPFORMAT formats[] = {CF_TEXT}; pfe = new FormatEnumerator(0, formats, 1); } return FormatEnumerator_QueryInterface(pfe, IID_IEnumFORMATETC, reinterpret_cast<void **>(ppEnum)); } catch (std::bad_alloc &) { pd->sci->errorStatus = SC_STATUS_BADALLOC; return E_OUTOFMEMORY; } catch (...) { pd->sci->errorStatus = SC_STATUS_FAILURE; return E_FAIL; } } STDMETHODIMP DataObject_DAdvise(DataObject *, FORMATETC *, DWORD, IAdviseSink *, PDWORD) { //Platform::DebugPrintf("DOB DAdvise\n"); return E_FAIL; } STDMETHODIMP DataObject_DUnadvise(DataObject *, DWORD) { //Platform::DebugPrintf("DOB DUnadvise\n"); return E_FAIL; } STDMETHODIMP DataObject_EnumDAdvise(DataObject *, IEnumSTATDATA **) { //Platform::DebugPrintf("DOB EnumDAdvise\n"); return E_FAIL; } static VFunction *vtDataObject[] = { (VFunction *)(DataObject_QueryInterface), (VFunction *)(DataObject_AddRef), (VFunction *)(DataObject_Release), (VFunction *)(DataObject_GetData), (VFunction *)(DataObject_GetDataHere), (VFunction *)(DataObject_QueryGetData), (VFunction *)(DataObject_GetCanonicalFormatEtc), (VFunction *)(DataObject_SetData), (VFunction *)(DataObject_EnumFormatEtc), (VFunction *)(DataObject_DAdvise), (VFunction *)(DataObject_DUnadvise), (VFunction *)(DataObject_EnumDAdvise) }; DataObject::DataObject() { vtbl = vtDataObject; sci = 0; } /// Implement IUnknown STDMETHODIMP DropTarget_QueryInterface(DropTarget *dt, REFIID riid, PVOID *ppv) { //Platform::DebugPrintf("DT QI %x\n", dt); return dt->sci->QueryInterface(riid, ppv); } STDMETHODIMP_(ULONG)DropTarget_AddRef(DropTarget *dt) { return dt->sci->AddRef(); } STDMETHODIMP_(ULONG)DropTarget_Release(DropTarget *dt) { return dt->sci->Release(); } /// Implement IDropTarget by forwarding to Scintilla STDMETHODIMP DropTarget_DragEnter(DropTarget *dt, LPDATAOBJECT pIDataSource, DWORD grfKeyState, POINTL pt, PDWORD pdwEffect) { try { return dt->sci->DragEnter(pIDataSource, grfKeyState, pt, pdwEffect); } catch (...) { dt->sci->errorStatus = SC_STATUS_FAILURE; } return E_FAIL; } STDMETHODIMP DropTarget_DragOver(DropTarget *dt, DWORD grfKeyState, POINTL pt, PDWORD pdwEffect) { try { return dt->sci->DragOver(grfKeyState, pt, pdwEffect); } catch (...) { dt->sci->errorStatus = SC_STATUS_FAILURE; } return E_FAIL; } STDMETHODIMP DropTarget_DragLeave(DropTarget *dt) { try { return dt->sci->DragLeave(); } catch (...) { dt->sci->errorStatus = SC_STATUS_FAILURE; } return E_FAIL; } STDMETHODIMP DropTarget_Drop(DropTarget *dt, LPDATAOBJECT pIDataSource, DWORD grfKeyState, POINTL pt, PDWORD pdwEffect) { try { return dt->sci->Drop(pIDataSource, grfKeyState, pt, pdwEffect); } catch (...) { dt->sci->errorStatus = SC_STATUS_FAILURE; } return E_FAIL; } static VFunction *vtDropTarget[] = { (VFunction *)(DropTarget_QueryInterface), (VFunction *)(DropTarget_AddRef), (VFunction *)(DropTarget_Release), (VFunction *)(DropTarget_DragEnter), (VFunction *)(DropTarget_DragOver), (VFunction *)(DropTarget_DragLeave), (VFunction *)(DropTarget_Drop) }; DropTarget::DropTarget() { vtbl = vtDropTarget; sci = 0; } /** * DBCS: support Input Method Editor (IME). * Called when IME Window opened. */ void ScintillaWin::ImeStartComposition() { #ifndef __DMC__ // Digital Mars compiler does not include Imm library if (caret.active) { // Move IME Window to current caret position HIMC hIMC = ::ImmGetContext(MainHWND()); Point pos = PointMainCaret(); COMPOSITIONFORM CompForm; CompForm.dwStyle = CFS_POINT; CompForm.ptCurrentPos.x = pos.x; CompForm.ptCurrentPos.y = pos.y; ::ImmSetCompositionWindow(hIMC, &CompForm); // Set font of IME window to same as surrounded text. if (stylesValid) { // Since the style creation code has been made platform independent, // The logfont for the IME is recreated here. int styleHere = (pdoc->StyleAt(sel.MainCaret())) & 31; LOGFONTA lf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ""}; int sizeZoomed = vs.styles[styleHere].size + vs.zoomLevel * SC_FONT_SIZE_MULTIPLIER; if (sizeZoomed <= 2 * SC_FONT_SIZE_MULTIPLIER) // Hangs if sizeZoomed <= 1 sizeZoomed = 2 * SC_FONT_SIZE_MULTIPLIER; AutoSurface surface(this); int deviceHeight = sizeZoomed; if (surface) { deviceHeight = (sizeZoomed * surface->LogPixelsY()) / 72; } // The negative is to allow for leading lf.lfHeight = -(abs(deviceHeight / SC_FONT_SIZE_MULTIPLIER)); lf.lfWeight = vs.styles[styleHere].weight; lf.lfItalic = static_cast<BYTE>(vs.styles[styleHere].italic ? 1 : 0); lf.lfCharSet = DEFAULT_CHARSET; lf.lfFaceName[0] = '\0'; if (vs.styles[styleHere].fontName) strcpy(lf.lfFaceName, vs.styles[styleHere].fontName); ::ImmSetCompositionFontA(hIMC, &lf); } ::ImmReleaseContext(MainHWND(), hIMC); // Caret is displayed in IME window. So, caret in Scintilla is useless. DropCaret(); } #endif } /** Called when IME Window closed. */ void ScintillaWin::ImeEndComposition() { ShowCaretAtCurrentPosition(); } void ScintillaWin::AddCharBytes(char b0, char b1) { int inputCodePage = InputCodePage(); if (inputCodePage && IsUnicodeMode()) { char utfval[4] = "\0\0\0"; char ansiChars[3]; wchar_t wcs[2]; if (b0) { // Two bytes from IME ansiChars[0] = b0; ansiChars[1] = b1; ansiChars[2] = '\0'; ::MultiByteToWideChar(inputCodePage, 0, ansiChars, 2, wcs, 1); } else { ansiChars[0] = b1; ansiChars[1] = '\0'; ::MultiByteToWideChar(inputCodePage, 0, ansiChars, 1, wcs, 1); } unsigned int len = UTF8Length(wcs, 1); UTF8FromUTF16(wcs, 1, utfval, len); utfval[len] = '\0'; AddCharUTF(utfval, len ? len : 1); } else if (b0) { char dbcsChars[3]; dbcsChars[0] = b0; dbcsChars[1] = b1; dbcsChars[2] = '\0'; AddCharUTF(dbcsChars, 2, true); } else { AddChar(b1); } } void ScintillaWin::GetIntelliMouseParameters() { // This retrieves the number of lines per scroll as configured inthe Mouse Properties sheet in Control Panel ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &linesPerScroll, 0); } void ScintillaWin::CopyToClipboard(const SelectionText &selectedText) { if (!::OpenClipboard(MainHWND())) return; ::EmptyClipboard(); GlobalMemory uniText; // Default Scintilla behaviour in Unicode mode if (IsUnicodeMode()) { int uchars = UTF16Length(selectedText.s, selectedText.len); uniText.Allocate(2 * uchars); if (uniText) { UTF16FromUTF8(selectedText.s, selectedText.len, static_cast<wchar_t *>(uniText.ptr), uchars); } } else { // Not Unicode mode // Convert to Unicode using the current Scintilla code page UINT cpSrc = CodePageFromCharSet( selectedText.characterSet, selectedText.codePage); int uLen = ::MultiByteToWideChar(cpSrc, 0, selectedText.s, selectedText.len, 0, 0); uniText.Allocate(2 * uLen); if (uniText) { ::MultiByteToWideChar(cpSrc, 0, selectedText.s, selectedText.len, static_cast<wchar_t *>(uniText.ptr), uLen); } } if (uniText) { if (!IsNT()) { // Copy ANSI text to clipboard on Windows 9x // Convert from Unicode text, so other ANSI programs can // paste the text // Windows NT, 2k, XP automatically generates CF_TEXT GlobalMemory ansiText; ansiText.Allocate(selectedText.len); if (ansiText) { ::WideCharToMultiByte(CP_ACP, 0, static_cast<wchar_t *>(uniText.ptr), -1, static_cast<char *>(ansiText.ptr), selectedText.len, NULL, NULL); ansiText.SetClip(CF_TEXT); } } uniText.SetClip(CF_UNICODETEXT); } else { // There was a failure - try to copy at least ANSI text GlobalMemory ansiText; ansiText.Allocate(selectedText.len); if (ansiText) { memcpy(static_cast<char *>(ansiText.ptr), selectedText.s, selectedText.len); ansiText.SetClip(CF_TEXT); } } if (selectedText.rectangular) { ::SetClipboardData(cfColumnSelect, 0); } if (selectedText.lineCopy) { ::SetClipboardData(cfLineSelect, 0); } ::CloseClipboard(); } void ScintillaWin::ScrollMessage(WPARAM wParam) { //DWORD dwStart = timeGetTime(); //Platform::DebugPrintf("Scroll %x %d\n", wParam, lParam); SCROLLINFO sci; memset(&sci, 0, sizeof(sci)); sci.cbSize = sizeof(sci); sci.fMask = SIF_ALL; GetScrollInfo(SB_VERT, &sci); //Platform::DebugPrintf("ScrollInfo %d mask=%x min=%d max=%d page=%d pos=%d track=%d\n", b,sci.fMask, //sci.nMin, sci.nMax, sci.nPage, sci.nPos, sci.nTrackPos); int topLineNew = topLine; switch (LoWord(wParam)) { case SB_LINEUP: topLineNew -= 1; break; case SB_LINEDOWN: topLineNew += 1; break; case SB_PAGEUP: topLineNew -= LinesToScroll(); break; case SB_PAGEDOWN: topLineNew += LinesToScroll(); break; case SB_TOP: topLineNew = 0; break; case SB_BOTTOM: topLineNew = MaxScrollPos(); break; case SB_THUMBPOSITION: topLineNew = sci.nTrackPos; break; case SB_THUMBTRACK: topLineNew = sci.nTrackPos; break; } ScrollTo(topLineNew); } void ScintillaWin::HorizontalScrollMessage(WPARAM wParam) { int xPos = xOffset; PRectangle rcText = GetTextRectangle(); int pageWidth = rcText.Width() * 2 / 3; switch (LoWord(wParam)) { case SB_LINEUP: xPos -= 20; break; case SB_LINEDOWN: // May move past the logical end xPos += 20; break; case SB_PAGEUP: xPos -= pageWidth; break; case SB_PAGEDOWN: xPos += pageWidth; if (xPos > scrollWidth - rcText.Width()) { // Hit the end exactly xPos = scrollWidth - rcText.Width(); } break; case SB_TOP: xPos = 0; break; case SB_BOTTOM: xPos = scrollWidth; break; case SB_THUMBPOSITION: case SB_THUMBTRACK: { // Do NOT use wParam, its 16 bit and not enough for very long lines. Its still possible to overflow the 32 bit but you have to try harder =] SCROLLINFO si; si.cbSize = sizeof(si); si.fMask = SIF_TRACKPOS; if (GetScrollInfo(SB_HORZ, &si)) { xPos = si.nTrackPos; } } break; } HorizontalScrollTo(xPos); } /** * Redraw all of text area. * This paint will not be abandoned. */ void ScintillaWin::FullPaint() { if (technology == SC_TECHNOLOGY_DEFAULT) { HDC hdc = ::GetDC(MainHWND()); FullPaintDC(hdc); ::ReleaseDC(MainHWND(), hdc); } else { FullPaintDC(0); } } /** * Redraw all of text area on the specified DC. * This paint will not be abandoned. */ void ScintillaWin::FullPaintDC(HDC hdc) { paintState = painting; rcPaint = GetClientRectangle(); paintingAllText = true; if (technology == SC_TECHNOLOGY_DEFAULT) { AutoSurface surfaceWindow(hdc, this); if (surfaceWindow) { Paint(surfaceWindow, rcPaint); surfaceWindow->Release(); } } else { #if defined(USE_D2D) EnsureRenderTarget(); AutoSurface surfaceWindow(pRenderTarget, this); if (surfaceWindow) { pRenderTarget->BeginDraw(); Paint(surfaceWindow, rcPaint); surfaceWindow->Release(); HRESULT hr = pRenderTarget->EndDraw(); if (hr == D2DERR_RECREATE_TARGET) { DropRenderTarget(); } } #endif } paintState = notPainting; } static bool CompareDevCap(HDC hdc, HDC hOtherDC, int nIndex) { return ::GetDeviceCaps(hdc, nIndex) == ::GetDeviceCaps(hOtherDC, nIndex); } bool ScintillaWin::IsCompatibleDC(HDC hOtherDC) { HDC hdc = ::GetDC(MainHWND()); bool isCompatible = CompareDevCap(hdc, hOtherDC, TECHNOLOGY) && CompareDevCap(hdc, hOtherDC, LOGPIXELSY) && CompareDevCap(hdc, hOtherDC, LOGPIXELSX) && CompareDevCap(hdc, hOtherDC, BITSPIXEL) && CompareDevCap(hdc, hOtherDC, PLANES); ::ReleaseDC(MainHWND(), hdc); return isCompatible; } DWORD ScintillaWin::EffectFromState(DWORD grfKeyState) { // These are the Wordpad semantics. DWORD dwEffect; if (inDragDrop == ddDragging) // Internal defaults to move dwEffect = DROPEFFECT_MOVE; else dwEffect = DROPEFFECT_COPY; if (grfKeyState & MK_ALT) dwEffect = DROPEFFECT_MOVE; if (grfKeyState & MK_CONTROL) dwEffect = DROPEFFECT_COPY; return dwEffect; } /// Implement IUnknown STDMETHODIMP ScintillaWin::QueryInterface(REFIID riid, PVOID *ppv) { *ppv = NULL; if (riid == IID_IUnknown) *ppv = reinterpret_cast<IDropTarget *>(&dt); if (riid == IID_IDropSource) *ppv = reinterpret_cast<IDropSource *>(&ds); if (riid == IID_IDropTarget) *ppv = reinterpret_cast<IDropTarget *>(&dt); if (riid == IID_IDataObject) *ppv = reinterpret_cast<IDataObject *>(&dob); if (!*ppv) return E_NOINTERFACE; return S_OK; } STDMETHODIMP_(ULONG) ScintillaWin::AddRef() { return 1; } STDMETHODIMP_(ULONG) ScintillaWin::Release() { return 1; } /// Implement IDropTarget STDMETHODIMP ScintillaWin::DragEnter(LPDATAOBJECT pIDataSource, DWORD grfKeyState, POINTL, PDWORD pdwEffect) { if (pIDataSource == NULL) return E_POINTER; FORMATETC fmtu = {CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; HRESULT hrHasUText = pIDataSource->QueryGetData(&fmtu); hasOKText = (hrHasUText == S_OK); if (!hasOKText) { FORMATETC fmte = {CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; HRESULT hrHasText = pIDataSource->QueryGetData(&fmte); hasOKText = (hrHasText == S_OK); } if (!hasOKText) { *pdwEffect = DROPEFFECT_NONE; return S_OK; } *pdwEffect = EffectFromState(grfKeyState); return S_OK; } STDMETHODIMP ScintillaWin::DragOver(DWORD grfKeyState, POINTL pt, PDWORD pdwEffect) { try { if (!hasOKText || pdoc->IsReadOnly()) { *pdwEffect = DROPEFFECT_NONE; return S_OK; } *pdwEffect = EffectFromState(grfKeyState); // Update the cursor. POINT rpt = {pt.x, pt.y}; ::ScreenToClient(MainHWND(), &rpt); SetDragPosition(SPositionFromLocation(Point(rpt.x, rpt.y), false, false, UserVirtualSpace())); return S_OK; } catch (...) { errorStatus = SC_STATUS_FAILURE; } return E_FAIL; } STDMETHODIMP ScintillaWin::DragLeave() { try { SetDragPosition(SelectionPosition(invalidPosition)); return S_OK; } catch (...) { errorStatus = SC_STATUS_FAILURE; } return E_FAIL; } STDMETHODIMP ScintillaWin::Drop(LPDATAOBJECT pIDataSource, DWORD grfKeyState, POINTL pt, PDWORD pdwEffect) { try { *pdwEffect = EffectFromState(grfKeyState); if (pIDataSource == NULL) return E_POINTER; SetDragPosition(SelectionPosition(invalidPosition)); STGMEDIUM medium = {0, {0}, 0}; char *data = 0; bool dataAllocated = false; FORMATETC fmtu = {CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; HRESULT hr = pIDataSource->GetData(&fmtu, &medium); if (SUCCEEDED(hr) && medium.hGlobal) { wchar_t *udata = static_cast<wchar_t *>(::GlobalLock(medium.hGlobal)); if (udata) { if (IsUnicodeMode()) { int tlen = ::GlobalSize(medium.hGlobal); // Convert UTF-16 to UTF-8 int dataLen = UTF8Length(udata, tlen/2); data = new char[dataLen+1]; UTF8FromUTF16(udata, tlen/2, data, dataLen); dataAllocated = true; } else { // Convert UTF-16 to ANSI // // Default Scintilla behavior in Unicode mode // CF_UNICODETEXT available, but not in Unicode mode // Convert from Unicode to current Scintilla code page UINT cpDest = CodePageOfDocument(); int tlen = ::WideCharToMultiByte(cpDest, 0, udata, -1, NULL, 0, NULL, NULL) - 1; // subtract 0 terminator data = new char[tlen + 1]; memset(data, 0, (tlen+1)); ::WideCharToMultiByte(cpDest, 0, udata, -1, data, tlen + 1, NULL, NULL); dataAllocated = true; } } } if (!data) { FORMATETC fmte = {CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; hr = pIDataSource->GetData(&fmte, &medium); if (SUCCEEDED(hr) && medium.hGlobal) { data = static_cast<char *>(::GlobalLock(medium.hGlobal)); } } if (data && convertPastes) { // Convert line endings of the drop into our local line-endings mode int len = static_cast<int>(strlen(data)); char *convertedText = Document::TransformLineEnds(&len, data, len, pdoc->eolMode); if (dataAllocated) delete []data; data = convertedText; dataAllocated = true; } if (!data) { //Platform::DebugPrintf("Bad data format: 0x%x\n", hres); return hr; } FORMATETC fmtr = {cfColumnSelect, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; HRESULT hrRectangular = pIDataSource->QueryGetData(&fmtr); POINT rpt = {pt.x, pt.y}; ::ScreenToClient(MainHWND(), &rpt); SelectionPosition movePos = SPositionFromLocation(Point(rpt.x, rpt.y), false, false, UserVirtualSpace()); DropAt(movePos, data, *pdwEffect == DROPEFFECT_MOVE, hrRectangular == S_OK); ::GlobalUnlock(medium.hGlobal); // Free data if (medium.pUnkForRelease != NULL) medium.pUnkForRelease->Release(); else ::GlobalFree(medium.hGlobal); if (dataAllocated) delete []data; return S_OK; } catch (...) { errorStatus = SC_STATUS_FAILURE; } return E_FAIL; } /// Implement important part of IDataObject STDMETHODIMP ScintillaWin::GetData(FORMATETC *pFEIn, STGMEDIUM *pSTM) { bool formatOK = (pFEIn->cfFormat == CF_TEXT) || ((pFEIn->cfFormat == CF_UNICODETEXT) && IsUnicodeMode()); if (!formatOK || pFEIn->ptd != 0 || (pFEIn->dwAspect & DVASPECT_CONTENT) == 0 || pFEIn->lindex != -1 || (pFEIn->tymed & TYMED_HGLOBAL) == 0 ) { //Platform::DebugPrintf("DOB GetData No %d %x %x fmt=%x\n", lenDrag, pFEIn, pSTM, pFEIn->cfFormat); return DATA_E_FORMATETC; } pSTM->tymed = TYMED_HGLOBAL; //Platform::DebugPrintf("DOB GetData OK %d %x %x\n", lenDrag, pFEIn, pSTM); GlobalMemory text; if (pFEIn->cfFormat == CF_UNICODETEXT) { int uchars = UTF16Length(drag.s, drag.len); text.Allocate(2 * uchars); if (text) { UTF16FromUTF8(drag.s, drag.len, static_cast<wchar_t *>(text.ptr), uchars); } } else { text.Allocate(drag.len); if (text) { memcpy(static_cast<char *>(text.ptr), drag.s, drag.len); } } pSTM->hGlobal = text ? text.Unlock() : 0; pSTM->pUnkForRelease = 0; return S_OK; } bool ScintillaWin::Register(HINSTANCE hInstance_) { hInstance = hInstance_; bool result; // Register the Scintilla class if (IsNT()) { // Register Scintilla as a wide character window WNDCLASSEXW wndclass; wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = ScintillaWin::SWndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = sizeof(ScintillaWin *); wndclass.hInstance = hInstance; wndclass.hIcon = NULL; wndclass.hCursor = NULL; wndclass.hbrBackground = NULL; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = L"Scintilla"; wndclass.hIconSm = 0; result = ::RegisterClassExW(&wndclass) != 0; } else { // Register Scintilla as a normal character window WNDCLASSEX wndclass; wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = ScintillaWin::SWndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = sizeof(ScintillaWin *); wndclass.hInstance = hInstance; wndclass.hIcon = NULL; wndclass.hCursor = NULL; wndclass.hbrBackground = NULL; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = scintillaClassName; wndclass.hIconSm = 0; result = ::RegisterClassEx(&wndclass) != 0; } if (result) { // Register the CallTip class WNDCLASSEX wndclassc; wndclassc.cbSize = sizeof(wndclassc); wndclassc.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW; wndclassc.cbClsExtra = 0; wndclassc.cbWndExtra = sizeof(ScintillaWin *); wndclassc.hInstance = hInstance; wndclassc.hIcon = NULL; wndclassc.hbrBackground = NULL; wndclassc.lpszMenuName = NULL; wndclassc.lpfnWndProc = ScintillaWin::CTWndProc; wndclassc.hCursor = ::LoadCursor(NULL, IDC_ARROW); wndclassc.lpszClassName = callClassName; wndclassc.hIconSm = 0; result = ::RegisterClassEx(&wndclassc) != 0; } return result; } bool ScintillaWin::Unregister() { bool result = ::UnregisterClass(scintillaClassName, hInstance) != 0; if (::UnregisterClass(callClassName, hInstance) == 0) result = false; return result; } bool ScintillaWin::HasCaretSizeChanged() { if ( ( (0 != vs.caretWidth) && (sysCaretWidth != vs.caretWidth) ) || ((0 != vs.lineHeight) && (sysCaretHeight != vs.lineHeight)) ) { return true; } return false; } BOOL ScintillaWin::CreateSystemCaret() { sysCaretWidth = vs.caretWidth; if (0 == sysCaretWidth) { sysCaretWidth = 1; } sysCaretHeight = vs.lineHeight; int bitmapSize = (((sysCaretWidth + 15) & ~15) >> 3) * sysCaretHeight; char *bits = new char[bitmapSize]; memset(bits, 0, bitmapSize); sysCaretBitmap = ::CreateBitmap(sysCaretWidth, sysCaretHeight, 1, 1, reinterpret_cast<BYTE *>(bits)); delete []bits; BOOL retval = ::CreateCaret( MainHWND(), sysCaretBitmap, sysCaretWidth, sysCaretHeight); ::ShowCaret(MainHWND()); return retval; } BOOL ScintillaWin::DestroySystemCaret() { ::HideCaret(MainHWND()); BOOL retval = ::DestroyCaret(); if (sysCaretBitmap) { ::DeleteObject(sysCaretBitmap); sysCaretBitmap = 0; } return retval; } sptr_t PASCAL ScintillaWin::CTWndProc( HWND hWnd, UINT iMessage, WPARAM wParam, sptr_t lParam) { // Find C++ object associated with window. ScintillaWin *sciThis = reinterpret_cast<ScintillaWin *>(PointerFromWindow(hWnd)); try { // ctp will be zero if WM_CREATE not seen yet if (sciThis == 0) { if (iMessage == WM_CREATE) { // Associate CallTip object with window CREATESTRUCT *pCreate = reinterpret_cast<CREATESTRUCT *>(lParam); SetWindowPointer(hWnd, pCreate->lpCreateParams); return 0; } else { return ::DefWindowProc(hWnd, iMessage, wParam, lParam); } } else { if (iMessage == WM_NCDESTROY) { ::SetWindowLong(hWnd, 0, 0); return ::DefWindowProc(hWnd, iMessage, wParam, lParam); } else if (iMessage == WM_PAINT) { PAINTSTRUCT ps; ::BeginPaint(hWnd, &ps); Surface *surfaceWindow = Surface::Allocate(sciThis->technology); if (surfaceWindow) { #if defined(USE_D2D) ID2D1HwndRenderTarget *pCTRenderTarget = 0; #endif RECT rc; GetClientRect(hWnd, &rc); // Create a Direct2D render target. if (sciThis->technology == SC_TECHNOLOGY_DEFAULT) { surfaceWindow->Init(ps.hdc, hWnd); } else { #if defined(USE_D2D) pD2DFactory->CreateHwndRenderTarget( D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, D2D1::PixelFormat(), 96.0, 96.0), D2D1::HwndRenderTargetProperties(hWnd, D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top)), &pCTRenderTarget); surfaceWindow->Init(pCTRenderTarget, hWnd); pCTRenderTarget->BeginDraw(); #endif } surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == sciThis->ct.codePage); surfaceWindow->SetDBCSMode(sciThis->ct.codePage); sciThis->ct.PaintCT(surfaceWindow); #if defined(USE_D2D) if (pCTRenderTarget) pCTRenderTarget->EndDraw(); #endif surfaceWindow->Release(); delete surfaceWindow; #if defined(USE_D2D) if (pCTRenderTarget) pCTRenderTarget->Release(); #endif } ::EndPaint(hWnd, &ps); return 0; } else if ((iMessage == WM_NCLBUTTONDOWN) || (iMessage == WM_NCLBUTTONDBLCLK)) { POINT pt; pt.x = static_cast<short>(LOWORD(lParam)); pt.y = static_cast<short>(HIWORD(lParam)); ScreenToClient(hWnd, &pt); sciThis->ct.MouseClick(Point(pt.x, pt.y)); sciThis->CallTipClick(); return 0; } else if (iMessage == WM_LBUTTONDOWN) { // This does not fire due to the hit test code sciThis->ct.MouseClick(Point::FromLong(lParam)); sciThis->CallTipClick(); return 0; } else if (iMessage == WM_SETCURSOR) { ::SetCursor(::LoadCursor(NULL, IDC_ARROW)); return 0; } else if (iMessage == WM_NCHITTEST) { return HTCAPTION; } else { return ::DefWindowProc(hWnd, iMessage, wParam, lParam); } } } catch (...) { sciThis->errorStatus = SC_STATUS_FAILURE; } return ::DefWindowProc(hWnd, iMessage, wParam, lParam); } sptr_t ScintillaWin::DirectFunction( ScintillaWin *sci, UINT iMessage, uptr_t wParam, sptr_t lParam) { PLATFORM_ASSERT(::GetCurrentThreadId() == ::GetWindowThreadProcessId(sci->MainHWND(), NULL)); return sci->WndProc(iMessage, wParam, lParam); } extern "C" #ifndef STATIC_BUILD __declspec(dllexport) #endif sptr_t __stdcall Scintilla_DirectFunction( ScintillaWin *sci, UINT iMessage, uptr_t wParam, sptr_t lParam) { return sci->WndProc(iMessage, wParam, lParam); } sptr_t PASCAL ScintillaWin::SWndProc( HWND hWnd, UINT iMessage, WPARAM wParam, sptr_t lParam) { //Platform::DebugPrintf("S W:%x M:%x WP:%x L:%x\n", hWnd, iMessage, wParam, lParam); // Find C++ object associated with window. ScintillaWin *sci = reinterpret_cast<ScintillaWin *>(PointerFromWindow(hWnd)); // sci will be zero if WM_CREATE not seen yet if (sci == 0) { try { if (iMessage == WM_CREATE) { // Create C++ object associated with window sci = new ScintillaWin(hWnd); SetWindowPointer(hWnd, sci); return sci->WndProc(iMessage, wParam, lParam); } } catch (...) { } return ::DefWindowProc(hWnd, iMessage, wParam, lParam); } else { if (iMessage == WM_NCDESTROY) { try { sci->Finalise(); delete sci; } catch (...) { } ::SetWindowLong(hWnd, 0, 0); return ::DefWindowProc(hWnd, iMessage, wParam, lParam); } else { return sci->WndProc(iMessage, wParam, lParam); } } } // This function is externally visible so it can be called from container when building statically. // Must be called once only. int Scintilla_RegisterClasses(void *hInstance) { Platform_Initialise(hInstance); bool result = ScintillaWin::Register(reinterpret_cast<HINSTANCE>(hInstance)); #ifdef SCI_LEXER Scintilla_LinkLexers(); #endif return result; } // This function is externally visible so it can be called from container when building statically. int Scintilla_ReleaseResources() { bool result = ScintillaWin::Unregister(); Platform_Finalise(); return result; } #ifndef STATIC_BUILD extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID) { //Platform::DebugPrintf("Scintilla::DllMain %d %d\n", hInstance, dwReason); if (dwReason == DLL_PROCESS_ATTACH) { if (!Scintilla_RegisterClasses(hInstance)) return FALSE; } else if (dwReason == DLL_PROCESS_DETACH) { Scintilla_ReleaseResources(); } return TRUE; } #endif |
Added win32/deps.mak.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 |
PlatWin.o: PlatWin.cxx ../include/Platform.h \ ../src/UniConversion.h ../src/XPM.h ../src/FontQuality.h ScintillaWin.o: ScintillaWin.cxx ../include/Platform.h \ ../include/ILexer.h ../include/Scintilla.h ../src/SplitVector.h \ ../src/Partitioning.h ../src/RunStyles.h ../src/ContractionState.h \ ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h ../src/Indicator.h \ ../src/XPM.h ../src/LineMarker.h ../src/Style.h ../src/AutoComplete.h \ ../src/ViewStyle.h ../src/CharClassify.h ../src/Decoration.h \ ../src/Document.h ../src/Selection.h ../src/PositionCache.h \ ../src/Editor.h ../src/ScintillaBase.h ../src/UniConversion.h AutoComplete.o: ../src/AutoComplete.cxx ../include/Platform.h \ ../lexlib/CharacterSet.h ../src/AutoComplete.h CallTip.o: ../src/CallTip.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/CallTip.h Catalogue.o: ../src/Catalogue.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h ../src/Catalogue.h CellBuffer.o: ../src/CellBuffer.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/CellBuffer.h CharClassify.o: ../src/CharClassify.cxx ../src/CharClassify.h ContractionState.o: ../src/ContractionState.cxx ../include/Platform.h \ ../src/SplitVector.h ../src/Partitioning.h ../src/RunStyles.h \ ../src/ContractionState.h Decoration.o: ../src/Decoration.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/Decoration.h Document.o: ../src/Document.cxx ../include/Platform.h ../include/ILexer.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/CellBuffer.h ../src/PerLine.h \ ../src/CharClassify.h ../lexlib/CharacterSet.h ../src/Decoration.h \ ../src/Document.h ../src/RESearch.h ../src/UniConversion.h Editor.o: ../src/Editor.cxx ../include/Platform.h ../include/ILexer.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/ContractionState.h ../src/CellBuffer.h \ ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ ../src/Style.h ../src/ViewStyle.h ../src/CharClassify.h \ ../src/Decoration.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../src/Document.h ../src/Selection.h ../src/PositionCache.h \ ../src/Editor.h ExternalLexer.o: ../src/ExternalLexer.cxx ../include/Platform.h \ ../include/ILexer.h ../include/Scintilla.h ../include/SciLexer.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/WordList.h \ ../lexlib/LexerModule.h ../src/Catalogue.h ../src/ExternalLexer.h Indicator.o: ../src/Indicator.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/Indicator.h KeyMap.o: ../src/KeyMap.cxx ../include/Platform.h ../include/Scintilla.h \ ../src/KeyMap.h LineMarker.o: ../src/LineMarker.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/XPM.h ../src/LineMarker.h PerLine.o: ../src/PerLine.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/CellBuffer.h ../src/PerLine.h PositionCache.o: ../src/PositionCache.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/ContractionState.h ../src/CellBuffer.h \ ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ ../src/Style.h ../src/ViewStyle.h ../src/CharClassify.h \ ../src/Decoration.h ../include/ILexer.h ../src/Document.h \ ../src/Selection.h ../src/PositionCache.h RESearch.o: ../src/RESearch.cxx ../src/CharClassify.h ../src/RESearch.h RunStyles.o: ../src/RunStyles.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ScintillaBase.o: ../src/ScintillaBase.cxx ../include/Platform.h \ ../include/ILexer.h ../include/Scintilla.h ../lexlib/PropSetSimple.h \ ../src/SplitVector.h ../src/Partitioning.h ../src/RunStyles.h \ ../src/ContractionState.h ../src/CellBuffer.h ../src/CallTip.h \ ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ ../src/Style.h ../src/ViewStyle.h ../src/AutoComplete.h \ ../src/CharClassify.h ../src/Decoration.h ../src/Document.h \ ../src/Selection.h ../src/PositionCache.h ../src/Editor.h \ ../src/ScintillaBase.h Selection.o: ../src/Selection.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/Selection.h Style.o: ../src/Style.cxx ../include/Platform.h ../include/Scintilla.h \ ../src/Style.h UniConversion.o: ../src/UniConversion.cxx ../src/UniConversion.h ViewStyle.o: ../src/ViewStyle.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ ../src/Style.h ../src/ViewStyle.h XPM.o: ../src/XPM.cxx ../include/Platform.h ../src/XPM.h Accessor.o: ../lexlib/Accessor.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h CharacterSet.o: ../lexlib/CharacterSet.cxx ../lexlib/CharacterSet.h LexerBase.o: ../lexlib/LexerBase.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/LexerModule.h ../lexlib/LexerBase.h LexerModule.o: ../lexlib/LexerModule.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/LexerModule.h ../lexlib/LexerBase.h ../lexlib/LexerSimple.h LexerSimple.o: ../lexlib/LexerSimple.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/LexerModule.h ../lexlib/LexerBase.h ../lexlib/LexerSimple.h PropSetSimple.o: ../lexlib/PropSetSimple.cxx ../lexlib/PropSetSimple.h StyleContext.o: ../lexlib/StyleContext.cxx ../include/ILexer.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h WordList.o: ../lexlib/WordList.cxx ../lexlib/WordList.h LexAbaqus.o: ../lexers/LexAbaqus.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexAda.o: ../lexers/LexAda.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexAPDL.o: ../lexers/LexAPDL.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexAsm.o: ../lexers/LexAsm.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexAsn1.o: ../lexers/LexAsn1.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexASY.o: ../lexers/LexASY.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexAU3.o: ../lexers/LexAU3.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexAVE.o: ../lexers/LexAVE.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexBaan.o: ../lexers/LexBaan.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexBash.o: ../lexers/LexBash.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexBasic.o: ../lexers/LexBasic.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexBullant.o: ../lexers/LexBullant.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexCaml.o: ../lexers/LexCaml.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexCLW.o: ../lexers/LexCLW.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexCmake.o: ../lexers/LexCmake.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexCOBOL.o: ../lexers/LexCOBOL.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexConf.o: ../lexers/LexConf.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexCPP.o: ../lexers/LexCPP.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexCrontab.o: ../lexers/LexCrontab.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexCsound.o: ../lexers/LexCsound.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexCSS.o: ../lexers/LexCSS.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexD.o: ../lexers/LexD.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexEiffel.o: ../lexers/LexEiffel.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexErlang.o: ../lexers/LexErlang.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexEScript.o: ../lexers/LexEScript.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexFlagship.o: ../lexers/LexFlagship.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexForth.o: ../lexers/LexForth.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexFortran.o: ../lexers/LexFortran.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexGAP.o: ../lexers/LexGAP.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexGui4Cli.o: ../lexers/LexGui4Cli.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexHaskell.o: ../lexers/LexHaskell.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexHTML.o: ../lexers/LexHTML.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexInno.o: ../lexers/LexInno.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexKix.o: ../lexers/LexKix.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexLisp.o: ../lexers/LexLisp.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexLout.o: ../lexers/LexLout.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexLua.o: ../lexers/LexLua.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexMagik.o: ../lexers/LexMagik.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexMarkdown.o: ../lexers/LexMarkdown.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexMatlab.o: ../lexers/LexMatlab.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexMetapost.o: ../lexers/LexMetapost.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexMMIXAL.o: ../lexers/LexMMIXAL.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexMPT.o: ../lexers/LexMPT.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexMSSQL.o: ../lexers/LexMSSQL.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexMySQL.o: ../lexers/LexMySQL.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexNimrod.o: ../lexers/LexNimrod.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexNsis.o: ../lexers/LexNsis.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexOpal.o: ../lexers/LexOpal.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexOthers.o: ../lexers/LexOthers.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexPascal.o: ../lexers/LexPascal.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexPB.o: ../lexers/LexPB.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexPerl.o: ../lexers/LexPerl.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexPLM.o: ../lexers/LexPLM.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexPOV.o: ../lexers/LexPOV.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexPowerPro.o: ../lexers/LexPowerPro.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexPowerShell.o: ../lexers/LexPowerShell.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexProgress.o: ../lexers/LexProgress.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexPS.o: ../lexers/LexPS.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexPython.o: ../lexers/LexPython.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h ../lexlib/LexerBase.h LexR.o: ../lexers/LexR.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexRebol.o: ../lexers/LexRebol.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexRuby.o: ../lexers/LexRuby.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexScriptol.o: ../lexers/LexScriptol.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexSmalltalk.o: ../lexers/LexSmalltalk.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexSML.o: ../lexers/LexSML.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexSorcus.o: ../lexers/LexSorcus.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexSpecman.o: ../lexers/LexSpecman.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexSpice.o: ../lexers/LexSpice.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexSQL.o: ../lexers/LexSQL.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexTACL.o: ../lexers/LexTACL.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexTADS3.o: ../lexers/LexTADS3.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexTAL.o: ../lexers/LexTAL.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexTCL.o: ../lexers/LexTCL.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexTeX.o: ../lexers/LexTeX.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexVB.o: ../lexers/LexVB.cxx ../include/ILexer.h ../include/Scintilla.h \ ../include/SciLexer.h ../lexlib/PropSetSimple.h ../lexlib/WordList.h \ ../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h ../lexlib/LexerModule.h LexVerilog.o: ../lexers/LexVerilog.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexVHDL.o: ../lexers/LexVHDL.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h LexYAML.o: ../lexers/LexYAML.cxx ../include/ILexer.h \ ../include/Scintilla.h ../include/SciLexer.h ../lexlib/PropSetSimple.h \ ../lexlib/WordList.h ../lexlib/LexAccessor.h ../lexlib/Accessor.h \ ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h |
Added win32/makefile.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# Make file for Scintilla on Windows # Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> # The License.txt file describes the conditions under which this software may be distributed. # This makefile assumes the mingw32 version of GCC 3.x or 4.x is used and changes will # be needed to use other compilers. .SUFFIXES: .cxx CC = g++ DEL = del /q COMPONENT = ../bin/Scintilla.dll LEXCOMPONENT = ../bin/SciLexer.dll LEXLIB = Lexers.a vpath %.h ../src ../include ../lexlib vpath %.cxx ../src ../lexlib ../lexers LDFLAGS=-shared -static -Wl,--enable-runtime-pseudo-reloc-v2 -mwindows -Wl,--add-stdcall-alias LIBS=-lstdc++ -limm32 -lole32 -luuid # Add -MMD to get dependencies INCLUDEDIRS=-I ../include -I ../src -I../lexlib CXXBASEFLAGS=-Wall -Wno-missing-braces -Wno-char-subscripts -pedantic $(INCLUDEDIRS) -fno-rtti ifdef DEBUG CXXFLAGS=-DDEBUG -g $(CXXBASEFLAGS) else CXXFLAGS=-DNDEBUG -Os $(CXXBASEFLAGS) STRIPFLAG=-s endif .cxx.o: $(CC) $(CXXFLAGS) -c $< ALL: $(COMPONENT) $(LEXCOMPONENT) $(LEXLIB) ScintillaWinS.o clean: $(DEL) *.exe *.o *.obj *.dll *.res *.map deps: $(CC) -MM $(CXXFLAGS) *.cxx ../src/*.cxx ../lexlib/*.cxx ../lexers/*.cxx >deps.mak LEXOBJS:=$(addsuffix .o,$(basename $(notdir $(wildcard ../lexers/Lex*.cxx)))) BASEOBJS = \ AutoComplete.o \ CallTip.o \ CellBuffer.o \ CharacterSet.o \ CharClassify.o \ ContractionState.o \ Decoration.o \ Document.o \ Editor.o \ KeyMap.o \ Indicator.o \ LineMarker.o \ PerLine.o \ PlatWin.o \ PositionCache.o \ PropSetSimple.o \ RESearch.o \ RunStyles.o \ ScintRes.o \ Selection.o \ Style.o \ UniConversion.o \ ViewStyle.o \ XPM.o SOBJS = ScintillaWin.o ScintillaBase.o $(BASEOBJS) $(COMPONENT): $(SOBJS) Scintilla.def $(CC) $(LDFLAGS) -o $@ $(STRIPFLAG) $(SOBJS) $(CXXFLAGS) $(LIBS) LOBJS = \ Accessor.o \ Catalogue.o \ ExternalLexer.o \ LexerBase.o \ LexerModule.o \ LexerSimple.o \ ScintillaWinL.o \ ScintillaBaseL.o \ StyleContext.o \ WordList.o \ $(BASEOBJS) \ $(LEXOBJS) $(LEXCOMPONENT): $(LOBJS) Scintilla.def $(CC) $(LDFLAGS) -o $@ $(STRIPFLAG) $(LOBJS) $(CXXFLAGS) $(LIBS) $(LEXLIB): $(LEXOBJS) $(AR) rc $@ $^ ranlib $@ # Automatically generate dependencies for most files with "make deps" include deps.mak # These dependencies are maintained by hand as they do not use the default output name ScintillaBaseL.o: ScintillaBase.cxx Platform.h \ ILexer.h Scintilla.h SciLexer.h PropSetSimple.h \ SplitVector.h Partitioning.h RunStyles.h \ ContractionState.h CellBuffer.h CallTip.h \ KeyMap.h Indicator.h XPM.h LineMarker.h \ Style.h ViewStyle.h AutoComplete.h \ CharClassify.h Decoration.h Document.h \ Selection.h PositionCache.h Editor.h \ ScintillaBase.h LexAccessor.h Accessor.h \ LexerModule.h Catalogue.h ScintillaWinL.o: ScintillaWin.cxx Platform.h \ ILexer.h Scintilla.h SplitVector.h \ Partitioning.h RunStyles.h ContractionState.h \ CellBuffer.h CallTip.h KeyMap.h Indicator.h \ XPM.h LineMarker.h Style.h AutoComplete.h \ ViewStyle.h CharClassify.h Decoration.h \ Document.h Selection.h PositionCache.h \ Editor.h ScintillaBase.h UniConversion.h \ LexAccessor.h Accessor.h \ LexerModule.h Catalogue.h ScintillaWinS.o: ScintillaWin.cxx Platform.h \ ILexer.h Scintilla.h SplitVector.h \ Partitioning.h RunStyles.h ContractionState.h \ CellBuffer.h CallTip.h KeyMap.h Indicator.h \ XPM.h LineMarker.h Style.h AutoComplete.h \ ViewStyle.h CharClassify.h Decoration.h \ Document.h Selection.h PositionCache.h \ Editor.h ScintillaBase.h UniConversion.h ScintillaBaseL.o: $(CC) $(CXXFLAGS) -D SCI_LEXER -c $< -o $@ ScintillaWinS.o: $(CC) $(CXXFLAGS) -D STATIC_BUILD -c $< -o $@ ScintillaWinL.o: $(CC) $(CXXFLAGS) -D SCI_LEXER -c $< -o $@ ScintRes.o: ScintRes.rc windres ScintRes.rc $@ |
Added win32/scintilla.mak.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 |
# Make file for Scintilla on Windows Visual C++ version # Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> # The License.txt file describes the conditions under which this software may be distributed. # This makefile is for using Visual C++ with nmake. # Usage for Microsoft: # nmake -f scintilla.mak # For debug versions define DEBUG on the command line: # nmake DEBUG=1 -f scintilla.mak # The main makefile uses mingw32 gcc and may be more current than this file. .SUFFIXES: .cxx DIR_O=. DIR_BIN=..\bin COMPONENT=$(DIR_BIN)\Scintilla.dll LEXCOMPONENT=$(DIR_BIN)\SciLexer.dll LEXLIB=Lexers.lib CC=cl RC=rc LD=link CXXFLAGS=-Zi -TP -MP -W4 -EHsc -Zc:forScope -Zc:wchar_t -D_CRT_SECURE_NO_DEPRECATE=1 CXXDEBUG=-Od -MTd -DDEBUG CXXNDEBUG=-O1 -MT -DNDEBUG -GL NAME=-Fo LDFLAGS=-OPT:REF -LTCG -DEBUG LDDEBUG= LIBS=KERNEL32.lib USER32.lib GDI32.lib IMM32.lib OLE32.LIB NOLOGO=-nologo !IFDEF QUIET CC=@$(CC) CXXFLAGS=$(CXXFLAGS) $(NOLOGO) LDFLAGS=$(LDFLAGS) $(NOLOGO) !ENDIF !IF [cl -c -nologo CheckD2D.cxx >NUL:] CXXFLAGS=$(CXXFLAGS) -DDISABLE_D2D !MESSAGE Direct2D is not available !ENDIF !IFDEF DEBUG CXXFLAGS=$(CXXFLAGS) $(CXXDEBUG) LDFLAGS=$(LDDEBUG) $(LDFLAGS) !ELSE CXXFLAGS=$(CXXFLAGS) $(CXXNDEBUG) !ENDIF INCLUDEDIRS=-I../include -I../src -I../lexlib CXXFLAGS=$(CXXFLAGS) $(INCLUDEDIRS) ALL: $(COMPONENT) $(LEXCOMPONENT) $(LEXLIB) $(DIR_O)\ScintillaWinS.obj clean: -del /q $(DIR_O)\*.obj $(DIR_O)\*.pdb $(COMPONENT) $(LEXCOMPONENT) \ $(DIR_O)\*.res $(DIR_BIN)\*.map $(DIR_BIN)\*.exp $(DIR_BIN)\*.pdb $(DIR_BIN)\*.lib SOBJS=\ $(DIR_O)\AutoComplete.obj \ $(DIR_O)\CallTip.obj \ $(DIR_O)\CellBuffer.obj \ $(DIR_O)\CharacterSet.obj \ $(DIR_O)\CharClassify.obj \ $(DIR_O)\ContractionState.obj \ $(DIR_O)\Decoration.obj \ $(DIR_O)\Document.obj \ $(DIR_O)\Editor.obj \ $(DIR_O)\Indicator.obj \ $(DIR_O)\KeyMap.obj \ $(DIR_O)\LineMarker.obj \ $(DIR_O)\PerLine.obj \ $(DIR_O)\PlatWin.obj \ $(DIR_O)\PositionCache.obj \ $(DIR_O)\PropSetSimple.obj \ $(DIR_O)\RESearch.obj \ $(DIR_O)\RunStyles.obj \ $(DIR_O)\ScintillaBase.obj \ $(DIR_O)\ScintillaWin.obj \ $(DIR_O)\Selection.obj \ $(DIR_O)\Style.obj \ $(DIR_O)\UniConversion.obj \ $(DIR_O)\ViewStyle.obj \ $(DIR_O)\XPM.obj #++Autogenerated -- run src/LexGen.py to regenerate #**LEXOBJS=\\\n\(\t$(DIR_O)\\\*.obj \\\n\) LEXOBJS=\ $(DIR_O)\LexA68k.obj \ $(DIR_O)\LexAbaqus.obj \ $(DIR_O)\LexAda.obj \ $(DIR_O)\LexAPDL.obj \ $(DIR_O)\LexAsm.obj \ $(DIR_O)\LexAsn1.obj \ $(DIR_O)\LexASY.obj \ $(DIR_O)\LexAU3.obj \ $(DIR_O)\LexAVE.obj \ $(DIR_O)\LexAVS.obj \ $(DIR_O)\LexBaan.obj \ $(DIR_O)\LexBash.obj \ $(DIR_O)\LexBasic.obj \ $(DIR_O)\LexBullant.obj \ $(DIR_O)\LexCaml.obj \ $(DIR_O)\LexCLW.obj \ $(DIR_O)\LexCmake.obj \ $(DIR_O)\LexCOBOL.obj \ $(DIR_O)\LexCoffeeScript.obj \ $(DIR_O)\LexConf.obj \ $(DIR_O)\LexCPP.obj \ $(DIR_O)\LexCrontab.obj \ $(DIR_O)\LexCsound.obj \ $(DIR_O)\LexCSS.obj \ $(DIR_O)\LexD.obj \ $(DIR_O)\LexECL.obj \ $(DIR_O)\LexEiffel.obj \ $(DIR_O)\LexErlang.obj \ $(DIR_O)\LexEScript.obj \ $(DIR_O)\LexFlagship.obj \ $(DIR_O)\LexForth.obj \ $(DIR_O)\LexFortran.obj \ $(DIR_O)\LexGAP.obj \ $(DIR_O)\LexGui4Cli.obj \ $(DIR_O)\LexHaskell.obj \ $(DIR_O)\LexHTML.obj \ $(DIR_O)\LexInno.obj \ $(DIR_O)\LexKix.obj \ $(DIR_O)\LexLaTeX.obj \ $(DIR_O)\LexLisp.obj \ $(DIR_O)\LexLout.obj \ $(DIR_O)\LexLua.obj \ $(DIR_O)\LexMagik.obj \ $(DIR_O)\LexMarkdown.obj \ $(DIR_O)\LexMatlab.obj \ $(DIR_O)\LexMetapost.obj \ $(DIR_O)\LexMMIXAL.obj \ $(DIR_O)\LexModula.obj \ $(DIR_O)\LexMPT.obj \ $(DIR_O)\LexMSSQL.obj \ $(DIR_O)\LexMySQL.obj \ $(DIR_O)\LexNimrod.obj \ $(DIR_O)\LexNsis.obj \ $(DIR_O)\LexOpal.obj \ $(DIR_O)\LexOScript.obj \ $(DIR_O)\LexOthers.obj \ $(DIR_O)\LexPascal.obj \ $(DIR_O)\LexPB.obj \ $(DIR_O)\LexPerl.obj \ $(DIR_O)\LexPLM.obj \ $(DIR_O)\LexPO.obj \ $(DIR_O)\LexPOV.obj \ $(DIR_O)\LexPowerPro.obj \ $(DIR_O)\LexPowerShell.obj \ $(DIR_O)\LexProgress.obj \ $(DIR_O)\LexPS.obj \ $(DIR_O)\LexPython.obj \ $(DIR_O)\LexR.obj \ $(DIR_O)\LexRebol.obj \ $(DIR_O)\LexRuby.obj \ $(DIR_O)\LexScriptol.obj \ $(DIR_O)\LexSmalltalk.obj \ $(DIR_O)\LexSML.obj \ $(DIR_O)\LexSorcus.obj \ $(DIR_O)\LexSpecman.obj \ $(DIR_O)\LexSpice.obj \ $(DIR_O)\LexSQL.obj \ $(DIR_O)\LexTACL.obj \ $(DIR_O)\LexTADS3.obj \ $(DIR_O)\LexTAL.obj \ $(DIR_O)\LexTCL.obj \ $(DIR_O)\LexTCMD.obj \ $(DIR_O)\LexTeX.obj \ $(DIR_O)\LexTxt2tags.obj \ $(DIR_O)\LexVB.obj \ $(DIR_O)\LexVerilog.obj \ $(DIR_O)\LexVHDL.obj \ $(DIR_O)\LexVisualProlog.obj \ $(DIR_O)\LexYAML.obj \ #--Autogenerated -- end of automatically generated section LOBJS=\ $(DIR_O)\Accessor.obj \ $(DIR_O)\AutoComplete.obj \ $(DIR_O)\CallTip.obj \ $(DIR_O)\Catalogue.obj \ $(DIR_O)\CellBuffer.obj \ $(DIR_O)\CharacterSet.obj \ $(DIR_O)\CharClassify.obj \ $(DIR_O)\ContractionState.obj \ $(DIR_O)\Decoration.obj \ $(DIR_O)\Document.obj \ $(DIR_O)\Editor.obj \ $(DIR_O)\ExternalLexer.obj \ $(DIR_O)\Indicator.obj \ $(DIR_O)\KeyMap.obj \ $(DIR_O)\LexerBase.obj \ $(DIR_O)\LexerModule.obj \ $(DIR_O)\LexerSimple.obj \ $(DIR_O)\LineMarker.obj \ $(DIR_O)\PerLine.obj \ $(DIR_O)\PlatWin.obj \ $(DIR_O)\PositionCache.obj \ $(DIR_O)\PropSetSimple.obj \ $(DIR_O)\RESearch.obj \ $(DIR_O)\RunStyles.obj \ $(DIR_O)\ScintillaBaseL.obj \ $(DIR_O)\ScintillaWinL.obj \ $(DIR_O)\Selection.obj \ $(DIR_O)\Style.obj \ $(DIR_O)\StyleContext.obj \ $(DIR_O)\UniConversion.obj \ $(DIR_O)\ViewStyle.obj \ $(DIR_O)\WordList.obj \ $(DIR_O)\XPM.obj \ $(LEXOBJS) $(DIR_O)\ScintRes.res : ScintRes.rc $(RC) -fo$@ $** $(COMPONENT): $(SOBJS) $(DIR_O)\ScintRes.res $(LD) $(LDFLAGS) -DEF:Scintilla.def -DLL -OUT:$@ $** $(LIBS) $(LEXCOMPONENT): $(LOBJS) $(DIR_O)\ScintRes.res $(LD) $(LDFLAGS) -DEF:Scintilla.def -DLL -OUT:$@ $** $(LIBS) $(LEXLIB): $(LEXOBJS) LIB /OUT:$@ $(LEXOBJS) # Define how to build all the objects and what they depend on {..\src}.cxx{$(DIR_O)}.obj:: $(CC) $(CXXFLAGS) -c $(NAME)$(DIR_O)\ $< {..\lexlib}.cxx{$(DIR_O)}.obj:: $(CC) $(CXXFLAGS) -c $(NAME)$(DIR_O)\ $< {..\lexers}.cxx{$(DIR_O)}.obj:: $(CC) $(CXXFLAGS) -c $(NAME)$(DIR_O)\ $< {.}.cxx{$(DIR_O)}.obj:: $(CC) $(CXXFLAGS) -c $(NAME)$(DIR_O)\ $< # Some source files are compiled into more than one object because of different conditional compilation $(DIR_O)\ScintillaBaseL.obj: ..\src\ScintillaBase.cxx $(CC) $(CXXFLAGS) -DSCI_LEXER -c $(NAME)$@ ..\src\ScintillaBase.cxx $(DIR_O)\ScintillaWinL.obj: ScintillaWin.cxx $(CC) $(CXXFLAGS) -DSCI_LEXER -c $(NAME)$@ ScintillaWin.cxx $(DIR_O)\ScintillaWinS.obj: ScintillaWin.cxx $(CC) $(CXXFLAGS) -DSTATIC_BUILD -c $(NAME)$@ ScintillaWin.cxx # Dependencies # All lexers depend on this set of headers LEX_HEADERS= ..\include\ILexer.h ..\include\Scintilla.h ..\include\SciLexer.h \ ..\lexlib\Accessor.h ..\lexlib\CharacterSet.h ..\lexlib\LexAccessor.h \ ..\lexlib\LexerModule.h ..\lexlib\StyleContext.h $(DIR_O)\AutoComplete.obj: ../src/AutoComplete.cxx ../include/Platform.h \ ../src/AutoComplete.h $(DIR_O)\Accessor.obj: ../lexlib/Accessor.cxx ../lexlib/Accessor.h $(DIR_O)\CallTip.obj: ../src/CallTip.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/CallTip.h $(DIR_O)\CellBuffer.obj: ../src/CellBuffer.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SVector.h ../src/SplitVector.h \ ../src/Partitioning.h ../src/CellBuffer.h $(DIR_O)\CharacterSet.obj: ../lexlib/CharacterSet.cxx ../lexlib/CharacterSet.h $(DIR_O)\CharClassify.obj: ../src/CharClassify.cxx ../src/CharClassify.h $(DIR_O)\ContractionState.obj: ../src/ContractionState.cxx ../include/Platform.h \ ../src/ContractionState.h $(DIR_O)\Decoration.obj: ../src/Decoration.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/Decoration.h $(DIR_O)\Document.obj: ../src/Document.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SVector.h ../src/SplitVector.h \ ../src/Partitioning.h ../src/RunStyles.h ../src/CellBuffer.h \ ../src/CharClassify.h ../src/Decoration.h ../src/Document.h \ ../src/RESearch.h ../src/PerLine.h $(DIR_O)\Editor.obj: ../src/Editor.cxx ../include/Platform.h ../include/Scintilla.h \ ../src/ContractionState.h ../src/SVector.h ../src/SplitVector.h \ ../src/Partitioning.h ../src/CellBuffer.h ../src/KeyMap.h \ ../src/RunStyles.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ ../src/Style.h ../src/ViewStyle.h ../src/CharClassify.h \ ../src/Decoration.h ../src/Document.h ../src/Editor.h ../src/Selection.h ../src/PositionCache.h $(DIR_O)\ExternalLexer.obj: ../src/ExternalLexer.cxx ../include/Platform.h \ ../include/Scintilla.h ../include/SciLexer.h \ ../lexlib/Accessor.h ../src/ExternalLexer.h $(DIR_O)\Indicator.obj: ../src/Indicator.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/Indicator.h $(DIR_O)\KeyMap.obj: ../src/KeyMap.cxx ../include/Platform.h ../include/Scintilla.h \ ../src/KeyMap.h #++Autogenerated -- run src/LexGen.py to regenerate #**\n\($(DIR_O)\\\*.obj: ..\\lexers\\\*.cxx $(LEX_HEADERS)\n\n\) $(DIR_O)\LexA68k.obj: ..\lexers\LexA68k.cxx $(LEX_HEADERS) $(DIR_O)\LexAbaqus.obj: ..\lexers\LexAbaqus.cxx $(LEX_HEADERS) $(DIR_O)\LexAda.obj: ..\lexers\LexAda.cxx $(LEX_HEADERS) $(DIR_O)\LexAPDL.obj: ..\lexers\LexAPDL.cxx $(LEX_HEADERS) $(DIR_O)\LexAsm.obj: ..\lexers\LexAsm.cxx $(LEX_HEADERS) $(DIR_O)\LexAsn1.obj: ..\lexers\LexAsn1.cxx $(LEX_HEADERS) $(DIR_O)\LexASY.obj: ..\lexers\LexASY.cxx $(LEX_HEADERS) $(DIR_O)\LexAU3.obj: ..\lexers\LexAU3.cxx $(LEX_HEADERS) $(DIR_O)\LexAVE.obj: ..\lexers\LexAVE.cxx $(LEX_HEADERS) $(DIR_O)\LexAVS.obj: ..\lexers\LexAVS.cxx $(LEX_HEADERS) $(DIR_O)\LexBaan.obj: ..\lexers\LexBaan.cxx $(LEX_HEADERS) $(DIR_O)\LexBash.obj: ..\lexers\LexBash.cxx $(LEX_HEADERS) $(DIR_O)\LexBasic.obj: ..\lexers\LexBasic.cxx $(LEX_HEADERS) $(DIR_O)\LexBullant.obj: ..\lexers\LexBullant.cxx $(LEX_HEADERS) $(DIR_O)\LexCaml.obj: ..\lexers\LexCaml.cxx $(LEX_HEADERS) $(DIR_O)\LexCLW.obj: ..\lexers\LexCLW.cxx $(LEX_HEADERS) $(DIR_O)\LexCmake.obj: ..\lexers\LexCmake.cxx $(LEX_HEADERS) $(DIR_O)\LexCOBOL.obj: ..\lexers\LexCOBOL.cxx $(LEX_HEADERS) $(DIR_O)\LexCoffeeScript.obj: ..\lexers\LexCoffeeScript.cxx $(LEX_HEADERS) $(DIR_O)\LexConf.obj: ..\lexers\LexConf.cxx $(LEX_HEADERS) $(DIR_O)\LexCPP.obj: ..\lexers\LexCPP.cxx $(LEX_HEADERS) $(DIR_O)\LexCrontab.obj: ..\lexers\LexCrontab.cxx $(LEX_HEADERS) $(DIR_O)\LexCsound.obj: ..\lexers\LexCsound.cxx $(LEX_HEADERS) $(DIR_O)\LexCSS.obj: ..\lexers\LexCSS.cxx $(LEX_HEADERS) $(DIR_O)\LexD.obj: ..\lexers\LexD.cxx $(LEX_HEADERS) $(DIR_O)\LexECL.obj: ..\lexers\LexECL.cxx $(LEX_HEADERS) $(DIR_O)\LexEiffel.obj: ..\lexers\LexEiffel.cxx $(LEX_HEADERS) $(DIR_O)\LexErlang.obj: ..\lexers\LexErlang.cxx $(LEX_HEADERS) $(DIR_O)\LexEScript.obj: ..\lexers\LexEScript.cxx $(LEX_HEADERS) $(DIR_O)\LexFlagship.obj: ..\lexers\LexFlagship.cxx $(LEX_HEADERS) $(DIR_O)\LexForth.obj: ..\lexers\LexForth.cxx $(LEX_HEADERS) $(DIR_O)\LexFortran.obj: ..\lexers\LexFortran.cxx $(LEX_HEADERS) $(DIR_O)\LexGAP.obj: ..\lexers\LexGAP.cxx $(LEX_HEADERS) $(DIR_O)\LexGui4Cli.obj: ..\lexers\LexGui4Cli.cxx $(LEX_HEADERS) $(DIR_O)\LexHaskell.obj: ..\lexers\LexHaskell.cxx $(LEX_HEADERS) $(DIR_O)\LexHTML.obj: ..\lexers\LexHTML.cxx $(LEX_HEADERS) $(DIR_O)\LexInno.obj: ..\lexers\LexInno.cxx $(LEX_HEADERS) $(DIR_O)\LexKix.obj: ..\lexers\LexKix.cxx $(LEX_HEADERS) $(DIR_O)\LexLaTeX.obj: ..\lexers\LexLaTeX.cxx $(LEX_HEADERS) $(DIR_O)\LexLisp.obj: ..\lexers\LexLisp.cxx $(LEX_HEADERS) $(DIR_O)\LexLout.obj: ..\lexers\LexLout.cxx $(LEX_HEADERS) $(DIR_O)\LexLua.obj: ..\lexers\LexLua.cxx $(LEX_HEADERS) $(DIR_O)\LexMagik.obj: ..\lexers\LexMagik.cxx $(LEX_HEADERS) $(DIR_O)\LexMarkdown.obj: ..\lexers\LexMarkdown.cxx $(LEX_HEADERS) $(DIR_O)\LexMatlab.obj: ..\lexers\LexMatlab.cxx $(LEX_HEADERS) $(DIR_O)\LexMetapost.obj: ..\lexers\LexMetapost.cxx $(LEX_HEADERS) $(DIR_O)\LexMMIXAL.obj: ..\lexers\LexMMIXAL.cxx $(LEX_HEADERS) $(DIR_O)\LexModula.obj: ..\lexers\LexModula.cxx $(LEX_HEADERS) $(DIR_O)\LexMPT.obj: ..\lexers\LexMPT.cxx $(LEX_HEADERS) $(DIR_O)\LexMSSQL.obj: ..\lexers\LexMSSQL.cxx $(LEX_HEADERS) $(DIR_O)\LexMySQL.obj: ..\lexers\LexMySQL.cxx $(LEX_HEADERS) $(DIR_O)\LexNimrod.obj: ..\lexers\LexNimrod.cxx $(LEX_HEADERS) $(DIR_O)\LexNsis.obj: ..\lexers\LexNsis.cxx $(LEX_HEADERS) $(DIR_O)\LexOpal.obj: ..\lexers\LexOpal.cxx $(LEX_HEADERS) $(DIR_O)\LexOScript.obj: ..\lexers\LexOScript.cxx $(LEX_HEADERS) $(DIR_O)\LexOthers.obj: ..\lexers\LexOthers.cxx $(LEX_HEADERS) $(DIR_O)\LexPascal.obj: ..\lexers\LexPascal.cxx $(LEX_HEADERS) $(DIR_O)\LexPB.obj: ..\lexers\LexPB.cxx $(LEX_HEADERS) $(DIR_O)\LexPerl.obj: ..\lexers\LexPerl.cxx $(LEX_HEADERS) $(DIR_O)\LexPLM.obj: ..\lexers\LexPLM.cxx $(LEX_HEADERS) $(DIR_O)\LexPO.obj: ..\lexers\LexPO.cxx $(LEX_HEADERS) $(DIR_O)\LexPOV.obj: ..\lexers\LexPOV.cxx $(LEX_HEADERS) $(DIR_O)\LexPowerPro.obj: ..\lexers\LexPowerPro.cxx $(LEX_HEADERS) $(DIR_O)\LexPowerShell.obj: ..\lexers\LexPowerShell.cxx $(LEX_HEADERS) $(DIR_O)\LexProgress.obj: ..\lexers\LexProgress.cxx $(LEX_HEADERS) $(DIR_O)\LexPS.obj: ..\lexers\LexPS.cxx $(LEX_HEADERS) $(DIR_O)\LexPython.obj: ..\lexers\LexPython.cxx $(LEX_HEADERS) $(DIR_O)\LexR.obj: ..\lexers\LexR.cxx $(LEX_HEADERS) $(DIR_O)\LexRebol.obj: ..\lexers\LexRebol.cxx $(LEX_HEADERS) $(DIR_O)\LexRuby.obj: ..\lexers\LexRuby.cxx $(LEX_HEADERS) $(DIR_O)\LexScriptol.obj: ..\lexers\LexScriptol.cxx $(LEX_HEADERS) $(DIR_O)\LexSmalltalk.obj: ..\lexers\LexSmalltalk.cxx $(LEX_HEADERS) $(DIR_O)\LexSML.obj: ..\lexers\LexSML.cxx $(LEX_HEADERS) $(DIR_O)\LexSorcus.obj: ..\lexers\LexSorcus.cxx $(LEX_HEADERS) $(DIR_O)\LexSpecman.obj: ..\lexers\LexSpecman.cxx $(LEX_HEADERS) $(DIR_O)\LexSpice.obj: ..\lexers\LexSpice.cxx $(LEX_HEADERS) $(DIR_O)\LexSQL.obj: ..\lexers\LexSQL.cxx $(LEX_HEADERS) $(DIR_O)\LexTACL.obj: ..\lexers\LexTACL.cxx $(LEX_HEADERS) $(DIR_O)\LexTADS3.obj: ..\lexers\LexTADS3.cxx $(LEX_HEADERS) $(DIR_O)\LexTAL.obj: ..\lexers\LexTAL.cxx $(LEX_HEADERS) $(DIR_O)\LexTCL.obj: ..\lexers\LexTCL.cxx $(LEX_HEADERS) $(DIR_O)\LexTCMD.obj: ..\lexers\LexTCMD.cxx $(LEX_HEADERS) $(DIR_O)\LexTeX.obj: ..\lexers\LexTeX.cxx $(LEX_HEADERS) $(DIR_O)\LexTxt2tags.obj: ..\lexers\LexTxt2tags.cxx $(LEX_HEADERS) $(DIR_O)\LexVB.obj: ..\lexers\LexVB.cxx $(LEX_HEADERS) $(DIR_O)\LexVerilog.obj: ..\lexers\LexVerilog.cxx $(LEX_HEADERS) $(DIR_O)\LexVHDL.obj: ..\lexers\LexVHDL.cxx $(LEX_HEADERS) $(DIR_O)\LexVisualProlog.obj: ..\lexers\LexVisualProlog.cxx $(LEX_HEADERS) $(DIR_O)\LexYAML.obj: ..\lexers\LexYAML.cxx $(LEX_HEADERS) #--Autogenerated -- end of automatically generated section $(DIR_O)\LexerBase.obj: ../lexlib/LexerBase.cxx ../lexlib/LexerBase.h $(DIR_O)\LexerModule.obj: ../lexlib/LexerModule.cxx ../lexlib/LexerModule.h $(DIR_O)\LexerSimple.obj: ../lexlib/LexerSimple.cxx ../lexlib/LexerSimple.h $(DIR_O)\LineMarker.obj: ../src/LineMarker.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/XPM.h ../src/LineMarker.h $(DIR_O)\PerLine.obj: ../src/PerLine.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SVector.h ../src/SplitVector.h \ ../src/Partitioning.h ../src/RunStyles.h ../src/PerLine.h $(DIR_O)\PlatWin.obj: PlatWin.cxx ../include/Platform.h \ ../src/UniConversion.h ../src/XPM.h $(DIR_O)\PositionCache.obj: ../src/PositionCache.cxx ../include/Platform.h ../include/Scintilla.h \ ../src/ContractionState.h ../src/SVector.h ../src/SplitVector.h \ ../src/Partitioning.h ../src/CellBuffer.h ../src/KeyMap.h \ ../src/RunStyles.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ ../src/Style.h ../src/ViewStyle.h ../src/CharClassify.h \ ../src/Decoration.h ../src/Document.h ../src/Editor.h ../src/Selection.h ../src/PositionCache.h $(DIR_O)\PropSetSimple.obj: ../lexlib/PropSetSimple.cxx ../include/Platform.h $(DIR_O)\RESearch.obj: ../src/RESearch.cxx ../src/CharClassify.h ../src/RESearch.h $(DIR_O)\RunStyles.obj: ../src/RunStyles.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h $(DIR_O)\ScintillaBase.obj: ../src/ScintillaBase.cxx ../include/Platform.h \ ../include/Scintilla.h \ ../src/ContractionState.h ../src/SVector.h ../src/SplitVector.h \ ../src/Partitioning.h ../src/RunStyles.h ../src/CellBuffer.h \ ../src/CallTip.h ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h \ ../src/LineMarker.h ../src/Style.h ../src/ViewStyle.h \ ../src/AutoComplete.h ../src/CharClassify.h ../src/Decoration.h \ ../src/Document.h ../src/Editor.h ../src/Selection.h ../src/ScintillaBase.h $(DIR_O)\ScintillaBaseL.obj: ../src/ScintillaBase.cxx ../include/Platform.h \ ../include/Scintilla.h \ ../src/ContractionState.h ../src/SVector.h ../src/SplitVector.h \ ../src/Partitioning.h ../src/RunStyles.h ../src/CellBuffer.h \ ../src/CallTip.h ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h \ ../src/LineMarker.h ../src/Style.h ../src/ViewStyle.h \ ../src/AutoComplete.h ../src/CharClassify.h ../src/Decoration.h \ ../src/Document.h ../src/Editor.h ../src/Selection.h ../src/ScintillaBase.h $(DIR_O)\ScintillaWin.obj: ScintillaWin.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/ContractionState.h \ ../src/SVector.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h \ ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h ../src/Style.h \ ../src/AutoComplete.h ../src/ViewStyle.h ../src/CharClassify.h \ ../src/Decoration.h ../src/Document.h ../src/Editor.h \ ../src/ScintillaBase.h ../src/Selection.h ../src/UniConversion.h $(DIR_O)\ScintillaWinS.obj: ScintillaWin.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/ContractionState.h \ ../src/SVector.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h \ ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h ../src/Style.h \ ../src/AutoComplete.h ../src/ViewStyle.h ../src/CharClassify.h \ ../src/Decoration.h ../src/Document.h ../src/Editor.h \ ../src/ScintillaBase.h ../src/Selection.h ../src/UniConversion.h $(DIR_O)\ScintillaWinL.obj: ScintillaWin.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/ContractionState.h \ ../src/SVector.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h \ ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h ../src/Style.h \ ../src/AutoComplete.h ../src/ViewStyle.h ../src/CharClassify.h \ ../src/Decoration.h ../src/Document.h ../src/Editor.h \ ../src/ScintillaBase.h ../src/Selection.h ../src/UniConversion.h $(DIR_O)\Selection.obj: ../src/Selection.cxx ../include/Platform.h ../include/Scintilla.h \ ../src/Selection.h $(DIR_O)\Style.obj: ../src/Style.cxx ../include/Platform.h ../include/Scintilla.h \ ../src/Style.h $(DIR_O)\StyleContext.obj: ../lexlib/StyleContext.cxx ../lexlib/Accessor.h \ ../lexlib/StyleContext.h $(DIR_O)\UniConversion.obj: ../src/UniConversion.cxx ../src/UniConversion.h $(DIR_O)\ViewStyle.obj: ../src/ViewStyle.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ ../src/Style.h ../src/ViewStyle.h $(DIR_O)\WordList.obj: ../lexlib/WordList.cxx ../lexlib/WordList.h $(DIR_O)\XPM.obj: ../src/XPM.cxx ../include/Platform.h ../src/XPM.h |
Added win32/scintilla_vc6.mak.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 |
# Make file for Scintilla on Windows Visual C++ version # Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org> # The License.txt file describes the conditions under which this software may be distributed. # This makefile is for using Visual C++ with nmake. # Usage for Microsoft: # nmake -f scintilla.mak # For debug versions define DEBUG on the command line: # nmake DEBUG=1 -f scintilla.mak # The main makefile uses mingw32 gcc and may be more current than this file. .SUFFIXES: .cxx DIR_O=. DIR_BIN=..\bin COMPONENT=$(DIR_BIN)\Scintilla.dll LEXCOMPONENT=$(DIR_BIN)\SciLexer.dll CC=cl RC=rc LD=link #-Zc:forScope -Zc:wchar_t CXXFLAGS=-Zi -TP -W3 -EHsc # For something scary:-Wp64 CXXDEBUG=-Od -MTd -DDEBUG CXXNDEBUG=-O1 -MT -DNDEBUG NAME=-Fo # If you have problems with lexers being linked, try removing -OPT:REF and replacing with -OPT:NOREF LDFLAGS=-OPT:NOWIN98 -OPT:REF LDDEBUG= LIBS=KERNEL32.lib USER32.lib GDI32.lib IMM32.lib OLE32.LIB NOLOGO=-nologo !IFDEF QUIET CC=@$(CC) CXXFLAGS=$(CXXFLAGS) $(NOLOGO) LDFLAGS=$(LDFLAGS) $(NOLOGO) !ENDIF !IFDEF DEBUG CXXFLAGS=$(CXXFLAGS) $(CXXDEBUG) LDFLAGS=$(LDDEBUG) $(LDFLAGS) !ELSE CXXFLAGS=$(CXXFLAGS) $(CXXNDEBUG) !ENDIF INCLUDEDIRS=-I../include -I../src -I../lexlib CXXFLAGS=$(CXXFLAGS) $(INCLUDEDIRS) ALL: $(COMPONENT) $(LEXCOMPONENT) $(DIR_O)\ScintillaWinS.obj clean: -del /q $(DIR_O)\*.obj $(DIR_O)\*.pdb $(COMPONENT) $(LEXCOMPONENT) \ $(DIR_O)\*.res $(DIR_BIN)\*.map $(DIR_BIN)\*.exp $(DIR_BIN)\*.pdb $(DIR_BIN)\*.lib SOBJS=\ $(DIR_O)\AutoComplete.obj \ $(DIR_O)\CallTip.obj \ $(DIR_O)\CellBuffer.obj \ $(DIR_O)\CharacterSet.obj \ $(DIR_O)\CharClassify.obj \ $(DIR_O)\ContractionState.obj \ $(DIR_O)\Decoration.obj \ $(DIR_O)\Document.obj \ $(DIR_O)\Editor.obj \ $(DIR_O)\Indicator.obj \ $(DIR_O)\KeyMap.obj \ $(DIR_O)\LineMarker.obj \ $(DIR_O)\PerLine.obj \ $(DIR_O)\PlatWin.obj \ $(DIR_O)\PositionCache.obj \ $(DIR_O)\PropSetSimple.obj \ $(DIR_O)\RESearch.obj \ $(DIR_O)\RunStyles.obj \ $(DIR_O)\ScintillaBase.obj \ $(DIR_O)\ScintillaWin.obj \ $(DIR_O)\Selection.obj \ $(DIR_O)\Style.obj \ $(DIR_O)\UniConversion.obj \ $(DIR_O)\ViewStyle.obj \ $(DIR_O)\XPM.obj #++Autogenerated -- run src/LexGen.py to regenerate #**LEXOBJS=\\\n\(\t$(DIR_O)\\\*.obj \\\n\) LEXOBJS=\ $(DIR_O)\LexA68k.obj \ $(DIR_O)\LexAbaqus.obj \ $(DIR_O)\LexAda.obj \ $(DIR_O)\LexAPDL.obj \ $(DIR_O)\LexAsm.obj \ $(DIR_O)\LexAsn1.obj \ $(DIR_O)\LexASY.obj \ $(DIR_O)\LexAU3.obj \ $(DIR_O)\LexAVE.obj \ $(DIR_O)\LexAVS.obj \ $(DIR_O)\LexBaan.obj \ $(DIR_O)\LexBash.obj \ $(DIR_O)\LexBasic.obj \ $(DIR_O)\LexBullant.obj \ $(DIR_O)\LexCaml.obj \ $(DIR_O)\LexCLW.obj \ $(DIR_O)\LexCmake.obj \ $(DIR_O)\LexCOBOL.obj \ $(DIR_O)\LexCoffeeScript.obj \ $(DIR_O)\LexConf.obj \ $(DIR_O)\LexCPP.obj \ $(DIR_O)\LexCrontab.obj \ $(DIR_O)\LexCsound.obj \ $(DIR_O)\LexCSS.obj \ $(DIR_O)\LexD.obj \ $(DIR_O)\LexECL.obj \ $(DIR_O)\LexEiffel.obj \ $(DIR_O)\LexErlang.obj \ $(DIR_O)\LexEScript.obj \ $(DIR_O)\LexFlagship.obj \ $(DIR_O)\LexForth.obj \ $(DIR_O)\LexFortran.obj \ $(DIR_O)\LexGAP.obj \ $(DIR_O)\LexGui4Cli.obj \ $(DIR_O)\LexHaskell.obj \ $(DIR_O)\LexHTML.obj \ $(DIR_O)\LexInno.obj \ $(DIR_O)\LexKix.obj \ $(DIR_O)\LexLaTeX.obj \ $(DIR_O)\LexLisp.obj \ $(DIR_O)\LexLout.obj \ $(DIR_O)\LexLua.obj \ $(DIR_O)\LexMagik.obj \ $(DIR_O)\LexMarkdown.obj \ $(DIR_O)\LexMatlab.obj \ $(DIR_O)\LexMetapost.obj \ $(DIR_O)\LexMMIXAL.obj \ $(DIR_O)\LexModula.obj \ $(DIR_O)\LexMPT.obj \ $(DIR_O)\LexMSSQL.obj \ $(DIR_O)\LexMySQL.obj \ $(DIR_O)\LexNimrod.obj \ $(DIR_O)\LexNsis.obj \ $(DIR_O)\LexOpal.obj \ $(DIR_O)\LexOScript.obj \ $(DIR_O)\LexOthers.obj \ $(DIR_O)\LexPascal.obj \ $(DIR_O)\LexPB.obj \ $(DIR_O)\LexPerl.obj \ $(DIR_O)\LexPLM.obj \ $(DIR_O)\LexPO.obj \ $(DIR_O)\LexPOV.obj \ $(DIR_O)\LexPowerPro.obj \ $(DIR_O)\LexPowerShell.obj \ $(DIR_O)\LexProgress.obj \ $(DIR_O)\LexPS.obj \ $(DIR_O)\LexPython.obj \ $(DIR_O)\LexR.obj \ $(DIR_O)\LexRebol.obj \ $(DIR_O)\LexRuby.obj \ $(DIR_O)\LexScriptol.obj \ $(DIR_O)\LexSmalltalk.obj \ $(DIR_O)\LexSML.obj \ $(DIR_O)\LexSorcus.obj \ $(DIR_O)\LexSpecman.obj \ $(DIR_O)\LexSpice.obj \ $(DIR_O)\LexSQL.obj \ $(DIR_O)\LexTACL.obj \ $(DIR_O)\LexTADS3.obj \ $(DIR_O)\LexTAL.obj \ $(DIR_O)\LexTCL.obj \ $(DIR_O)\LexTCMD.obj \ $(DIR_O)\LexTeX.obj \ $(DIR_O)\LexTxt2tags.obj \ $(DIR_O)\LexVB.obj \ $(DIR_O)\LexVerilog.obj \ $(DIR_O)\LexVHDL.obj \ $(DIR_O)\LexVisualProlog.obj \ $(DIR_O)\LexYAML.obj \ #--Autogenerated -- end of automatically generated section LOBJS=\ $(DIR_O)\Accessor.obj \ $(DIR_O)\AutoComplete.obj \ $(DIR_O)\CallTip.obj \ $(DIR_O)\Catalogue.obj \ $(DIR_O)\CellBuffer.obj \ $(DIR_O)\CharacterSet.obj \ $(DIR_O)\CharClassify.obj \ $(DIR_O)\ContractionState.obj \ $(DIR_O)\Decoration.obj \ $(DIR_O)\Document.obj \ $(DIR_O)\Editor.obj \ $(DIR_O)\ExternalLexer.obj \ $(DIR_O)\Indicator.obj \ $(DIR_O)\KeyMap.obj \ $(DIR_O)\LexerBase.obj \ $(DIR_O)\LexerModule.obj \ $(DIR_O)\LexerSimple.obj \ $(DIR_O)\LineMarker.obj \ $(DIR_O)\PerLine.obj \ $(DIR_O)\PlatWin.obj \ $(DIR_O)\PositionCache.obj \ $(DIR_O)\PropSetSimple.obj \ $(DIR_O)\RESearch.obj \ $(DIR_O)\RunStyles.obj \ $(DIR_O)\ScintillaBaseL.obj \ $(DIR_O)\ScintillaWinL.obj \ $(DIR_O)\Selection.obj \ $(DIR_O)\Style.obj \ $(DIR_O)\StyleContext.obj \ $(DIR_O)\UniConversion.obj \ $(DIR_O)\ViewStyle.obj \ $(DIR_O)\WordList.obj \ $(DIR_O)\XPM.obj \ $(LEXOBJS) $(DIR_O)\ScintRes.res : ScintRes.rc $(RC) -fo$@ $** $(COMPONENT): $(SOBJS) $(DIR_O)\ScintRes.res $(LD) $(LDFLAGS) -DEF:Scintilla.def -DLL -OUT:$@ $** $(LIBS) $(LEXCOMPONENT): $(LOBJS) $(DIR_O)\ScintRes.res $(LD) $(LDFLAGS) -DEF:Scintilla.def -DLL -OUT:$@ $** $(LIBS) # Define how to build all the objects and what they depend on {..\src}.cxx{$(DIR_O)}.obj: $(CC) $(CXXFLAGS) -c $(NAME)$@ $< {..\lexlib}.cxx{$(DIR_O)}.obj: $(CC) $(CXXFLAGS) -c $(NAME)$@ $< {..\lexers}.cxx{$(DIR_O)}.obj: $(CC) $(CXXFLAGS) -c $(NAME)$@ $< {.}.cxx{$(DIR_O)}.obj: $(CC) $(CXXFLAGS) -c $(NAME)$@ $< # Some source files are compiled into more than one object because of different conditional compilation $(DIR_O)\ScintillaBaseL.obj: ..\src\ScintillaBase.cxx $(CC) $(CXXFLAGS) -DSCI_LEXER -c $(NAME)$@ ..\src\ScintillaBase.cxx $(DIR_O)\ScintillaWinL.obj: ScintillaWin.cxx $(CC) $(CXXFLAGS) -DSCI_LEXER -c $(NAME)$@ ScintillaWin.cxx $(DIR_O)\ScintillaWinS.obj: ScintillaWin.cxx $(CC) $(CXXFLAGS) -DSTATIC_BUILD -c $(NAME)$@ ScintillaWin.cxx # Dependencies # All lexers depend on this set of headers LEX_HEADERS= ..\include\ILexer.h ..\include\Scintilla.h ..\include\SciLexer.h \ ..\lexlib\Accessor.h ..\lexlib\CharacterSet.h ..\lexlib\LexAccessor.h \ ..\lexlib\LexerModule.h ..\lexlib\StyleContext.h $(DIR_O)\AutoComplete.obj: ../src/AutoComplete.cxx ../include/Platform.h \ ../src/AutoComplete.h $(DIR_O)\Accessor.obj: ../lexlib/Accessor.cxx ../lexlib/Accessor.h $(DIR_O)\CallTip.obj: ../src/CallTip.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/CallTip.h $(DIR_O)\CellBuffer.obj: ../src/CellBuffer.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SVector.h ../src/SplitVector.h \ ../src/Partitioning.h ../src/CellBuffer.h $(DIR_O)\CharacterSet.obj: ../lexlib/CharacterSet.cxx ../lexlib/CharacterSet.h $(DIR_O)\CharClassify.obj: ../src/CharClassify.cxx ../src/CharClassify.h $(DIR_O)\ContractionState.obj: ../src/ContractionState.cxx ../include/Platform.h \ ../src/ContractionState.h $(DIR_O)\Decoration.obj: ../src/Decoration.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/Decoration.h $(DIR_O)\Document.obj: ../src/Document.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SVector.h ../src/SplitVector.h \ ../src/Partitioning.h ../src/RunStyles.h ../src/CellBuffer.h \ ../src/CharClassify.h ../src/Decoration.h ../src/Document.h \ ../src/RESearch.h ../src/PerLine.h $(DIR_O)\Editor.obj: ../src/Editor.cxx ../include/Platform.h ../include/Scintilla.h \ ../src/ContractionState.h ../src/SVector.h ../src/SplitVector.h \ ../src/Partitioning.h ../src/CellBuffer.h ../src/KeyMap.h \ ../src/RunStyles.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ ../src/Style.h ../src/ViewStyle.h ../src/CharClassify.h \ ../src/Decoration.h ../src/Document.h ../src/Editor.h ../src/Selection.h ../src/PositionCache.h $(DIR_O)\ExternalLexer.obj: ../src/ExternalLexer.cxx ../include/Platform.h \ ../include/Scintilla.h ../include/SciLexer.h \ ../lexlib/Accessor.h ../src/ExternalLexer.h $(DIR_O)\Indicator.obj: ../src/Indicator.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/Indicator.h $(DIR_O)\KeyMap.obj: ../src/KeyMap.cxx ../include/Platform.h ../include/Scintilla.h \ ../src/KeyMap.h #++Autogenerated -- run src/LexGen.py to regenerate #**\n\($(DIR_O)\\\*.obj: ..\\lexers\\\*.cxx $(LEX_HEADERS)\n\n\) $(DIR_O)\LexA68k.obj: ..\lexers\LexA68k.cxx $(LEX_HEADERS) $(DIR_O)\LexAbaqus.obj: ..\lexers\LexAbaqus.cxx $(LEX_HEADERS) $(DIR_O)\LexAda.obj: ..\lexers\LexAda.cxx $(LEX_HEADERS) $(DIR_O)\LexAPDL.obj: ..\lexers\LexAPDL.cxx $(LEX_HEADERS) $(DIR_O)\LexAsm.obj: ..\lexers\LexAsm.cxx $(LEX_HEADERS) $(DIR_O)\LexAsn1.obj: ..\lexers\LexAsn1.cxx $(LEX_HEADERS) $(DIR_O)\LexASY.obj: ..\lexers\LexASY.cxx $(LEX_HEADERS) $(DIR_O)\LexAU3.obj: ..\lexers\LexAU3.cxx $(LEX_HEADERS) $(DIR_O)\LexAVE.obj: ..\lexers\LexAVE.cxx $(LEX_HEADERS) $(DIR_O)\LexAVS.obj: ..\lexers\LexAVS.cxx $(LEX_HEADERS) $(DIR_O)\LexBaan.obj: ..\lexers\LexBaan.cxx $(LEX_HEADERS) $(DIR_O)\LexBash.obj: ..\lexers\LexBash.cxx $(LEX_HEADERS) $(DIR_O)\LexBasic.obj: ..\lexers\LexBasic.cxx $(LEX_HEADERS) $(DIR_O)\LexBullant.obj: ..\lexers\LexBullant.cxx $(LEX_HEADERS) $(DIR_O)\LexCaml.obj: ..\lexers\LexCaml.cxx $(LEX_HEADERS) $(DIR_O)\LexCLW.obj: ..\lexers\LexCLW.cxx $(LEX_HEADERS) $(DIR_O)\LexCmake.obj: ..\lexers\LexCmake.cxx $(LEX_HEADERS) $(DIR_O)\LexCOBOL.obj: ..\lexers\LexCOBOL.cxx $(LEX_HEADERS) $(DIR_O)\LexCoffeeScript.obj: ..\lexers\LexCoffeeScript.cxx $(LEX_HEADERS) $(DIR_O)\LexConf.obj: ..\lexers\LexConf.cxx $(LEX_HEADERS) $(DIR_O)\LexCPP.obj: ..\lexers\LexCPP.cxx $(LEX_HEADERS) $(DIR_O)\LexCrontab.obj: ..\lexers\LexCrontab.cxx $(LEX_HEADERS) $(DIR_O)\LexCsound.obj: ..\lexers\LexCsound.cxx $(LEX_HEADERS) $(DIR_O)\LexCSS.obj: ..\lexers\LexCSS.cxx $(LEX_HEADERS) $(DIR_O)\LexD.obj: ..\lexers\LexD.cxx $(LEX_HEADERS) $(DIR_O)\LexECL.obj: ..\lexers\LexECL.cxx $(LEX_HEADERS) $(DIR_O)\LexEiffel.obj: ..\lexers\LexEiffel.cxx $(LEX_HEADERS) $(DIR_O)\LexErlang.obj: ..\lexers\LexErlang.cxx $(LEX_HEADERS) $(DIR_O)\LexEScript.obj: ..\lexers\LexEScript.cxx $(LEX_HEADERS) $(DIR_O)\LexFlagship.obj: ..\lexers\LexFlagship.cxx $(LEX_HEADERS) $(DIR_O)\LexForth.obj: ..\lexers\LexForth.cxx $(LEX_HEADERS) $(DIR_O)\LexFortran.obj: ..\lexers\LexFortran.cxx $(LEX_HEADERS) $(DIR_O)\LexGAP.obj: ..\lexers\LexGAP.cxx $(LEX_HEADERS) $(DIR_O)\LexGui4Cli.obj: ..\lexers\LexGui4Cli.cxx $(LEX_HEADERS) $(DIR_O)\LexHaskell.obj: ..\lexers\LexHaskell.cxx $(LEX_HEADERS) $(DIR_O)\LexHTML.obj: ..\lexers\LexHTML.cxx $(LEX_HEADERS) $(DIR_O)\LexInno.obj: ..\lexers\LexInno.cxx $(LEX_HEADERS) $(DIR_O)\LexKix.obj: ..\lexers\LexKix.cxx $(LEX_HEADERS) $(DIR_O)\LexLaTeX.obj: ..\lexers\LexLaTeX.cxx $(LEX_HEADERS) $(DIR_O)\LexLisp.obj: ..\lexers\LexLisp.cxx $(LEX_HEADERS) $(DIR_O)\LexLout.obj: ..\lexers\LexLout.cxx $(LEX_HEADERS) $(DIR_O)\LexLua.obj: ..\lexers\LexLua.cxx $(LEX_HEADERS) $(DIR_O)\LexMagik.obj: ..\lexers\LexMagik.cxx $(LEX_HEADERS) $(DIR_O)\LexMarkdown.obj: ..\lexers\LexMarkdown.cxx $(LEX_HEADERS) $(DIR_O)\LexMatlab.obj: ..\lexers\LexMatlab.cxx $(LEX_HEADERS) $(DIR_O)\LexMetapost.obj: ..\lexers\LexMetapost.cxx $(LEX_HEADERS) $(DIR_O)\LexMMIXAL.obj: ..\lexers\LexMMIXAL.cxx $(LEX_HEADERS) $(DIR_O)\LexModula.obj: ..\lexers\LexModula.cxx $(LEX_HEADERS) $(DIR_O)\LexMPT.obj: ..\lexers\LexMPT.cxx $(LEX_HEADERS) $(DIR_O)\LexMSSQL.obj: ..\lexers\LexMSSQL.cxx $(LEX_HEADERS) $(DIR_O)\LexMySQL.obj: ..\lexers\LexMySQL.cxx $(LEX_HEADERS) $(DIR_O)\LexNimrod.obj: ..\lexers\LexNimrod.cxx $(LEX_HEADERS) $(DIR_O)\LexNsis.obj: ..\lexers\LexNsis.cxx $(LEX_HEADERS) $(DIR_O)\LexOpal.obj: ..\lexers\LexOpal.cxx $(LEX_HEADERS) $(DIR_O)\LexOScript.obj: ..\lexers\LexOScript.cxx $(LEX_HEADERS) $(DIR_O)\LexOthers.obj: ..\lexers\LexOthers.cxx $(LEX_HEADERS) $(DIR_O)\LexPascal.obj: ..\lexers\LexPascal.cxx $(LEX_HEADERS) $(DIR_O)\LexPB.obj: ..\lexers\LexPB.cxx $(LEX_HEADERS) $(DIR_O)\LexPerl.obj: ..\lexers\LexPerl.cxx $(LEX_HEADERS) $(DIR_O)\LexPLM.obj: ..\lexers\LexPLM.cxx $(LEX_HEADERS) $(DIR_O)\LexPO.obj: ..\lexers\LexPO.cxx $(LEX_HEADERS) $(DIR_O)\LexPOV.obj: ..\lexers\LexPOV.cxx $(LEX_HEADERS) $(DIR_O)\LexPowerPro.obj: ..\lexers\LexPowerPro.cxx $(LEX_HEADERS) $(DIR_O)\LexPowerShell.obj: ..\lexers\LexPowerShell.cxx $(LEX_HEADERS) $(DIR_O)\LexProgress.obj: ..\lexers\LexProgress.cxx $(LEX_HEADERS) $(DIR_O)\LexPS.obj: ..\lexers\LexPS.cxx $(LEX_HEADERS) $(DIR_O)\LexPython.obj: ..\lexers\LexPython.cxx $(LEX_HEADERS) $(DIR_O)\LexR.obj: ..\lexers\LexR.cxx $(LEX_HEADERS) $(DIR_O)\LexRebol.obj: ..\lexers\LexRebol.cxx $(LEX_HEADERS) $(DIR_O)\LexRuby.obj: ..\lexers\LexRuby.cxx $(LEX_HEADERS) $(DIR_O)\LexScriptol.obj: ..\lexers\LexScriptol.cxx $(LEX_HEADERS) $(DIR_O)\LexSmalltalk.obj: ..\lexers\LexSmalltalk.cxx $(LEX_HEADERS) $(DIR_O)\LexSML.obj: ..\lexers\LexSML.cxx $(LEX_HEADERS) $(DIR_O)\LexSorcus.obj: ..\lexers\LexSorcus.cxx $(LEX_HEADERS) $(DIR_O)\LexSpecman.obj: ..\lexers\LexSpecman.cxx $(LEX_HEADERS) $(DIR_O)\LexSpice.obj: ..\lexers\LexSpice.cxx $(LEX_HEADERS) $(DIR_O)\LexSQL.obj: ..\lexers\LexSQL.cxx $(LEX_HEADERS) $(DIR_O)\LexTACL.obj: ..\lexers\LexTACL.cxx $(LEX_HEADERS) $(DIR_O)\LexTADS3.obj: ..\lexers\LexTADS3.cxx $(LEX_HEADERS) $(DIR_O)\LexTAL.obj: ..\lexers\LexTAL.cxx $(LEX_HEADERS) $(DIR_O)\LexTCL.obj: ..\lexers\LexTCL.cxx $(LEX_HEADERS) $(DIR_O)\LexTCMD.obj: ..\lexers\LexTCMD.cxx $(LEX_HEADERS) $(DIR_O)\LexTeX.obj: ..\lexers\LexTeX.cxx $(LEX_HEADERS) $(DIR_O)\LexTxt2tags.obj: ..\lexers\LexTxt2tags.cxx $(LEX_HEADERS) $(DIR_O)\LexVB.obj: ..\lexers\LexVB.cxx $(LEX_HEADERS) $(DIR_O)\LexVerilog.obj: ..\lexers\LexVerilog.cxx $(LEX_HEADERS) $(DIR_O)\LexVHDL.obj: ..\lexers\LexVHDL.cxx $(LEX_HEADERS) $(DIR_O)\LexVisualProlog.obj: ..\lexers\LexVisualProlog.cxx $(LEX_HEADERS) $(DIR_O)\LexYAML.obj: ..\lexers\LexYAML.cxx $(LEX_HEADERS) #--Autogenerated -- end of automatically generated section $(DIR_O)\LexerBase.obj: ../lexlib/LexerBase.cxx ../lexlib/LexerBase.h $(DIR_O)\LexerModule.obj: ../lexlib/LexerModule.cxx ../lexlib/LexerModule.h $(DIR_O)\LexerSimple.obj: ../lexlib/LexerSimple.cxx ../lexlib/LexerSimple.h $(DIR_O)\LineMarker.obj: ../src/LineMarker.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/XPM.h ../src/LineMarker.h $(DIR_O)\PerLine.obj: ../src/PerLine.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SVector.h ../src/SplitVector.h \ ../src/Partitioning.h ../src/RunStyles.h ../src/PerLine.h $(DIR_O)\PlatWin.obj: PlatWin.cxx ../include/Platform.h \ ../src/UniConversion.h ../src/XPM.h $(DIR_O)\PositionCache.obj: ../src/Editor.cxx ../include/Platform.h ../include/Scintilla.h \ ../src/ContractionState.h ../src/SVector.h ../src/SplitVector.h \ ../src/Partitioning.h ../src/CellBuffer.h ../src/KeyMap.h \ ../src/RunStyles.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ ../src/Style.h ../src/ViewStyle.h ../src/CharClassify.h \ ../src/Decoration.h ../src/Document.h ../src/Editor.h ../src/Selection.h ../src/PositionCache.h $(DIR_O)\PropSetSimple.obj: ../lexlib/PropSetSimple.cxx ../include/Platform.h $(DIR_O)\RESearch.obj: ../src/RESearch.cxx ../src/CharClassify.h ../src/RESearch.h $(DIR_O)\RunStyles.obj: ../src/RunStyles.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h $(DIR_O)\ScintillaBase.obj: ../src/ScintillaBase.cxx ../include/Platform.h \ ../include/Scintilla.h \ ../src/ContractionState.h ../src/SVector.h ../src/SplitVector.h \ ../src/Partitioning.h ../src/RunStyles.h ../src/CellBuffer.h \ ../src/CallTip.h ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h \ ../src/LineMarker.h ../src/Style.h ../src/ViewStyle.h \ ../src/AutoComplete.h ../src/CharClassify.h ../src/Decoration.h \ ../src/Document.h ../src/Editor.h ../src/Selection.h ../src/ScintillaBase.h $(DIR_O)\ScintillaBaseL.obj: ../src/ScintillaBase.cxx ../include/Platform.h \ ../include/Scintilla.h \ ../src/ContractionState.h ../src/SVector.h ../src/SplitVector.h \ ../src/Partitioning.h ../src/RunStyles.h ../src/CellBuffer.h \ ../src/CallTip.h ../src/KeyMap.h ../src/Indicator.h ../src/XPM.h \ ../src/LineMarker.h ../src/Style.h ../src/ViewStyle.h \ ../src/AutoComplete.h ../src/CharClassify.h ../src/Decoration.h \ ../src/Document.h ../src/Editor.h ../src/Selection.h ../src/ScintillaBase.h $(DIR_O)\ScintillaWin.obj: ScintillaWin.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/ContractionState.h \ ../src/SVector.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h \ ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h ../src/Style.h \ ../src/AutoComplete.h ../src/ViewStyle.h ../src/CharClassify.h \ ../src/Decoration.h ../src/Document.h ../src/Editor.h \ ../src/ScintillaBase.h ../src/Selection.h ../src/UniConversion.h $(DIR_O)\ScintillaWinS.obj: ScintillaWin.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/ContractionState.h \ ../src/SVector.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h \ ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h ../src/Style.h \ ../src/AutoComplete.h ../src/ViewStyle.h ../src/CharClassify.h \ ../src/Decoration.h ../src/Document.h ../src/Editor.h \ ../src/ScintillaBase.h ../src/Selection.h ../src/UniConversion.h $(DIR_O)\ScintillaWinL.obj: ScintillaWin.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/ContractionState.h \ ../src/SVector.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/CellBuffer.h ../src/CallTip.h ../src/KeyMap.h \ ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h ../src/Style.h \ ../src/AutoComplete.h ../src/ViewStyle.h ../src/CharClassify.h \ ../src/Decoration.h ../src/Document.h ../src/Editor.h \ ../src/ScintillaBase.h ../src/Selection.h ../src/UniConversion.h $(DIR_O)\Selection.obj: ../src/Selection.cxx ../include/Platform.h ../include/Scintilla.h \ ../src/Selection.h $(DIR_O)\Style.obj: ../src/Style.cxx ../include/Platform.h ../include/Scintilla.h \ ../src/Style.h $(DIR_O)\StyleContext.obj: ../lexlib/StyleContext.cxx ../lexlib/Accessor.h \ ../lexlib/StyleContext.h $(DIR_O)\UniConversion.obj: ../src/UniConversion.cxx ../src/UniConversion.h $(DIR_O)\ViewStyle.obj: ../src/ViewStyle.cxx ../include/Platform.h \ ../include/Scintilla.h ../src/SplitVector.h ../src/Partitioning.h \ ../src/RunStyles.h ../src/Indicator.h ../src/XPM.h ../src/LineMarker.h \ ../src/Style.h ../src/ViewStyle.h $(DIR_O)\WordList.obj: ../lexlib/WordList.cxx ../lexlib/WordList.h $(DIR_O)\XPM.obj: ../src/XPM.cxx ../include/Platform.h ../src/XPM.h |
Added zipsrc.bat.
> > > > |
1 2 3 4 |
cd .. del/q scintilla.zip zip scintilla.zip scintilla\*.* scintilla\*\*.* scintilla\*\*\*.* scintilla\*\*\*\*.* scintilla\*\*\*\*\*.* -x *.o -x *.obj -x *.dll -x *.lib -x *.res -x *.exp cd scintilla |