Added Scintilla imgui.
|
@ -8895,6 +8895,12 @@ struct ImFontAtlas::ImFontAtlasData
|
|||
int RangesCount;
|
||||
};
|
||||
|
||||
const stbtt_fontinfo& getFontInfo(int index)
|
||||
{
|
||||
const ImGuiIO& io = ImGui::GetIO();
|
||||
return io.Fonts[index].InputData[0]->FontInfo;
|
||||
}
|
||||
|
||||
ImFontAtlas::ImFontAtlas()
|
||||
{
|
||||
TexID = NULL;
|
||||
|
|
|
@ -0,0 +1,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.
|
|
@ -0,0 +1,67 @@
|
|||
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 2010 is the development system
|
||||
used for most development although TDM Mingw32 4.7.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.
|
||||
|
||||
*** 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
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1 @@
|
|||
This empty files ensures that the directory is created.
|
|
@ -0,0 +1,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
|
|
@ -0,0 +1,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
|
||||
CGFloat 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: @"tiff" 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 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 value 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.2f, 0.3f, 0.5f, 0.75f, 1.0f, 1.3f, 1.6f, 2.0f, 2.5f, 3.0f
|
||||
};
|
||||
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;
|
||||
CGFloat 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 accommodate 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
|
|
@ -0,0 +1,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).
|
||||
*/
|
||||
|
||||
typedef NS_OPTIONS(NSUInteger, 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.
|
||||
*/
|
||||
|
||||
typedef NS_ENUM(NSInteger, 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
|
||||
|
|
@ -0,0 +1,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 <assert.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
#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
|
|
@ -0,0 +1,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. */
|
||||
explicit 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 static_cast<float>(::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
|
|
@ -0,0 +1,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 static_cast<float>(::CTFontGetAscent(fontRef));
|
||||
}
|
||||
|
||||
float getDescent() const
|
||||
{
|
||||
return static_cast<float>(::CTFontGetDescent(fontRef));
|
||||
}
|
||||
|
||||
float getLeading() const
|
||||
{
|
||||
return static_cast<float>(::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
|
||||
|
|
@ -0,0 +1,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
|
||||
|
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "ILexer.h"
|
||||
|
||||
#ifdef SCI_LEXER
|
||||
#include "SciLexer.h"
|
||||
#include "PropSetSimple.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 "CharClassify.h"
|
||||
#include "Decoration.h"
|
||||
#include "CaseFolder.h"
|
||||
#include "Document.h"
|
||||
#include "CaseConvert.h"
|
||||
#include "Selection.h"
|
||||
#include "PositionCache.h"
|
||||
#include "EditModel.h"
|
||||
#include "MarginView.h"
|
||||
#include "EditView.h"
|
||||
#include "Editor.h"
|
||||
|
||||
#include "AutoComplete.h"
|
||||
#include "ScintillaBase.h"
|
||||
|
||||
extern "C" NSString* ScintillaRecPboardType;
|
||||
|
||||
@class SCIContentView;
|
||||
@class SCIMarginView;
|
||||
@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 {
|
||||
|
||||
/**
|
||||
* Main scintilla class, implemented for OS X (Cocoa).
|
||||
*/
|
||||
class ScintillaCocoa : public ScintillaBase
|
||||
{
|
||||
private:
|
||||
TimerTarget* timerTarget;
|
||||
NSEvent* lastMouseEvent;
|
||||
|
||||
id<ScintillaNotificationProtocol> delegate;
|
||||
|
||||
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 TargetAsUTF8(char *text);
|
||||
int EncodedFromUTF8(char *utf8, char *encoded) const;
|
||||
|
||||
int scrollSpeed;
|
||||
int scrollTicks;
|
||||
NSTimer* tickTimer;
|
||||
NSTimer* idleTimer;
|
||||
CFRunLoopObserverRef observer;
|
||||
|
||||
FindHighlightLayer *layerFindIndicator;
|
||||
|
||||
protected:
|
||||
Point GetVisibleOriginInMain() const;
|
||||
PRectangle GetClientRectangle() const;
|
||||
virtual PRectangle GetClientDrawingRectangle();
|
||||
Point ConvertPoint(NSPoint point);
|
||||
virtual void RedrawRect(PRectangle rc);
|
||||
virtual void DiscardOverdraw();
|
||||
virtual void Redraw();
|
||||
|
||||
virtual void Initialise();
|
||||
virtual void Finalise();
|
||||
virtual CaseFolder *CaseFolderForEncoding();
|
||||
virtual std::string CaseMapString(const std::string &s, int caseMapping);
|
||||
virtual void CancelModes();
|
||||
|
||||
public:
|
||||
ScintillaCocoa(SCIContentView* view, SCIMarginView* viewMargin);
|
||||
virtual ~ScintillaCocoa();
|
||||
|
||||
void SetDelegate(id<ScintillaNotificationProtocol> delegate_);
|
||||
void RegisterNotifyCallback(intptr_t windowid, SciNotifyFunc callback);
|
||||
sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
|
||||
|
||||
NSScrollView* ScrollContainer() const;
|
||||
SCIContentView* 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 TickFor(TickReason reason);
|
||||
bool FineTickerAvailable();
|
||||
bool FineTickerRunning(TickReason reason);
|
||||
void FineTickerStart(TickReason reason, int millis, int tolerance);
|
||||
void FineTickerCancel(TickReason reason);
|
||||
bool SetIdle(bool on);
|
||||
void SetMouseCapture(bool on);
|
||||
bool HaveMouseCapture();
|
||||
void WillDraw(NSRect rect);
|
||||
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(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam);
|
||||
|
||||
NSTimer *timers[tickPlatform+1];
|
||||
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);
|
||||
NSRange PositionsFromCharacters(NSRange range) const;
|
||||
NSRange CharactersFromPositions(NSRange range) const;
|
||||
void SelectOnlyMainSelection();
|
||||
void ConvertSelectionVirtualSpace();
|
||||
bool ClearAllSelections();
|
||||
void CompositionStart();
|
||||
void CompositionCommit();
|
||||
void CompositionUndo();
|
||||
virtual void SetDocPointer(Document *document);
|
||||
|
||||
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();
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
Двоичные данные
3rdparty/scintilla/cocoa/ScintillaFramework/English.lproj/InfoPlist.strings
поставляемый
Normal file
|
@ -0,0 +1,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>
|
1201
3rdparty/scintilla/cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj
поставляемый
Normal file
|
@ -0,0 +1,7 @@
|
|||
//
|
||||
// Prefix header for all source files of the 'Scintilla' target in the 'Scintilla' project.
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
|
@ -0,0 +1,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 "Scintilla/ScintillaView.h"
|
||||
#import "Scintilla/InfoBar.h"
|
||||
|
||||
@interface AppController : NSObject {
|
||||
IBOutlet NSBox *mEditHost;
|
||||
ScintillaView* mEditor;
|
||||
}
|
||||
|
||||
- (void) awakeFromNib;
|
||||
- (void) setupEditor;
|
||||
- (IBAction) searchText: (id) sender;
|
||||
|
||||
@end
|
|
@ -0,0 +1,282 @@
|
|||
/**
|
||||
* 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];
|
||||
}
|
||||
|
||||
-(IBAction) setFontQuality: (id) sender
|
||||
{
|
||||
[ScintillaView directCall:mEditor message:SCI_SETFONTQUALITY wParam:[sender tag] lParam:0];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
Двоичные данные
3rdparty/scintilla/cocoa/ScintillaTest/English.lproj/InfoPlist.strings
поставляемый
Normal file
|
@ -0,0 +1,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>
|
|
@ -0,0 +1,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>
|
410
3rdparty/scintilla/cocoa/ScintillaTest/ScintillaTest.xcodeproj/project.pbxproj
поставляемый
Normal file
|
@ -0,0 +1,410 @@
|
|||
// !$*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 = 0510;
|
||||
};
|
||||
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)";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
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 = macosx;
|
||||
USER_HEADER_SEARCH_PATHS = "";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
C01FCF4C08A954540054247B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
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 = macosx;
|
||||
USER_HEADER_SEARCH_PATHS = "";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
C01FCF4F08A954540054247B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = c99;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_LDFLAGS = "";
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
C01FCF5008A954540054247B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = c99;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
OTHER_LDFLAGS = "";
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
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 */;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
//
|
||||
// Prefix header for all source files of the 'ScintillaTest' target in the 'ScintillaTest' project
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
|
@ -0,0 +1,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 ;
|
||||
|
|
@ -0,0 +1,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);
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
|
||||
/**
|
||||
* 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 "Scintilla.h"
|
||||
#import "SciLexer.h"
|
||||
|
||||
#import "InfoBarCommunicator.h"
|
||||
|
||||
/**
|
||||
* Scintilla sends these two messages to the notify handler. Please refer
|
||||
* to the Windows API doc for details about the message format.
|
||||
*/
|
||||
#define WM_COMMAND 1001
|
||||
#define WM_NOTIFY 1002
|
||||
|
||||
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
|
||||
* ScintillaView registerNotifyCallback() to register such a handler.
|
||||
* Message format is:
|
||||
* <br>
|
||||
* WM_COMMAND: HIWORD (wParam) = notification code, LOWORD (wParam) = control ID, lParam = ScintillaCocoa*
|
||||
* <br>
|
||||
* WM_NOTIFY: wParam = 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);
|
||||
|
||||
class ScintillaCocoa;
|
||||
}
|
||||
|
||||
@class ScintillaView;
|
||||
|
||||
extern NSString *const SCIUpdateUINotification;
|
||||
|
||||
@protocol ScintillaNotificationProtocol
|
||||
- (void)notification: (Scintilla::SCNotification*)notification;
|
||||
@end
|
||||
|
||||
/**
|
||||
* SCIMarginView draws line numbers and other margins next to the text view.
|
||||
*/
|
||||
@interface SCIMarginView : NSRulerView
|
||||
{
|
||||
@private
|
||||
int marginWidth;
|
||||
ScintillaView *owner;
|
||||
NSMutableArray *currentCursors;
|
||||
}
|
||||
|
||||
@property (assign) int marginWidth;
|
||||
@property (assign) ScintillaView *owner;
|
||||
|
||||
- (id)initWithScrollView:(NSScrollView *)aScrollView;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* SCIContentView is the Cocoa interface to the Scintilla backend. It handles text input and
|
||||
* provides a canvas for painting the output.
|
||||
*/
|
||||
@interface SCIContentView : NSView <
|
||||
NSTextInputClient,
|
||||
NSUserInterfaceValidations,
|
||||
NSDraggingSource,
|
||||
NSDraggingDestination>
|
||||
{
|
||||
@private
|
||||
ScintillaView* mOwner;
|
||||
NSCursor* mCurrentCursor;
|
||||
NSTrackingArea *trackingArea;
|
||||
|
||||
// Set when we are in composition mode and partial input is displayed.
|
||||
NSRange mMarkedTextRange;
|
||||
}
|
||||
|
||||
@property (nonatomic, assign) ScintillaView* owner;
|
||||
|
||||
- (void) setCursor: (int) cursor;
|
||||
|
||||
- (BOOL) canUndo;
|
||||
- (BOOL) canRedo;
|
||||
|
||||
@end
|
||||
|
||||
@interface ScintillaView : NSView <InfoBarCommunicator, ScintillaNotificationProtocol>
|
||||
{
|
||||
@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.
|
||||
SCIContentView* mContent;
|
||||
|
||||
NSScrollView *scrollView;
|
||||
SCIMarginView *marginView;
|
||||
|
||||
CGFloat zoomDelta;
|
||||
|
||||
// Area to display additional controls (e.g. zoom info, caret position, status info).
|
||||
NSView <InfoBarCommunicator>* mInfoBar;
|
||||
BOOL mInfoBarAtTop;
|
||||
|
||||
id<ScintillaNotificationProtocol> mDelegate;
|
||||
}
|
||||
|
||||
@property (nonatomic, readonly) Scintilla::ScintillaCocoa* backend;
|
||||
@property (nonatomic, assign) id<ScintillaNotificationProtocol> delegate;
|
||||
@property (nonatomic, readonly) NSScrollView *scrollView;
|
||||
|
||||
+ (Class) contentViewClass;
|
||||
|
||||
- (void) notify: (NotificationType) type message: (NSString*) message location: (NSPoint) location
|
||||
value: (float) value;
|
||||
- (void) setCallback: (id <InfoBarCommunicator>) callback;
|
||||
|
||||
- (void) suspendDrawing: (BOOL) suspend;
|
||||
- (void) notification: (Scintilla::SCNotification*) notification;
|
||||
|
||||
// Scroller handling
|
||||
- (void) setMarginWidth: (int) width;
|
||||
- (SCIContentView*) content;
|
||||
- (void) updateMarginCursors;
|
||||
|
||||
// NSTextView compatibility layer.
|
||||
- (NSString*) string;
|
||||
- (void) setString: (NSString*) aString;
|
||||
- (void) insertText: (id) aString;
|
||||
- (void) setEditable: (BOOL) editable;
|
||||
- (BOOL) isEditable;
|
||||
- (NSRange) selectedRange;
|
||||
|
||||
- (NSString*) selectedString;
|
||||
|
||||
- (void) deleteRange: (NSRange) range;
|
||||
|
||||
- (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;
|
||||
- (sptr_t) message: (unsigned int) message wParam: (uptr_t) wParam lParam: (sptr_t) lParam;
|
||||
- (sptr_t) message: (unsigned int) message wParam: (uptr_t) wParam;
|
||||
- (sptr_t) message: (unsigned int) message;
|
||||
|
||||
// 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;
|
||||
|
||||
// The delegate property should be used instead of registerNotifyCallback which is deprecated.
|
||||
- (void) registerNotifyCallback: (intptr_t) windowid value: (Scintilla::SciNotifyFunc) callback __attribute__((deprecated));
|
||||
|
||||
- (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
|
|
@ -0,0 +1,66 @@
|
|||
# Script to build Scintilla for OS X with most supported build files.
|
||||
# Current directory should be scintilla/cocoa before running.
|
||||
|
||||
cd ../..
|
||||
|
||||
# ************************************************************
|
||||
# Target 1: Unit tests
|
||||
|
||||
echo Unit tests
|
||||
|
||||
cd scintilla/test/unit
|
||||
make clean
|
||||
make test
|
||||
cd ../../..
|
||||
|
||||
# ************************************************************
|
||||
# Target 2: build framework and test app with Xcode targetting OS X 10.n with n from 9 to 5
|
||||
# Only SDK versions that are installed will be built
|
||||
# Clean both then build both -- if perform clean in ScintillaTest, also cleans ScintillaFramework
|
||||
# which can cause double build
|
||||
|
||||
echo Building Cocoa-native ScintillaFramework and ScintillaTest
|
||||
for sdk in macosx10.9 macosx10.8 macosx10.7 macosx10.6 macosx10.5
|
||||
do
|
||||
xcodebuild -showsdks | grep $sdk
|
||||
if [ "$(xcodebuild -showsdks | grep $sdk)" != "" ]
|
||||
then
|
||||
echo Building with $sdk
|
||||
cd scintilla/cocoa/ScintillaFramework
|
||||
xcodebuild clean
|
||||
cd ../ScintillaTest
|
||||
xcodebuild clean
|
||||
cd ../ScintillaFramework
|
||||
xcodebuild -sdk $sdk
|
||||
cd ../ScintillaTest
|
||||
xcodebuild -sdk $sdk
|
||||
cd ../../..
|
||||
else
|
||||
echo Warning $sdk not available
|
||||
fi
|
||||
done
|
||||
|
||||
# ************************************************************
|
||||
# Target 3: Qt builds
|
||||
# Requires Qt development libraries and qmake to be installed
|
||||
|
||||
echo Building Qt and PySide
|
||||
|
||||
cd scintilla/qt
|
||||
cd ScintillaEditBase
|
||||
qmake -spec macx-xcode
|
||||
xcodebuild clean
|
||||
xcodebuild
|
||||
cd ..
|
||||
|
||||
cd ScintillaEdit
|
||||
python WidgetGen.py
|
||||
qmake -spec macx-xcode
|
||||
xcodebuild clean
|
||||
xcodebuild
|
||||
cd ..
|
||||
|
||||
cd ScintillaEditPy
|
||||
python sepbuild.py
|
||||
cd ..
|
||||
cd ../..
|
После Ширина: | Высота: | Размер: 3.0 KiB |
После Ширина: | Высота: | Размер: 5.2 KiB |
После Ширина: | Высота: | Размер: 4.4 KiB |
|
@ -0,0 +1,42 @@
|
|||
// File to suppress cppcheck warnings for files that will not be fixed.
|
||||
// Does not suppress warnings where an additional occurrence of the warning may be of interest.
|
||||
// Does not suppress false positives from cppcheck.
|
||||
|
||||
// Coding style is to use assignments in constructor when there are many
|
||||
// members to initialize or the initialization is complex or has comments.
|
||||
useInitializationList
|
||||
|
||||
// Suppress most lexer warnings since the lexers are maintained by others
|
||||
useInitializationList:scintilla/lexers/LexAsm.cxx
|
||||
useInitializationList:scintilla/lexers/LexBasic.cxx
|
||||
noCopyConstructor:scintilla/lexers/LexBash.cxx
|
||||
variableScope:scintilla/lexers/LexBash.cxx
|
||||
variableScope:scintilla/lexers/LexCmake.cxx
|
||||
variableScope:scintilla/lexers/LexCSS.cxx
|
||||
useInitializationList:scintilla/lexers/LexD.cxx
|
||||
variableScope:scintilla/lexers/LexErlang.cxx
|
||||
variableScope:scintilla/lexers/LexGui4Cli.cxx
|
||||
variableScope:scintilla/lexers/LexInno.cxx
|
||||
variableScope:scintilla/lexers/LexLaTeX.cxx
|
||||
variableScope:scintilla/lexers/LexMetapost.cxx
|
||||
variableScope:scintilla/lexers/LexModula.cxx
|
||||
variableScope:scintilla/lexers/LexNimrod.cxx
|
||||
variableScope:scintilla/lexers/LexNsis.cxx
|
||||
variableScope:scintilla/lexers/LexOpal.cxx
|
||||
variableScope:scintilla/lexers/LexOthers.cxx
|
||||
variableScope:scintilla/lexers/LexPB.cxx
|
||||
noCopyConstructor:scintilla/lexers/LexPerl.cxx
|
||||
variableScope:scintilla/lexers/LexRuby.cxx
|
||||
uninitMemberVar:scintilla/lexers/LexRuby.cxx
|
||||
variableScope:scintilla/lexers/LexSpecman.cxx
|
||||
unreadVariable:scintilla/lexers/LexSpice.cxx
|
||||
clarifyCalculation:scintilla/lexers/LexTADS3.cxx
|
||||
invalidscanf:scintilla/lexers/LexTCMD.cxx
|
||||
variableScope:scintilla/lexers/LexTeX.cxx
|
||||
variableScope:scintilla/lexers/LexVHDL.cxx
|
||||
|
||||
// Suppress C-style pointer casting for Qt code as won't be changing
|
||||
cstyleCast:scintilla/qt/ScintillaEdit/ScintillaDocument.cpp
|
||||
|
||||
// Suppress everything in catch.hpp as won't be changing
|
||||
*:scintilla/test/unit/catch.hpp
|
|
@ -0,0 +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:
|
|
@ -0,0 +1 @@
|
|||
del /S /Q .cvsignore
|
|
@ -0,0 +1,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>
|
||||
|
|
@ -0,0 +1,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>
|
После Ширина: | Высота: | Размер: 8.3 KiB |
|
@ -0,0 +1,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 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
|
После Ширина: | Высота: | Размер: 20 KiB |
После Ширина: | Высота: | Размер: 33 KiB |
|
@ -0,0 +1,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>
|
После Ширина: | Высота: | Размер: 16 KiB |
После Ширина: | Высота: | Размер: 9.9 KiB |
После Ширина: | Высота: | Размер: 6.0 KiB |
|
@ -0,0 +1,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/scintilla356.zip?download">
|
||||
Windows</a>
|
||||
<a href="http://prdownloads.sourceforge.net/scintilla/scintilla356.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.5.6
|
||||
</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/scintilla356.zip?download">zip format</a> (1450K) commonly used on Windows</li>
|
||||
<li><a href="http://prdownloads.sourceforge.net/scintilla/scintilla356.tgz?download">tgz format</a> (1300K) 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>
|
|
@ -0,0 +1,552 @@
|
|||
<?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://rhaberkorn.github.com/sciteco/">SciTECO</a>
|
||||
is an advanced TECO dialect and interactive screen editor based on Scintilla.
|
||||
</p>
|
||||
<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>
|
||||
|
|
@ -0,0 +1,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>
|
|
@ -0,0 +1,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>
|
||||
|
|
@ -0,0 +1,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>
|
||||
|
После Ширина: | Высота: | Размер: 33 KiB |
|
@ -0,0 +1,184 @@
|
|||
<?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="20150526" />
|
||||
<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,
|
||||
GTK+, and OS X</font>
|
||||
</td>
|
||||
<td width="40%" align="right">
|
||||
<font color="#FFCC99" size="3"> Release version 3.5.6<br />
|
||||
Site last modified May 26 2015</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.5.6 fixes a bug with undo on Cocoa that could lose data.</li>
|
||||
<li>Version 3.5.5 improves IME on Qt and fixes minor bugs.</li>
|
||||
<li>Version 3.5.4 improves indicators to be able to change appearance on mouse-over and to use a wide variety of colours together.</li>
|
||||
<li>Version 3.5.3 removes support for Windows 95, 98, and ME.</li>
|
||||
<li>Version 3.5.2 only supports 64-bit builds for OS X 10.7+ Cocoa. Provisional support of C++11 <regex>.</li>
|
||||
<li>Version 3.5.1 fixes minor bugs and includes a lexer for BibTeX.</li>
|
||||
<li>Version 3.5.0 can share space vertically so that extreme ascenders and descenders are not cut off.
|
||||
Separate timers are used to minimize wake ups and thus power use.</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, OS X, and Linux compatible operating
|
||||
systems with GTK+. They have been run on Windows XP, Windows 7, OS X 10.6+, 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="http://sourceforge.net/projects/scintilla/">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 20 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="http://sourceforge.net/projects/scintilla/">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>
|
||||
|
После Ширина: | Высота: | Размер: 17 KiB |
|
@ -0,0 +1,83 @@
|
|||
// 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.
|
||||
|
||||
#ifndef CONVERTER_H
|
||||
#define CONVERTER_H
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
namespace Scintilla {
|
||||
#endif
|
||||
|
||||
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];
|
||||
g_strlcpy(fullDest, charSetDestination, sizeof(fullDest));
|
||||
g_strlcat(fullDest, "//TRANSLIT", sizeof(fullDest));
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,538 @@
|
|||
PlatGTK.o: PlatGTK.cxx \
|
||||
../include/Scintilla.h ../include/ScintillaWidget.h \
|
||||
../lexlib/StringCopy.h ../src/XPM.h ../src/UniConversion.h Converter.h
|
||||
ScintillaGTK.o: ScintillaGTK.cxx \
|
||||
../include/ILexer.h ../include/Scintilla.h ../include/ScintillaWidget.h \
|
||||
../include/SciLexer.h ../lexlib/StringCopy.h ../lexlib/LexerModule.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/CharClassify.h \
|
||||
../src/Decoration.h ../src/CaseFolder.h ../src/Document.h \
|
||||
../src/CaseConvert.h ../src/UniConversion.h ../src/Selection.h \
|
||||
../src/PositionCache.h ../src/EditModel.h ../src/MarginView.h \
|
||||
../src/EditView.h ../src/Editor.h ../src/AutoComplete.h \
|
||||
../src/ScintillaBase.h ../src/ExternalLexer.h scintilla-marshal.h \
|
||||
Converter.h
|
||||
AutoComplete.o: ../src/AutoComplete.cxx ../include/Platform.h \
|
||||
../include/Scintilla.h ../lexlib/CharacterSet.h ../src/AutoComplete.h
|
||||
CallTip.o: ../src/CallTip.cxx ../include/Platform.h \
|
||||
../include/Scintilla.h ../lexlib/StringCopy.h ../src/CallTip.h
|
||||
CaseConvert.o: ../src/CaseConvert.cxx ../lexlib/StringCopy.h \
|
||||
../src/CaseConvert.h ../src/UniConversion.h ../src/UnicodeFromUTF8.h
|
||||
CaseFolder.o: ../src/CaseFolder.cxx ../src/CaseFolder.h \
|
||||
../src/CaseConvert.h ../src/UniConversion.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 ../lexlib/CharacterSet.h ../src/SplitVector.h \
|
||||
../src/Partitioning.h ../src/RunStyles.h ../src/CellBuffer.h \
|
||||
../src/PerLine.h ../src/CharClassify.h ../src/Decoration.h \
|
||||
../src/CaseFolder.h ../src/Document.h ../src/RESearch.h \
|
||||
../src/UniConversion.h
|
||||
EditModel.o: ../src/EditModel.cxx ../include/Platform.h \
|
||||
../include/ILexer.h ../include/Scintilla.h ../lexlib/StringCopy.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/CaseFolder.h ../src/Document.h ../src/UniConversion.h \
|
||||
../src/Selection.h ../src/PositionCache.h ../src/EditModel.h
|
||||
EditView.o: ../src/EditView.cxx ../include/Platform.h ../include/ILexer.h \
|
||||
../include/Scintilla.h ../lexlib/StringCopy.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/CaseFolder.h \
|
||||
../src/Document.h ../src/UniConversion.h ../src/Selection.h \
|
||||
../src/PositionCache.h ../src/EditModel.h ../src/MarginView.h \
|
||||
../src/EditView.h
|
||||
Editor.o: ../src/Editor.cxx ../include/Platform.h ../include/ILexer.h \
|
||||
../include/Scintilla.h ../lexlib/StringCopy.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/CaseFolder.h \
|
||||
../src/Document.h ../src/UniConversion.h ../src/Selection.h \
|
||||
../src/PositionCache.h ../src/EditModel.h ../src/MarginView.h \
|
||||
../src/EditView.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/Indicator.h ../src/XPM.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 ../lexlib/StringCopy.h ../src/XPM.h \
|
||||
../src/LineMarker.h
|
||||
MarginView.o: ../src/MarginView.cxx ../include/Platform.h \
|
||||
../include/ILexer.h ../include/Scintilla.h ../lexlib/StringCopy.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/CaseFolder.h ../src/Document.h ../src/UniConversion.h \
|
||||
../src/Selection.h ../src/PositionCache.h ../src/EditModel.h \
|
||||
../src/MarginView.h ../src/EditView.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/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/CaseFolder.h \
|
||||
../src/Document.h ../src/UniConversion.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 ../include/SciLexer.h \
|
||||
../lexlib/PropSetSimple.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/CharClassify.h \
|
||||
../src/Decoration.h ../src/CaseFolder.h ../src/Document.h \
|
||||
../src/Selection.h ../src/PositionCache.h ../src/EditModel.h \
|
||||
../src/MarginView.h ../src/EditView.h ../src/Editor.h \
|
||||
../src/AutoComplete.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
|
||||
CharacterCategory.o: ../lexlib/CharacterCategory.cxx \
|
||||
../lexlib/StringCopy.h ../lexlib/CharacterCategory.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
|
||||
LexerNoExceptions.o: ../lexlib/LexerNoExceptions.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/LexerNoExceptions.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/StringCopy.h \
|
||||
../lexlib/WordList.h
|
||||
LexA68k.o: ../lexers/LexA68k.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.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/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/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/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/WordList.h ../lexlib/LexAccessor.h \
|
||||
../lexlib/Accessor.h ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h
|
||||
LexAVS.o: ../lexers/LexAVS.cxx ../include/ILexer.h ../include/Scintilla.h \
|
||||
../include/SciLexer.h ../lexlib/WordList.h ../lexlib/LexAccessor.h \
|
||||
../lexlib/Accessor.h ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h
|
||||
LexAbaqus.o: ../lexers/LexAbaqus.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.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/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/WordList.h ../lexlib/LexAccessor.h \
|
||||
../lexlib/StyleContext.h ../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h ../lexlib/OptionSet.h
|
||||
LexAsn1.o: ../lexers/LexAsn1.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.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/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/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/WordList.h \
|
||||
../lexlib/LexAccessor.h ../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h ../lexlib/LexerModule.h ../lexlib/OptionSet.h
|
||||
LexBullant.o: ../lexers/LexBullant.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.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/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/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/WordList.h ../lexlib/LexAccessor.h \
|
||||
../lexlib/Accessor.h ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h ../lexlib/OptionSet.h ../lexlib/SparseState.h \
|
||||
../lexlib/SubStyles.h
|
||||
LexCSS.o: ../lexers/LexCSS.cxx ../include/ILexer.h ../include/Scintilla.h \
|
||||
../include/SciLexer.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
|
||||
LexCmake.o: ../lexers/LexCmake.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.h ../lexlib/WordList.h \
|
||||
../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h ../lexlib/LexerModule.h
|
||||
LexCoffeeScript.o: ../lexers/LexCoffeeScript.cxx ../include/Platform.h \
|
||||
../include/ILexer.h ../include/Scintilla.h ../include/SciLexer.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/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/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/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/WordList.h ../lexlib/LexAccessor.h \
|
||||
../lexlib/StyleContext.h ../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h ../lexlib/OptionSet.h
|
||||
LexDMAP.o: ../lexers/LexDMAP.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.h ../lexlib/WordList.h \
|
||||
../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h ../lexlib/LexerModule.h
|
||||
LexDMIS.o: ../lexers/LexDMIS.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.h ../lexlib/WordList.h \
|
||||
../lexlib/LexAccessor.h ../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h ../lexlib/LexerModule.h
|
||||
LexECL.o: ../lexers/LexECL.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/OptionSet.h
|
||||
LexEScript.o: ../lexers/LexEScript.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.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/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/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/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/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/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/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/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/StringCopy.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/CharacterCategory.h ../lexlib/LexerModule.h \
|
||||
../lexlib/OptionSet.h
|
||||
LexInno.o: ../lexers/LexInno.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.h ../lexlib/WordList.h \
|
||||
../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h ../lexlib/LexerModule.h
|
||||
LexKVIrc.o: ../lexers/LexKVIrc.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.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/WordList.h ../lexlib/LexAccessor.h \
|
||||
../lexlib/Accessor.h ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h
|
||||
LexLaTeX.o: ../lexers/LexLaTeX.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
|
||||
LexLisp.o: ../lexers/LexLisp.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.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/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/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/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/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/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/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/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/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/WordList.h \
|
||||
../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h ../lexlib/LexerModule.h
|
||||
LexModula.o: ../lexers/LexModula.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/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/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/WordList.h \
|
||||
../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h ../lexlib/LexerModule.h
|
||||
LexOScript.o: ../lexers/LexOScript.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.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/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/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/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/WordList.h ../lexlib/LexAccessor.h \
|
||||
../lexlib/Accessor.h ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h
|
||||
LexPO.o: ../lexers/LexPO.cxx ../include/ILexer.h ../include/Scintilla.h \
|
||||
../include/SciLexer.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/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/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/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/WordList.h \
|
||||
../lexlib/LexAccessor.h ../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h ../lexlib/LexerModule.h ../lexlib/OptionSet.h
|
||||
LexPowerPro.o: ../lexers/LexPowerPro.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.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/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/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/WordList.h \
|
||||
../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h ../lexlib/LexerModule.h
|
||||
LexR.o: ../lexers/LexR.cxx ../include/ILexer.h ../include/Scintilla.h \
|
||||
../include/SciLexer.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/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/WordList.h \
|
||||
../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h ../lexlib/LexerModule.h
|
||||
LexRust.o: ../lexers/LexRust.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/OptionSet.h
|
||||
LexSML.o: ../lexers/LexSML.cxx ../include/ILexer.h ../include/Scintilla.h \
|
||||
../include/SciLexer.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/WordList.h ../lexlib/LexAccessor.h \
|
||||
../lexlib/Accessor.h ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h ../lexlib/OptionSet.h ../lexlib/SparseState.h
|
||||
LexSTTXT.o: ../lexers/LexSTTXT.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.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/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/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/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/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/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/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/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/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/WordList.h ../lexlib/LexAccessor.h \
|
||||
../lexlib/Accessor.h ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h
|
||||
LexTCMD.o: ../lexers/LexTCMD.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.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/WordList.h ../lexlib/LexAccessor.h \
|
||||
../lexlib/Accessor.h ../lexlib/StyleContext.h ../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h
|
||||
LexTxt2tags.o: ../lexers/LexTxt2tags.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.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/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/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/WordList.h \
|
||||
../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h ../lexlib/LexerModule.h
|
||||
LexVisualProlog.o: ../lexers/LexVisualProlog.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.h ../lexlib/WordList.h \
|
||||
../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h ../lexlib/CharacterCategory.h \
|
||||
../lexlib/LexerModule.h ../lexlib/OptionSet.h
|
||||
LexYAML.o: ../lexers/LexYAML.cxx ../include/ILexer.h \
|
||||
../include/Scintilla.h ../include/SciLexer.h ../lexlib/WordList.h \
|
||||
../lexlib/LexAccessor.h ../lexlib/Accessor.h ../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h ../lexlib/LexerModule.h
|
|
@ -0,0 +1,106 @@
|
|||
# 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
|
||||
CXX = clang++ -Wno-deprecated-register
|
||||
CC = clang
|
||||
# Can choose aspect to sanitize: address and undefined can simply change SANITIZE but for
|
||||
# thread also need to create Position Independent Executable -> search online documentation
|
||||
SANITIZE = address
|
||||
#SANITIZE = undefined
|
||||
endif
|
||||
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 -pedantic -DGTK -DSCI_LEXER $(INCLUDEDIRS) $(DEPRECATED)
|
||||
|
||||
ifdef NOTHREADS
|
||||
THREADFLAGS=-DG_THREADS_IMPL_NONE
|
||||
else
|
||||
THREADFLAGS=
|
||||
endif
|
||||
|
||||
ifdef CXX11_REGEX
|
||||
REFLAGS=-DCXX11_REGEX
|
||||
endif
|
||||
|
||||
ifdef DEBUG
|
||||
ifdef CLANG
|
||||
CTFLAGS=-DDEBUG -g -fsanitize=$(SANITIZE) $(CXXBASEFLAGS) $(THREADFLAGS)
|
||||
else
|
||||
CTFLAGS=-DDEBUG -g $(CXXBASEFLAGS) $(THREADFLAGS)
|
||||
endif
|
||||
else
|
||||
CTFLAGS=-DNDEBUG -Os $(CXXBASEFLAGS) $(THREADFLAGS)
|
||||
endif
|
||||
|
||||
CFLAGS:=$(CTFLAGS)
|
||||
CXXTFLAGS:=--std=c++0x $(CTFLAGS) $(REFLAGS)
|
||||
|
||||
CONFIGFLAGS:=$(shell pkg-config --cflags $(GTKVERSION))
|
||||
MARSHALLER=scintilla-marshal.o
|
||||
|
||||
.cxx.o:
|
||||
$(CXX) $(CONFIGFLAGS) $(CXXTFLAGS) $(CXXFLAGS) -c $<
|
||||
.c.o:
|
||||
$(CC) $(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:
|
||||
$(CXX) -MM $(CONFIGFLAGS) $(CXXTFLAGS) *.cxx ../src/*.cxx ../lexlib/*.cxx ../lexers/*.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 CaseConvert.o CaseFolder.o \
|
||||
ScintillaBase.o ContractionState.o EditModel.o Editor.o EditView.o ExternalLexer.o MarginView.o \
|
||||
PropSetSimple.o PlatGTK.o \
|
||||
KeyMap.o LineMarker.o PositionCache.o ScintillaGTK.o CellBuffer.o CharacterCategory.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
|
|
@ -0,0 +1,105 @@
|
|||
# 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++
|
||||
CCOMP = clang
|
||||
# Can choose aspect to sanitize: address and undefined can simply change SANITIZE but for
|
||||
# thread also need to create Position Independent Executable -> search online documentation
|
||||
SANITIZE = address
|
||||
#SANITIZE = undefined
|
||||
else
|
||||
CC = g++ -mrecip
|
||||
CCOMP = gcc -mrecip
|
||||
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 -pedantic -DGTK -DSCI_LEXER $(INCLUDEDIRS) $(DEPRECATED)
|
||||
|
||||
ifdef NOTHREADS
|
||||
THREADFLAGS=-DG_THREADS_IMPL_NONE
|
||||
else
|
||||
THREADFLAGS=
|
||||
endif
|
||||
|
||||
ifdef DEBUG
|
||||
ifdef CLANG
|
||||
CTFLAGS=-DDEBUG -g -fsanitize=$(SANITIZE) $(CXXBASEFLAGS) $(THREADFLAGS)
|
||||
else
|
||||
CTFLAGS=-DDEBUG -g $(CXXBASEFLAGS) $(THREADFLAGS)
|
||||
endif
|
||||
else
|
||||
CTFLAGS=-DNDEBUG -Os $(CXXBASEFLAGS) $(THREADFLAGS)
|
||||
endif
|
||||
|
||||
CFLAGS:=$(CTFLAGS)
|
||||
CXXTFLAGS:=--std=c++0x $(CTFLAGS)
|
||||
|
||||
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 ../lexlib/*.cxx ../lexers/*.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 CaseConvert.o CaseFolder.o \
|
||||
ScintillaBase.o ContractionState.o Editor.o ExternalLexer.o PropSetSimple.o PlatGTK.o \
|
||||
KeyMap.o LineMarker.o PositionCache.o ScintillaGTK.o CellBuffer.o CharacterCategory.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
|
|
@ -0,0 +1,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);
|
||||
}
|
||||
|
|
@ -0,0 +1,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__ */
|
||||
|
|
@ -0,0 +1 @@
|
|||
NONE:INT,POINTER
|
|
@ -0,0 +1,98 @@
|
|||
// 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;
|
||||
};
|
||||
|
||||
class IDocumentWithLineEnd : public IDocument {
|
||||
public:
|
||||
virtual int SCI_METHOD LineEnd(int line) const = 0;
|
||||
virtual int SCI_METHOD GetRelativePosition(int positionStart, int characterOffset) const = 0;
|
||||
virtual int SCI_METHOD GetCharacterAndWidth(int position, int *pWidth) 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;
|
||||
};
|
||||
|
||||
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 int SCI_METHOD StyleFromSubStyle(int subStyle) = 0;
|
||||
virtual int SCI_METHOD PrimaryStyleFromStyle(int style) = 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;
|
||||
};
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,533 @@
|
|||
// 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_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
|
||||
// PLAT_TK = Tcl/TK on Linux or Win32
|
||||
|
||||
#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_CURSES 0
|
||||
#define PLAT_TK 0
|
||||
|
||||
#if defined(FOX)
|
||||
#undef PLAT_FOX
|
||||
#define PLAT_FOX 1
|
||||
|
||||
#elif defined(__WX__)
|
||||
#undef PLAT_WX
|
||||
#define PLAT_WX 1
|
||||
|
||||
#elif defined(CURSES)
|
||||
#undef PLAT_CURSES
|
||||
#define PLAT_CURSES 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
|
||||
|
||||
typedef float XYPOSITION;
|
||||
typedef double XYACCUMULATOR;
|
||||
inline int RoundXYPosition(XYPOSITION xyPos) {
|
||||
return int(xyPos + 0.5);
|
||||
}
|
||||
|
||||
// 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 similar to the Win32 POINT and GTK+ GdkPoint types.
|
||||
*/
|
||||
class Point {
|
||||
public:
|
||||
XYPOSITION x;
|
||||
XYPOSITION y;
|
||||
|
||||
explicit Point(XYPOSITION x_=0, XYPOSITION y_=0) : x(x_), y(y_) {
|
||||
}
|
||||
|
||||
static Point FromInts(int x_, int y_) {
|
||||
return Point(static_cast<XYPOSITION>(x_), static_cast<XYPOSITION>(y_));
|
||||
}
|
||||
|
||||
// Other automatically defined methods (assignment, copy constructor, destructor) are fine
|
||||
|
||||
static Point FromLong(long lpoint);
|
||||
};
|
||||
|
||||
/**
|
||||
* A geometric rectangle class.
|
||||
* PRectangle is similar to the Win32 RECT.
|
||||
* 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;
|
||||
|
||||
explicit PRectangle(XYPOSITION left_=0, XYPOSITION top_=0, XYPOSITION right_=0, XYPOSITION bottom_ = 0) :
|
||||
left(left_), top(top_), right(right_), bottom(bottom_) {
|
||||
}
|
||||
|
||||
static PRectangle FromInts(int left_, int top_, int right_, int bottom_) {
|
||||
return PRectangle(static_cast<XYPOSITION>(left_), static_cast<XYPOSITION>(top_),
|
||||
static_cast<XYPOSITION>(right_), static_cast<XYPOSITION>(bottom_));
|
||||
}
|
||||
|
||||
// Other automatically defined methods (assignment, copy constructor, destructor) are fine
|
||||
|
||||
bool operator==(PRectangle &rc) const {
|
||||
return (rc.left == left) && (rc.right == right) &&
|
||||
(rc.top == top) && (rc.bottom == bottom);
|
||||
}
|
||||
bool Contains(Point pt) const {
|
||||
return (pt.x >= left) && (pt.x <= right) &&
|
||||
(pt.y >= top) && (pt.y <= bottom);
|
||||
}
|
||||
bool ContainsWholePixel(Point pt) const {
|
||||
// Does the rectangle contain all of the pixel to left/below the point
|
||||
return (pt.x >= left) && ((pt.x+1) <= right) &&
|
||||
(pt.y >= top) && ((pt.y+1) <= bottom);
|
||||
}
|
||||
bool Contains(PRectangle rc) const {
|
||||
return (rc.left >= left) && (rc.right <= right) &&
|
||||
(rc.top >= top) && (rc.bottom <= bottom);
|
||||
}
|
||||
bool Intersects(PRectangle other) const {
|
||||
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() const { return right - left; }
|
||||
XYPOSITION Height() const { return bottom - top; }
|
||||
bool Empty() const {
|
||||
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() const {
|
||||
return co & 0xff;
|
||||
}
|
||||
|
||||
unsigned int GetGreen() const {
|
||||
return (co >> 8) & 0xff;
|
||||
}
|
||||
|
||||
unsigned int GetBlue() const {
|
||||
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;
|
||||
// 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_; }
|
||||
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;
|
||||
public:
|
||||
Window() : wid(0), cursorLast(cursorInvalid) {
|
||||
}
|
||||
Window(const Window &source) : wid(source.wid), cursorLast(cursorInvalid) {
|
||||
}
|
||||
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);
|
||||
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);
|
||||
};
|
||||
|
||||
#if defined(__clang__)
|
||||
# if __has_feature(attribute_analyzer_noreturn)
|
||||
# define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
|
||||
# else
|
||||
# define CLANG_ANALYZER_NORETURN
|
||||
# endif
|
||||
#else
|
||||
# define CLANG_ANALYZER_NORETURN
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 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) CLANG_ANALYZER_NORETURN;
|
||||
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
|
||||
|
||||
#if defined(__GNUC__) && defined(SCINTILLA_QT)
|
||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,51 @@
|
|||
/* 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
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,347 @@
|
|||
// 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)
|
||||
{
|
||||
// Used to buffer a string, to be able to compare it using built-in functions
|
||||
char Buffer[100];
|
||||
|
||||
|
||||
// Used to know the length of an operator
|
||||
int OpType;
|
||||
|
||||
|
||||
// Get references to keywords lists
|
||||
WordList &cpuInstruction = *keywordlists[0];
|
||||
WordList ®isters = *keywordlists[1];
|
||||
WordList &directive = *keywordlists[2];
|
||||
WordList &extInstruction = *keywordlists[3];
|
||||
WordList &alert = *keywordlists[4];
|
||||
WordList &doxygenKeyword = *keywordlists[5];
|
||||
|
||||
|
||||
// Instanciate a context for our source
|
||||
StyleContext sc(startPos, length, initStyle, styler);
|
||||
|
||||
|
||||
/************************************************************
|
||||
*
|
||||
* Parse the source
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
for ( ; sc.More(); sc.Forward())
|
||||
{
|
||||
/************************************************************
|
||||
*
|
||||
* A style always terminates at the end of a line, even for
|
||||
* comments (no multi-lines comments)
|
||||
*
|
||||
************************************************************/
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_A68K_DEFAULT);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************
|
||||
*
|
||||
* If we are not in "default style", check if the style continues
|
||||
* In this case, we just have to loop
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
if (sc.state != SCE_A68K_DEFAULT)
|
||||
{
|
||||
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)) // Macro argument
|
||||
|| ((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_DECLARATION) && IsIdentifierChar(sc.ch)) // Macro declaration (or global label, we don't know at this point)
|
||||
|| ((sc.state == SCE_A68K_IDENTIFIER) && IsIdentifierChar(sc.ch)) // Identifier
|
||||
|| ((sc.state == SCE_A68K_LABEL) && IsIdentifierChar(sc.ch)) // Label (local)
|
||||
|| ((sc.state == SCE_A68K_COMMENT_DOXYGEN) && IsDoxygenChar(sc.ch)) // Doxygen keyword
|
||||
|| ((sc.state == SCE_A68K_COMMENT_SPECIAL) && isalpha(sc.ch)) // Alert
|
||||
|| ((sc.state == SCE_A68K_COMMENT) && !isalpha(sc.ch) && (sc.ch != '\\'))) // Normal comment
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
*
|
||||
* Check if current state terminates
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
// Strings: include terminal ' or " in the current string by skipping it
|
||||
if ((sc.state == SCE_A68K_STRING1) || (sc.state == SCE_A68K_STRING2)) {
|
||||
sc.Forward();
|
||||
}
|
||||
|
||||
|
||||
// If a macro declaration was terminated with ':', it was a label
|
||||
else if ((sc.state == SCE_A68K_MACRO_DECLARATION) && (sc.chPrev == ':')) {
|
||||
sc.ChangeState(SCE_A68K_LABEL);
|
||||
}
|
||||
|
||||
|
||||
// If it wasn't a Doxygen keyword, change it to normal comment
|
||||
else if (sc.state == SCE_A68K_COMMENT_DOXYGEN) {
|
||||
sc.GetCurrent(Buffer, sizeof(Buffer));
|
||||
if (!doxygenKeyword.InList(Buffer)) {
|
||||
sc.ChangeState(SCE_A68K_COMMENT);
|
||||
}
|
||||
sc.SetState(SCE_A68K_COMMENT);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// If it wasn't an Alert, change it to normal comment
|
||||
else if (sc.state == SCE_A68K_COMMENT_SPECIAL) {
|
||||
sc.GetCurrent(Buffer, sizeof(Buffer));
|
||||
if (!alert.InList(Buffer)) {
|
||||
sc.ChangeState(SCE_A68K_COMMENT);
|
||||
}
|
||||
// Reset style to normal comment, or to Doxygen keyword if it begins with '\'
|
||||
if (sc.ch == '\\') {
|
||||
sc.SetState(SCE_A68K_COMMENT_DOXYGEN);
|
||||
}
|
||||
else {
|
||||
sc.SetState(SCE_A68K_COMMENT);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// If we are in a comment, it's a Doxygen keyword or an Alert
|
||||
else if (sc.state == SCE_A68K_COMMENT) {
|
||||
if (sc.ch == '\\') {
|
||||
sc.SetState(SCE_A68K_COMMENT_DOXYGEN);
|
||||
}
|
||||
else {
|
||||
sc.SetState(SCE_A68K_COMMENT_SPECIAL);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
// Something which begins at the beginning of a line, and with
|
||||
// - '\' + an identifier start char, or
|
||||
// - '\\@' + an identifier start char
|
||||
// is a local label (second case is used for macro local labels). We set it already as a label, it can't be a macro/equ declaration
|
||||
if (sc.atLineStart && (sc.ch < 0x80) && IsIdentifierStart(sc.chNext) && (sc.ch == '\\')) {
|
||||
sc.SetState(SCE_A68K_LABEL);
|
||||
}
|
||||
|
||||
if (sc.atLineStart && (sc.ch < 0x80) && (sc.ch == '\\') && (sc.chNext == '\\')) {
|
||||
sc.Forward(2);
|
||||
if ((sc.ch == '@') && IsIdentifierStart(sc.chNext)) {
|
||||
sc.ChangeState(SCE_A68K_LABEL);
|
||||
sc.SetState(SCE_A68K_LABEL);
|
||||
}
|
||||
}
|
||||
|
||||
// Label and macro identifiers start at the beginning of a line
|
||||
// We set both as a macro id, but if it wasn't one (':' at the end),
|
||||
// it will be changed as a label.
|
||||
if (sc.atLineStart && (sc.ch < 0x80) && IsIdentifierStart(sc.ch)) {
|
||||
sc.SetState(SCE_A68K_MACRO_DECLARATION);
|
||||
}
|
||||
else if ((sc.ch < 0x80) && (sc.ch == ';')) { // Default: alert in a comment. If it doesn't match
|
||||
sc.SetState(SCE_A68K_COMMENT); // with an alert, it will be toggle to a normal 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 are prefixed with '\'
|
||||
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);
|
|
@ -0,0 +1,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);
|
|
@ -0,0 +1,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);
|
|
@ -0,0 +1,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);
|
|
@ -0,0 +1,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);
|
||||
|
|
@ -0,0 +1,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);
|
|
@ -0,0 +1,605 @@
|
|||
// 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 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 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);
|
|
@ -0,0 +1,515 @@
|
|||
// 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 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 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 == '_';
|
||||
}
|
|
@ -0,0 +1,467 @@
|
|||
// 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;
|
||||
int commentChar;
|
||||
public:
|
||||
LexerAsm(int commentChar_) {
|
||||
commentChar = commentChar_;
|
||||
}
|
||||
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(';');
|
||||
}
|
||||
|
||||
static ILexer *LexerFactoryAs() {
|
||||
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 == commentChar){
|
||||
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);
|
||||
LexerModule lmAs(SCLEX_AS, LexerAsm::LexerFactoryAs, "as", asmWordListDesc);
|
||||
|
|
@ -0,0 +1,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 lmAsn1(SCLEX_ASN1, ColouriseAsn1Doc, "asn1", FoldAsn1Doc, asn1WordLists);
|
|
@ -0,0 +1,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);
|
|
@ -0,0 +1,845 @@
|
|||
// 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 setMetaCharacter(CharacterSet::setNone, "|&;()<> \t\r\n");
|
||||
setMetaCharacter.Add(0);
|
||||
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 (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 single quoted, there's no escape
|
||||
// * if double quoted, there are \\ and \" escapes
|
||||
if ((HereDoc.Quote == '\'' && sc.ch != HereDoc.Quote) ||
|
||||
(HereDoc.Quoted && sc.ch != HereDoc.Quote && sc.ch != '\\') ||
|
||||
(HereDoc.Quote != '\'' && sc.chPrev == '\\') ||
|
||||
(setHereDoc2.Contains(sc.ch))) {
|
||||
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 == '\\') {
|
||||
if (HereDoc.Quoted && sc.chNext != HereDoc.Quote && sc.chNext != '\\') {
|
||||
// in quoted prefixes only \ and the quote eat the escape
|
||||
HereDoc.Append(sc.ch);
|
||||
} else {
|
||||
// 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 (sc.ch == '\t' && !sc.atLineEnd) { // tabulation 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.Indent) &&
|
||||
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 == '#') {
|
||||
if (stylePrev != SCE_SH_WORD && stylePrev != SCE_SH_IDENTIFIER &&
|
||||
(sc.currentPos == 0 || setMetaCharacter.Contains(sc.chPrev))) {
|
||||
sc.SetState(SCE_SH_COMMENTLINE);
|
||||
} else {
|
||||
sc.SetState(SCE_SH_WORD);
|
||||
}
|
||||
} 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;
|
||||
if (sc.GetRelative(2) == '-') { // <<- indent case
|
||||
HereDoc.Indent = true;
|
||||
sc.Forward();
|
||||
} else {
|
||||
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 skipHereCh = 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 == '<') {
|
||||
if (styler.SafeGetCharAt(i + 2) == '<') {
|
||||
skipHereCh = 1;
|
||||
} else {
|
||||
if (skipHereCh == 0) {
|
||||
levelCurrent++;
|
||||
} else {
|
||||
skipHereCh = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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);
|
|
@ -0,0 +1,566 @@
|
|||
// 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
|
||||
* 64 - letter
|
||||
*/
|
||||
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, 84, 84, 84, 84, 84, 84, 68, 68, 68, 68, 68, 68, 68, 68, 68,
|
||||
68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 2, 2, 2, 2, 68,
|
||||
2, 84, 84, 84, 84, 84, 84, 68, 68, 68, 68, 68, 68, 68, 68, 68,
|
||||
68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 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 bool IsLetter(int c) {
|
||||
return c < 128 && (character_classification[c] & 64);
|
||||
}
|
||||
|
||||
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, "enum") ||
|
||||
!strcmp(token, "type") ||
|
||||
!strcmp(token, "union") ||
|
||||
!strcmp(token, "property") ||
|
||||
!strcmp(token, "destructor") ||
|
||||
!strcmp(token, "constructor")) {
|
||||
level |= SC_FOLDLEVELHEADERFLAG;
|
||||
return 1;
|
||||
}
|
||||
if (!strcmp(token, "end function") ||
|
||||
!strcmp(token, "end sub") ||
|
||||
!strcmp(token, "end enum") ||
|
||||
!strcmp(token, "end type") ||
|
||||
!strcmp(token, "end union") ||
|
||||
!strcmp(token, "end property") ||
|
||||
!strcmp(token, "end destructor") ||
|
||||
!strcmp(token, "end constructor")) {
|
||||
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);
|
||||
int styleBeforeKeyword = SCE_B_DEFAULT;
|
||||
|
||||
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);
|
||||
}
|
||||
} else if (sc.state == SCE_B_DOCLINE) {
|
||||
if (sc.atLineEnd) {
|
||||
sc.SetState(SCE_B_DEFAULT);
|
||||
} else if (sc.ch == '\\' || sc.ch == '@') {
|
||||
if (IsLetter(sc.chNext) && sc.chPrev != '\\') {
|
||||
styleBeforeKeyword = sc.state;
|
||||
sc.SetState(SCE_B_DOCKEYWORD);
|
||||
};
|
||||
}
|
||||
} else if (sc.state == SCE_B_DOCKEYWORD) {
|
||||
if (IsSpace(sc.ch)) {
|
||||
sc.SetState(styleBeforeKeyword);
|
||||
} else if (sc.atLineEnd && styleBeforeKeyword == SCE_B_DOCLINE) {
|
||||
sc.SetState(SCE_B_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_B_COMMENTBLOCK) {
|
||||
if (sc.Match("\'/")) {
|
||||
sc.Forward();
|
||||
sc.ForwardSetState(SCE_B_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_B_DOCBLOCK) {
|
||||
if (sc.Match("\'/")) {
|
||||
sc.Forward();
|
||||
sc.ForwardSetState(SCE_B_DEFAULT);
|
||||
} else if (sc.ch == '\\' || sc.ch == '@') {
|
||||
if (IsLetter(sc.chNext) && sc.chPrev != '\\') {
|
||||
styleBeforeKeyword = sc.state;
|
||||
sc.SetState(SCE_B_DOCKEYWORD);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (sc.atLineStart)
|
||||
isfirst = true;
|
||||
|
||||
if (sc.state == SCE_B_DEFAULT || sc.state == SCE_B_ERROR) {
|
||||
if (isfirst && sc.Match('.') && comment_char != '\'') {
|
||||
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 if (sc.Match("\'*") || sc.Match("\'!")) {
|
||||
sc.SetState(SCE_B_DOCLINE);
|
||||
} else {
|
||||
sc.SetState(SCE_B_COMMENT);
|
||||
}
|
||||
} else if (sc.Match("/\'")) {
|
||||
if (sc.Match("/\'*") || sc.Match("/\'!")) { // Support of gtk-doc/Doxygen doc. style
|
||||
sc.SetState(SCE_B_DOCBLOCK);
|
||||
} else {
|
||||
sc.SetState(SCE_B_COMMENTBLOCK);
|
||||
}
|
||||
sc.Forward(); // Eat the ' so it isn't used for the end of the 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.Match("&h") || sc.Match("&H") || sc.Match("&o") || sc.Match("&O")) {
|
||||
sc.SetState(SCE_B_HEXNUMBER);
|
||||
} else if (sc.Match('%') || sc.Match("&b") || sc.Match("&B")) {
|
||||
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);
|
|
@ -0,0 +1,310 @@
|
|||
// Copyright 2008-2010 Sergiu Dotenco. The License.txt file describes the
|
||||
// conditions under which this software may be distributed.
|
||||
|
||||
/**
|
||||
* @file LexBibTeX.cxx
|
||||
* @brief General BibTeX coloring scheme.
|
||||
* @author Sergiu Dotenco
|
||||
* @date April 18, 2009
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
#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
|
||||
|
||||
namespace {
|
||||
bool IsAlphabetic(unsigned int ch)
|
||||
{
|
||||
return IsASCII(ch) && std::isalpha(ch) != 0;
|
||||
}
|
||||
bool IsAlphaNumeric(char ch)
|
||||
{
|
||||
return IsASCII(ch) && std::isalnum(ch);
|
||||
}
|
||||
|
||||
bool EqualCaseInsensitive(const char* a, const char* b)
|
||||
{
|
||||
return CompareCaseInsensitive(a, b) == 0;
|
||||
}
|
||||
|
||||
bool EntryWithoutKey(const char* name)
|
||||
{
|
||||
return EqualCaseInsensitive(name,"string");
|
||||
}
|
||||
|
||||
char GetClosingBrace(char openbrace)
|
||||
{
|
||||
char result = openbrace;
|
||||
|
||||
switch (openbrace) {
|
||||
case '(': result = ')'; break;
|
||||
case '{': result = '}'; break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IsEntryStart(char prev, char ch)
|
||||
{
|
||||
return prev != '\\' && ch == '@';
|
||||
}
|
||||
|
||||
bool IsEntryStart(const StyleContext& sc)
|
||||
{
|
||||
return IsEntryStart(sc.chPrev, sc.ch);
|
||||
}
|
||||
|
||||
void ColorizeBibTeX(unsigned start_pos, int length, int /*init_style*/, WordList* keywordlists[], Accessor& styler)
|
||||
{
|
||||
WordList &EntryNames = *keywordlists[0];
|
||||
bool fold_compact = styler.GetPropertyInt("fold.compact", 1) != 0;
|
||||
|
||||
std::string buffer;
|
||||
buffer.reserve(25);
|
||||
|
||||
// We always colorize a section from the beginning, so let's
|
||||
// search for the @ character which isn't escaped, i.e. \@
|
||||
while (start_pos > 0 && !IsEntryStart(styler.SafeGetCharAt(start_pos - 1),
|
||||
styler.SafeGetCharAt(start_pos))) {
|
||||
--start_pos; ++length;
|
||||
}
|
||||
|
||||
styler.StartAt(start_pos);
|
||||
styler.StartSegment(start_pos);
|
||||
|
||||
int current_line = styler.GetLine(start_pos);
|
||||
int prev_level = styler.LevelAt(current_line) & SC_FOLDLEVELNUMBERMASK;
|
||||
int current_level = prev_level;
|
||||
int visible_chars = 0;
|
||||
|
||||
bool in_comment = false ;
|
||||
StyleContext sc(start_pos, length, SCE_BIBTEX_DEFAULT, styler);
|
||||
|
||||
bool going = sc.More(); // needed because of a fuzzy end of file state
|
||||
char closing_brace = 0;
|
||||
bool collect_entry_name = false;
|
||||
|
||||
for (; going; sc.Forward()) {
|
||||
if (!sc.More())
|
||||
going = false; // we need to go one behind the end of text
|
||||
|
||||
if (in_comment) {
|
||||
if (sc.atLineEnd) {
|
||||
sc.SetState(SCE_BIBTEX_DEFAULT);
|
||||
in_comment = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Found @entry
|
||||
if (IsEntryStart(sc)) {
|
||||
sc.SetState(SCE_BIBTEX_UNKNOWN_ENTRY);
|
||||
sc.Forward();
|
||||
++current_level;
|
||||
|
||||
buffer.clear();
|
||||
collect_entry_name = true;
|
||||
}
|
||||
else if ((sc.state == SCE_BIBTEX_ENTRY || sc.state == SCE_BIBTEX_UNKNOWN_ENTRY)
|
||||
&& (sc.ch == '{' || sc.ch == '(')) {
|
||||
// Entry name colorization done
|
||||
// Found either a { or a ( after entry's name, e.g. @entry(...) @entry{...}
|
||||
// Closing counterpart needs to be stored.
|
||||
closing_brace = GetClosingBrace(sc.ch);
|
||||
|
||||
sc.SetState(SCE_BIBTEX_DEFAULT); // Don't colorize { (
|
||||
|
||||
// @string doesn't have any key
|
||||
if (EntryWithoutKey(buffer.c_str()))
|
||||
sc.ForwardSetState(SCE_BIBTEX_PARAMETER);
|
||||
else
|
||||
sc.ForwardSetState(SCE_BIBTEX_KEY); // Key/label colorization
|
||||
}
|
||||
|
||||
// Need to handle the case where entry's key is empty
|
||||
// e.g. @book{,...}
|
||||
if (sc.state == SCE_BIBTEX_KEY && sc.ch == ',') {
|
||||
// Key/label colorization done
|
||||
sc.SetState(SCE_BIBTEX_DEFAULT); // Don't colorize the ,
|
||||
sc.ForwardSetState(SCE_BIBTEX_PARAMETER); // Parameter colorization
|
||||
}
|
||||
else if (sc.state == SCE_BIBTEX_PARAMETER && sc.ch == '=') {
|
||||
sc.SetState(SCE_BIBTEX_DEFAULT); // Don't colorize the =
|
||||
sc.ForwardSetState(SCE_BIBTEX_VALUE); // Parameter value colorization
|
||||
|
||||
int start = sc.currentPos;
|
||||
|
||||
// We need to handle multiple situations:
|
||||
// 1. name"one two {three}"
|
||||
// 2. name={one {one two {two}} three}
|
||||
// 3. year=2005
|
||||
|
||||
// Skip ", { until we encounter the first alphanumerical character
|
||||
while (sc.More() && !(IsAlphaNumeric(sc.ch) || sc.ch == '"' || sc.ch == '{'))
|
||||
sc.Forward();
|
||||
|
||||
if (sc.More()) {
|
||||
// Store " or {
|
||||
char ch = sc.ch;
|
||||
|
||||
// Not interested in alphanumerical characters
|
||||
if (IsAlphaNumeric(ch))
|
||||
ch = 0;
|
||||
|
||||
int skipped = 0;
|
||||
|
||||
if (ch) {
|
||||
// Skip preceding " or { such as in name={{test}}.
|
||||
// Remember how many characters have been skipped
|
||||
// Make sure that empty values, i.e. "" are also handled correctly
|
||||
while (sc.More() && (sc.ch == ch && (ch != '"' || skipped < 1))) {
|
||||
sc.Forward();
|
||||
++skipped;
|
||||
}
|
||||
}
|
||||
|
||||
// Closing counterpart for " is the same character
|
||||
if (ch == '{')
|
||||
ch = '}';
|
||||
|
||||
// We have reached the parameter value
|
||||
// In case the open character was a alnum char, skip until , is found
|
||||
// otherwise until skipped == 0
|
||||
while (sc.More() && (skipped > 0 || (!ch && !(sc.ch == ',' || sc.ch == closing_brace)))) {
|
||||
// Make sure the character isn't escaped
|
||||
if (sc.chPrev != '\\') {
|
||||
// Parameter value contains a { which is the 2nd case described above
|
||||
if (sc.ch == '{')
|
||||
++skipped; // Remember it
|
||||
else if (sc.ch == '}')
|
||||
--skipped;
|
||||
else if (skipped == 1 && sc.ch == ch && ch == '"') // Don't ignore cases like {"o}
|
||||
skipped = 0;
|
||||
}
|
||||
|
||||
sc.Forward();
|
||||
}
|
||||
}
|
||||
|
||||
// Don't colorize the ,
|
||||
sc.SetState(SCE_BIBTEX_DEFAULT);
|
||||
|
||||
// Skip until the , or entry's closing closing_brace is found
|
||||
// since this parameter might be the last one
|
||||
while (sc.More() && !(sc.ch == ',' || sc.ch == closing_brace))
|
||||
sc.Forward();
|
||||
|
||||
int state = SCE_BIBTEX_PARAMETER; // The might be more parameters
|
||||
|
||||
// We've reached the closing closing_brace for the bib entry
|
||||
// in case no " or {} has been used to enclose the value,
|
||||
// as in 3rd case described above
|
||||
if (sc.ch == closing_brace) {
|
||||
--current_level;
|
||||
// Make sure the text between entries is not colored
|
||||
// using parameter's style
|
||||
state = SCE_BIBTEX_DEFAULT;
|
||||
}
|
||||
|
||||
int end = sc.currentPos;
|
||||
current_line = styler.GetLine(end);
|
||||
|
||||
// We have possibly skipped some lines, so the folding levels
|
||||
// have to be adjusted separately
|
||||
for (int i = styler.GetLine(start); i <= styler.GetLine(end); ++i)
|
||||
styler.SetLevel(i, prev_level);
|
||||
|
||||
sc.ForwardSetState(state);
|
||||
}
|
||||
|
||||
if (sc.state == SCE_BIBTEX_PARAMETER && sc.ch == closing_brace) {
|
||||
sc.SetState(SCE_BIBTEX_DEFAULT);
|
||||
--current_level;
|
||||
}
|
||||
|
||||
// Non escaped % found which represents a comment until the end of the line
|
||||
if (sc.chPrev != '\\' && sc.ch == '%') {
|
||||
in_comment = true;
|
||||
sc.SetState(SCE_BIBTEX_COMMENT);
|
||||
}
|
||||
}
|
||||
|
||||
if (sc.state == SCE_BIBTEX_UNKNOWN_ENTRY || sc.state == SCE_BIBTEX_ENTRY) {
|
||||
if (!IsAlphabetic(sc.ch) && collect_entry_name)
|
||||
collect_entry_name = false;
|
||||
|
||||
if (collect_entry_name) {
|
||||
buffer += static_cast<char>(tolower(sc.ch));
|
||||
if (EntryNames.InList(buffer.c_str()))
|
||||
sc.ChangeState(SCE_BIBTEX_ENTRY);
|
||||
else
|
||||
sc.ChangeState(SCE_BIBTEX_UNKNOWN_ENTRY);
|
||||
}
|
||||
}
|
||||
|
||||
if (sc.atLineEnd) {
|
||||
int level = prev_level;
|
||||
|
||||
if (visible_chars == 0 && fold_compact)
|
||||
level |= SC_FOLDLEVELWHITEFLAG;
|
||||
|
||||
if ((current_level > prev_level))
|
||||
level |= SC_FOLDLEVELHEADERFLAG;
|
||||
// else if (current_level < prev_level)
|
||||
// level |= SC_FOLDLEVELBOXFOOTERFLAG; // Deprecated
|
||||
|
||||
if (level != styler.LevelAt(current_line)) {
|
||||
styler.SetLevel(current_line, level);
|
||||
}
|
||||
|
||||
++current_line;
|
||||
prev_level = current_level;
|
||||
visible_chars = 0;
|
||||
}
|
||||
|
||||
if (!isspacechar(sc.ch))
|
||||
++visible_chars;
|
||||
}
|
||||
|
||||
sc.Complete();
|
||||
|
||||
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
|
||||
int flagsNext = styler.LevelAt(current_line) & ~SC_FOLDLEVELNUMBERMASK;
|
||||
styler.SetLevel(current_line, prev_level | flagsNext);
|
||||
}
|
||||
}
|
||||
static const char * const BibTeXWordLists[] = {
|
||||
"Entry Names",
|
||||
0,
|
||||
};
|
||||
|
||||
|
||||
LexerModule lmBibTeX(SCLEX_BIBTEX, ColorizeBibTeX, "bib", 0, BibTeXWordLists);
|
||||
|
||||
// Entry Names
|
||||
// article, book, booklet, conference, inbook,
|
||||
// incollection, inproceedings, manual, mastersthesis,
|
||||
// misc, phdthesis, proceedings, techreport, unpublished,
|
||||
// string, url
|
||||
|
|
@ -0,0 +1,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);
|
|
@ -0,0 +1,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);
|
|
@ -0,0 +1,381 @@
|
|||
// 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];
|
||||
s[0] = '\0';
|
||||
s[1] = '\0';
|
||||
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);
|
|
@ -0,0 +1,567 @@
|
|||
// Scintilla source code edit control
|
||||
/** @file LexCSS.cxx
|
||||
** Lexer for Cascading Style Sheets
|
||||
** Written by Jakub Vrána
|
||||
** 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);
|
|
@ -0,0 +1,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 */
|
|
@ -0,0 +1,457 @@
|
|||
// 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 ( cCurrChar == '\n' || cCurrChar == '\r' ) {
|
||||
if ( styler.SafeGetCharAt(i-1) == '\\' ) {
|
||||
styler.ColourTo(i-2,state);
|
||||
styler.ColourTo(i-1,SCE_CMAKE_DEFAULT);
|
||||
}
|
||||
else {
|
||||
styler.ColourTo(i-1,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_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);
|
|
@ -0,0 +1,415 @@
|
|||
// 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_COFFEESCRIPT_DEFAULT
|
||||
|| state == SCE_COFFEESCRIPT_COMMENTLINE
|
||||
|| state == SCE_COFFEESCRIPT_COMMENTBLOCK
|
||||
|| state == SCE_COFFEESCRIPT_VERBOSE_REGEX
|
||||
|| state == SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT
|
||||
|| state == SCE_COFFEESCRIPT_WORD
|
||||
|| state == SCE_COFFEESCRIPT_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);
|
||||
while (--pos > lineStartPos) {
|
||||
char 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 &keywords4 = *keywordlists[3];
|
||||
|
||||
CharacterSet setOKBeforeRE(CharacterSet::setNone, "([{=,:;!%^&*|?~+-");
|
||||
CharacterSet setCouldBePostOp(CharacterSet::setNone, "+-");
|
||||
|
||||
CharacterSet setWordStart(CharacterSet::setAlpha, "_$@", 0x80, true);
|
||||
CharacterSet setWord(CharacterSet::setAlphaNum, "._$", 0x80, true);
|
||||
|
||||
int chPrevNonWhite = ' ';
|
||||
int visibleChars = 0;
|
||||
|
||||
// look back to set chPrevNonWhite properly for better regex colouring
|
||||
int endPos = startPos + length;
|
||||
if (startPos > 0 && IsSpaceEquiv(initStyle)) {
|
||||
unsigned int back = startPos;
|
||||
styler.Flush();
|
||||
while (back > 0 && IsSpaceEquiv(styler.StyleAt(--back)))
|
||||
;
|
||||
if (styler.StyleAt(back) == SCE_COFFEESCRIPT_OPERATOR) {
|
||||
chPrevNonWhite = styler.SafeGetCharAt(back);
|
||||
}
|
||||
if (startPos != back) {
|
||||
initStyle = styler.StyleAt(back);
|
||||
if (IsSpaceEquiv(initStyle)) {
|
||||
initStyle = SCE_COFFEESCRIPT_DEFAULT;
|
||||
}
|
||||
}
|
||||
startPos = back;
|
||||
}
|
||||
|
||||
StyleContext sc(startPos, endPos - startPos, initStyle, styler);
|
||||
|
||||
for (; sc.More(); sc.Forward()) {
|
||||
|
||||
if (sc.atLineStart) {
|
||||
// Reset states to beginning of colourise so no surprises
|
||||
// if different sets of lines lexed.
|
||||
visibleChars = 0;
|
||||
}
|
||||
|
||||
// Determine if the current state should terminate.
|
||||
switch (sc.state) {
|
||||
case SCE_COFFEESCRIPT_OPERATOR:
|
||||
sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_NUMBER:
|
||||
// We accept almost anything because of hex. and number suffixes
|
||||
if (!setWord.Contains(sc.ch) || sc.Match('.', '.')) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_IDENTIFIER:
|
||||
if (!setWord.Contains(sc.ch) || (sc.ch == '.') || (sc.ch == '$')) {
|
||||
char s[1000];
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
if (keywords.InList(s)) {
|
||||
sc.ChangeState(SCE_COFFEESCRIPT_WORD);
|
||||
} else if (keywords2.InList(s)) {
|
||||
sc.ChangeState(SCE_COFFEESCRIPT_WORD2);
|
||||
} else if (keywords4.InList(s)) {
|
||||
sc.ChangeState(SCE_COFFEESCRIPT_GLOBALCLASS);
|
||||
}
|
||||
sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_WORD:
|
||||
case SCE_COFFEESCRIPT_WORD2:
|
||||
case SCE_COFFEESCRIPT_GLOBALCLASS:
|
||||
if (!setWord.Contains(sc.ch)) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_COMMENTLINE:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_STRING:
|
||||
if (sc.ch == '\\') {
|
||||
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
|
||||
sc.Forward();
|
||||
}
|
||||
} else if (sc.ch == '\"') {
|
||||
sc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_CHARACTER:
|
||||
if (sc.ch == '\\') {
|
||||
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
|
||||
sc.Forward();
|
||||
}
|
||||
} else if (sc.ch == '\'') {
|
||||
sc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_REGEX:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
} else if (sc.ch == '/') {
|
||||
sc.Forward();
|
||||
while ((sc.ch < 0x80) && islower(sc.ch))
|
||||
sc.Forward(); // gobble regex flags
|
||||
sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
} else if (sc.ch == '\\') {
|
||||
// Gobble up the quoted character
|
||||
if (sc.chNext == '\\' || sc.chNext == '/') {
|
||||
sc.Forward();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_STRINGEOL:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_COMMENTBLOCK:
|
||||
if (sc.Match("###")) {
|
||||
sc.Forward();
|
||||
sc.Forward();
|
||||
sc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
} else if (sc.ch == '\\') {
|
||||
sc.Forward();
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_VERBOSE_REGEX:
|
||||
if (sc.Match("///")) {
|
||||
sc.Forward();
|
||||
sc.Forward();
|
||||
sc.ForwardSetState(SCE_COFFEESCRIPT_DEFAULT);
|
||||
} else if (sc.Match('#')) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT);
|
||||
} else if (sc.ch == '\\') {
|
||||
sc.Forward();
|
||||
}
|
||||
break;
|
||||
case SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Determine if a new state should be entered.
|
||||
if (sc.state == SCE_COFFEESCRIPT_DEFAULT) {
|
||||
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_NUMBER);
|
||||
} else if (setWordStart.Contains(sc.ch)) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_IDENTIFIER);
|
||||
} else if (sc.Match("///")) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_VERBOSE_REGEX);
|
||||
sc.Forward();
|
||||
sc.Forward();
|
||||
} else if (sc.ch == '/'
|
||||
&& (setOKBeforeRE.Contains(chPrevNonWhite)
|
||||
|| followsReturnKeyword(sc, styler))
|
||||
&& (!setCouldBePostOp.Contains(chPrevNonWhite)
|
||||
|| !FollowsPostfixOperator(sc, styler))) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_REGEX); // JavaScript's RegEx
|
||||
} else if (sc.ch == '\"') {
|
||||
sc.SetState(SCE_COFFEESCRIPT_STRING);
|
||||
} else if (sc.ch == '\'') {
|
||||
sc.SetState(SCE_COFFEESCRIPT_CHARACTER);
|
||||
} else if (sc.ch == '#') {
|
||||
if (sc.Match("###")) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_COMMENTBLOCK);
|
||||
sc.Forward();
|
||||
sc.Forward();
|
||||
} else {
|
||||
sc.SetState(SCE_COFFEESCRIPT_COMMENTLINE);
|
||||
}
|
||||
} else if (isoperator(static_cast<char>(sc.ch))) {
|
||||
sc.SetState(SCE_COFFEESCRIPT_OPERATOR);
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) {
|
||||
chPrevNonWhite = sc.ch;
|
||||
visibleChars++;
|
||||
}
|
||||
}
|
||||
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 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",
|
||||
"Secondary keywords",
|
||||
"Unused",
|
||||
"Global classes",
|
||||
0,
|
||||
};
|
||||
|
||||
LexerModule lmCoffeeScript(SCLEX_COFFEESCRIPT, ColouriseCoffeeScriptDoc, "coffeescript", FoldCoffeeScriptDoc, csWordLists);
|
|
@ -0,0 +1,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+1];
|
||||
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);
|
|
@ -0,0 +1,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+1];
|
||||
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);
|
|
@ -0,0 +1,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);
|
|
@ -0,0 +1,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);
|