Update Scintilla to version 2.03.

git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@4723 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Enrico Tröger 2010-03-07 10:31:51 +00:00
parent 90a7f9294b
commit 7396f7672d
52 changed files with 3283 additions and 2274 deletions

View File

@ -11,7 +11,7 @@
#include "Platform.h"
#include "PropSet.h"
#include "CharClassify.h"
#include "AutoComplete.h"
#ifdef SCI_NAMESPACE

View File

@ -254,11 +254,9 @@ PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
const char *faceName, int size,
int codePage_, int characterSet, Window &wParent) {
clickPlace = 0;
if (val)
delete []val;
delete []val;
val = 0;
val = new char[strlen(defn) + 1];
if (!val)
return PRectangle();
strcpy(val, defn);
codePage = codePage_;
Surface *surfaceMeasure = Surface::Allocate();

View File

@ -27,8 +27,8 @@ class CallTip {
bool useStyleCallTip; // if true, STYLE_CALLTIP should be used
// Private so CallTip objects can not be copied
CallTip(const CallTip &) {}
CallTip &operator=(const CallTip &) { return *this; }
CallTip(const CallTip &);
CallTip &operator=(const CallTip &);
void DrawChunk(Surface *surface, int &x, const char *s,
int posStart, int posEnd, int ytext, PRectangle rcClient,
bool highlight, bool draw);

View File

@ -71,6 +71,7 @@ Action::Action() {
position = 0;
data = 0;
lenData = 0;
mayCoalesce = false;
}
Action::~Action() {
@ -150,8 +151,6 @@ void UndoHistory::EnsureUndoRoom() {
// Run out of undo nodes so extend the array
int lenActionsNew = lenActions * 2;
Action *actionsNew = new Action[lenActionsNew];
if (!actionsNew)
return;
for (int act = 0; act <= currentAction; act++)
actionsNew[act].Grab(&actions[act]);
delete []actions;

View File

@ -5,6 +5,7 @@
// Copyright 2006 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <ctype.h>
#include "CharClassify.h"
@ -41,3 +42,37 @@ void CharClassify::SetCharClasses(const unsigned char *chars, cc newCharClass) {
}
}
}
int CompareCaseInsensitive(const char *a, const char *b) {
while (*a && *b) {
if (*a != *b) {
char upperA = MakeUpperCase(*a);
char upperB = MakeUpperCase(*b);
if (upperA != upperB)
return upperA - upperB;
}
a++;
b++;
}
// Either *a or *b is nul
return *a - *b;
}
int CompareNCaseInsensitive(const char *a, const char *b, size_t len) {
while (*a && *b && len) {
if (*a != *b) {
char upperA = MakeUpperCase(*a);
char upperB = MakeUpperCase(*b);
if (upperA != upperB)
return upperA - upperB;
}
a++;
b++;
len--;
}
if (len == 0)
return 0;
else
// Either *a or *b is nul
return *a - *b;
}

View File

@ -2,7 +2,7 @@
/** @file CharClassify.h
** Character classifications used by Document and RESearch.
**/
// Copyright 2006 by Neil Hodgson <neilh@scintilla.org>
// Copyright 2006-2009 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef CHARCLASSIFY_H
@ -22,4 +22,16 @@ private:
enum { maxChar=256 };
unsigned char charClass[maxChar]; // not type cc to save space
};
// These functions are implemented because each platform calls them something different.
int CompareCaseInsensitive(const char *a, const char *b);
int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
inline char MakeUpperCase(char ch) {
if (ch < 'a' || ch > 'z')
return ch;
else
return static_cast<char>(ch - 'a' + 'A');
}
#endif

View File

@ -217,6 +217,10 @@ int Document::LineEndPosition(int position) const {
return LineEnd(LineFromPosition(position));
}
bool Document::IsLineEndPosition(int position) const {
return LineEnd(LineFromPosition(position)) == position;
}
int Document::VCHomePosition(int position) const {
int line = LineFromPosition(position);
int startPosition = LineStart(line);
@ -757,10 +761,9 @@ void Document::SetLineIndentation(int line, int indent) {
CreateIndentation(linebuf, sizeof(linebuf), indent, tabInChars, !useTabs);
int thisLineStart = LineStart(line);
int indentPos = GetLineIndentPosition(line);
BeginUndoAction();
UndoGroup ug(this);
DeleteChars(thisLineStart, indentPos - thisLineStart);
InsertCString(thisLineStart, linebuf);
EndUndoAction();
}
}
@ -801,8 +804,8 @@ int Document::GetColumn(int pos) {
int Document::FindColumn(int line, int column) {
int position = LineStart(line);
int columnCurrent = 0;
if ((line >= 0) && (line < LinesTotal())) {
int columnCurrent = 0;
while ((columnCurrent < column) && (position < Length())) {
char ch = cb.CharAt(position);
if (ch == '\t') {
@ -867,7 +870,7 @@ char *Document::TransformLineEnds(int *pLenOut, const char *s, size_t len, int e
}
void Document::ConvertLineEnds(int eolModeSet) {
BeginUndoAction();
UndoGroup ug(this);
for (int pos = 0; pos < Length(); pos++) {
if (cb.CharAt(pos) == '\r') {
@ -902,7 +905,6 @@ void Document::ConvertLineEnds(int eolModeSet) {
}
}
EndUndoAction();
}
bool Document::IsWhiteLine(int line) const {
@ -1065,16 +1067,6 @@ bool Document::IsWordAt(int start, int end) {
return IsWordStartAt(start) && IsWordEndAt(end);
}
// The comparison and case changing functions here assume ASCII
// or extended ASCII such as the normal Windows code page.
static inline char MakeUpperCase(char ch) {
if (ch < 'a' || ch > 'z')
return ch;
else
return static_cast<char>(ch - 'a' + 'A');
}
static inline char MakeLowerCase(char ch) {
if (ch < 'A' || ch > 'Z')
return ch;
@ -1374,8 +1366,6 @@ bool Document::AddWatcher(DocWatcher *watcher, void *userData) {
return false;
}
WatcherWithUserData *pwNew = new WatcherWithUserData[lenWatchers + 1];
if (!pwNew)
return false;
for (int j = 0; j < lenWatchers; j++)
pwNew[j] = watchers[j];
pwNew[lenWatchers].watcher = watcher;
@ -1396,8 +1386,6 @@ bool Document::RemoveWatcher(DocWatcher *watcher, void *userData) {
lenWatchers = 0;
} else {
WatcherWithUserData *pwNew = new WatcherWithUserData[lenWatchers];
if (!pwNew)
return false;
for (int j = 0; j < lenWatchers - 1; j++) {
pwNew[j] = (j < i) ? watchers[j] : watchers[j + 1];
}
@ -1758,8 +1746,6 @@ const char *BuiltinRegex::SubstituteByPosition(Document* doc, const char *text,
}
}
substituted = new char[lenResult + 1];
if (!substituted)
return 0;
char *o = substituted;
for (int j = 0; j < *length; j++) {
if (text[j] == '\\') {

View File

@ -239,6 +239,7 @@ public:
int LineStart(int line) const;
int LineEnd(int line) const;
int LineEndPosition(int position) const;
bool IsLineEndPosition(int position) const;
int VCHomePosition(int position) const;
int SetLevel(int line, int level);
@ -319,6 +320,27 @@ private:
void NotifyModified(DocModification mh);
};
class UndoGroup {
Document *pdoc;
bool groupNeeded;
public:
UndoGroup(Document *pdoc_, bool groupNeeded_=true) :
pdoc(pdoc_), groupNeeded(groupNeeded_) {
if (groupNeeded) {
pdoc->BeginUndoAction();
}
}
~UndoGroup() {
if (groupNeeded) {
pdoc->EndUndoAction();
}
}
bool Needed() const {
return groupNeeded;
}
};
/**
* To optimise processing of document modifications by DocWatchers, a hint is passed indicating the
* scope of the change.

View File

@ -14,14 +14,15 @@ class Document;
/**
*/
class DocumentAccessor : public Accessor {
// Private so DocumentAccessor objects can not be copied
DocumentAccessor(const DocumentAccessor &source) : Accessor(), props(source.props) {}
DocumentAccessor &operator=(const DocumentAccessor &) { return *this; }
DocumentAccessor(const DocumentAccessor &source);
DocumentAccessor &operator=(const DocumentAccessor &);
protected:
Document *pdoc;
PropSet &props;
PropertyGet &props;
WindowID id;
int lenDoc;
@ -37,7 +38,7 @@ protected:
void Fill(int position);
public:
DocumentAccessor(Document *pdoc_, PropSet &props_, WindowID id_=0) :
DocumentAccessor(Document *pdoc_, PropertyGet &props_, WindowID id_=0) :
Accessor(), pdoc(pdoc_), props(props_), id(id_),
lenDoc(-1), validLen(0), chFlags(0), chWhile(0),
startSeg(0), startPosStyling(0),

File diff suppressed because it is too large Load Diff

View File

@ -78,14 +78,11 @@ public:
}
void Copy(const char *s_, int len_, int codePage_, int characterSet_, bool rectangular_, bool lineCopy_) {
delete []s;
s = 0;
s = new char[len_];
if (s) {
len = len_;
for (int i = 0; i < len_; i++) {
s[i] = s_[i];
}
} else {
len = 0;
len = len_;
for (int i = 0; i < len_; i++) {
s[i] = s_[i];
}
codePage = codePage_;
characterSet = characterSet_;
@ -101,8 +98,8 @@ public:
*/
class Editor : public DocWatcher {
// Private so Editor objects can not be copied
Editor(const Editor &) : DocWatcher() {}
Editor &operator=(const Editor &) { return *this; }
Editor(const Editor &);
Editor &operator=(const Editor &);
protected: // ScintillaBase subclass needs access to much of Editor
@ -143,6 +140,12 @@ protected: // ScintillaBase subclass needs access to much of Editor
bool verticalScrollBarVisible;
bool endAtLastLine;
bool caretSticky;
bool multipleSelection;
bool additionalSelectionTyping;
bool additionalCaretsBlink;
bool additionalCaretsVisible;
int virtualSpaceOptions;
Surface *pixmapLine;
Surface *pixmapSelMargin;
@ -171,13 +174,11 @@ protected: // ScintillaBase subclass needs access to much of Editor
Point ptMouseLast;
enum { ddNone, ddInitial, ddDragging } inDragDrop;
bool dropWentOutside;
int posDrag;
int posDrop;
SelectionPosition posDrag;
SelectionPosition posDrop;
int lastXChosen;
int lineAnchor;
int originalAnchorPos;
int currentPos;
int anchor;
int targetStart;
int targetEnd;
int searchFlags;
@ -199,11 +200,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
int modEventMask;
SelectionText drag;
enum selTypes { noSel, selStream, selRectangle, selLines };
selTypes selType;
bool moveExtendsSelection;
int xStartSelect; ///< x position of start of rectangular selection
int xEndSelect; ///< x position of end of rectangular selection
Selection sel;
bool primarySelection;
int caretXPolicy;
@ -259,9 +256,14 @@ protected: // ScintillaBase subclass needs access to much of Editor
int LinesOnScreen();
int LinesToScroll();
int MaxScrollPos();
SelectionPosition ClampPositionIntoDocument(SelectionPosition sp) const;
Point LocationFromPosition(SelectionPosition pos);
Point LocationFromPosition(int pos);
int XFromPosition(int pos);
int XFromPosition(SelectionPosition sp);
SelectionPosition SPositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false, bool virtualSpace=true);
int PositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false);
SelectionPosition SPositionFromLineX(int lineDoc, int x);
int PositionFromLineX(int line, int x);
int LineFromLocation(Point pt);
void SetTopLine(int topLineNew);
@ -273,20 +275,31 @@ protected: // ScintillaBase subclass needs access to much of Editor
PRectangle RectangleFromRange(int start, int end);
void InvalidateRange(int start, int end);
bool UserVirtualSpace() const {
return ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0);
}
int CurrentPosition();
bool SelectionEmpty();
int SelectionStart();
int SelectionEnd();
SelectionPosition SelectionStart();
SelectionPosition SelectionEnd();
void SetRectangularRange();
void InvalidateSelection(int currentPos_, int anchor_, bool invalidateWholeSelection);
void ThinRectangularRange();
void InvalidateSelection(SelectionRange newMain, bool invalidateWholeSelection=false);
void SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_);
void SetSelection(int currentPos_, int anchor_);
void SetSelection(SelectionPosition currentPos_);
void SetSelection(int currentPos_);
void SetEmptySelection(SelectionPosition currentPos_);
void SetEmptySelection(int currentPos_);
bool RangeContainsProtected(int start, int end) const;
bool SelectionContainsProtected();
int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true) const;
int MovePositionTo(int newPos, selTypes sel=noSel, bool ensureVisible=true);
int MovePositionSoVisible(int pos, int moveDir);
SelectionPosition MovePositionOutsideChar(SelectionPosition pos, int moveDir, bool checkLineEnd=true) const;
int MovePositionTo(SelectionPosition newPos, Selection::selTypes sel=Selection::noSel, bool ensureVisible=true);
int MovePositionTo(int newPos, Selection::selTypes sel=Selection::noSel, bool ensureVisible=true);
SelectionPosition MovePositionSoVisible(SelectionPosition pos, int moveDir);
SelectionPosition MovePositionSoVisible(int pos, int moveDir);
Point PointMainCaret();
void SetLastXChosen();
void ScrollTo(int line, bool moveThumb=true);
@ -311,8 +324,8 @@ protected: // ScintillaBase subclass needs access to much of Editor
LineLayout *RetrieveLineLayout(int lineNumber);
void LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout *ll,
int width=LineLayout::wrapWidthInfinite);
ColourAllocated SelectionBackground(ViewStyle &vsDraw);
ColourAllocated TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourAllocated background, bool inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll);
ColourAllocated SelectionBackground(ViewStyle &vsDraw, bool main);
ColourAllocated TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourAllocated background, int inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll);
void DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight);
void DrawWrapMarker(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourAllocated wrapColour);
void DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll,
@ -324,8 +337,11 @@ protected: // ScintillaBase subclass needs access to much of Editor
void DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine);
void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine=0);
void DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine, int xStart, int offset, int posCaret, PRectangle rcCaret);
PRectangle rcLine, LineLayout *ll, int subLine);
void DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine,
int xStart, int offset, int posCaret, PRectangle rcCaret, ColourAllocated caretColour);
void DrawCarets(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine);
void RefreshPixMaps(Surface *surfaceWindow);
void Paint(Surface *surfaceWindow, PRectangle rcArea);
long FormatRange(bool draw, Sci_RangeToFormat *pfr);
@ -338,13 +354,15 @@ protected: // ScintillaBase subclass needs access to much of Editor
void SetScrollBars();
void ChangeSize();
void FilterSelections();
int InsertSpace(int position, unsigned int spaces);
void AddChar(char ch);
virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false);
void ClearSelection();
void ClearAll();
void ClearDocumentStyle();
void Cut();
void PasteRectangular(int pos, const char *ptr, int len);
void PasteRectangular(SelectionPosition pos, const char *ptr, int len);
virtual void Copy() = 0;
virtual void CopyAllowLine();
virtual bool CanPaste();
@ -384,14 +402,14 @@ protected: // ScintillaBase subclass needs access to much of Editor
void NotifyStyleNeeded(Document *doc, void *userData, int endPos);
void NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
void PageMove(int direction, selTypes sel=noSel, bool stuttered = false);
void PageMove(int direction, Selection::selTypes sel=Selection::noSel, bool stuttered = false);
void ChangeCaseOfSelection(bool makeUpperCase);
void LineTranspose();
void Duplicate(bool forLine);
virtual void CancelModes();
void NewLine();
void CursorUpOrDown(int direction, selTypes sel=noSel);
void ParaUpOrDown(int direction, selTypes sel=noSel);
void CursorUpOrDown(int direction, Selection::selTypes sel=Selection::noSel);
void ParaUpOrDown(int direction, Selection::selTypes sel=Selection::noSel);
int StartEndDisplayLine(int pos, bool start);
virtual int KeyCommand(unsigned int iMessage);
virtual int KeyDefault(int /* key */, int /*modifiers*/);
@ -410,18 +428,16 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void CopyToClipboard(const SelectionText &selectedText) = 0;
char *CopyRange(int start, int end);
void CopySelectionFromRange(SelectionText *ss, bool allowLineCopy, int start, int end);
void CopySelectionRange(SelectionText *ss, bool allowLineCopy=false);
void CopyRangeToClipboard(int start, int end);
void CopyText(int length, const char *text);
void SetDragPosition(int newPos);
void SetDragPosition(SelectionPosition newPos);
virtual void DisplayCursor(Window::Cursor c);
virtual bool DragThreshold(Point ptStart, Point ptNow);
virtual void StartDrag();
void DropAt(int position, const char *value, bool moving, bool rectangular);
/** PositionInSelection returns 0 if position in selection, -1 if position before selection, and 1 if after.
* Before means either before any line of selection or before selection on its line, with a similar meaning to after. */
int PositionInSelection(int pos);
void DropAt(SelectionPosition position, const char *value, bool moving, bool rectangular);
/** PositionInSelection returns true if position in selection. */
bool PositionInSelection(int pos);
bool PointInSelection(Point pt);
bool PointInSelMargin(Point pt);
void LineSelection(int lineCurrent_, int lineAnchor_);
@ -469,6 +485,8 @@ protected: // ScintillaBase subclass needs access to much of Editor
static const char *StringFromEOLMode(int eolMode);
static sptr_t StringResult(sptr_t lParam, const char *val);
public:
// Public so the COM thunks can access it.
bool IsUnicodeMode() const;

View File

@ -10,6 +10,8 @@
#include <string.h>
#include <ctype.h>
#include <string>
#include "Platform.h"
#include "Scintilla.h"
@ -39,7 +41,7 @@ char **WordListsToStrings(WordList *val[]) {
dim++;
char **wls = new char * [dim + 1];
for (int i = 0;i < dim;i++) {
SString words;
std::string words;
words = "";
for (int n = 0; n < val[i]->len; n++) {
words += val[i]->words[n];

View File

@ -40,6 +40,7 @@ public:
ExternalLexerModule(int language_, LexerFunction fnLexer_,
const char *languageName_=0, LexerFunction fnFolder_=0) : LexerModule(language_, fnLexer_, 0, fnFolder_){
strncpy(name, languageName_, sizeof(name));
name[sizeof(name)-1] = '\0';
languageName = name;
};
virtual void Lex(unsigned int startPos, int lengthDoc, int initStyle,
@ -68,7 +69,7 @@ public:
void Release();
LexerLibrary *next;
SString m_sModuleName;
std::string m_sModuleName;
};
/// LexerManager manages external lexers, contains LexerLibrarys.

View File

@ -23,6 +23,192 @@
using namespace Scintilla;
#endif
/**
* Creates an array that points into each word in the string and puts \0 terminators
* after each word.
*/
static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) {
int prev = '\n';
int words = 0;
// For rapid determination of whether a character is a separator, build
// a look up table.
bool wordSeparator[256];
for (int i=0;i<256; i++) {
wordSeparator[i] = false;
}
wordSeparator['\r'] = true;
wordSeparator['\n'] = true;
if (!onlyLineEnds) {
wordSeparator[' '] = true;
wordSeparator['\t'] = true;
}
for (int j = 0; wordlist[j]; j++) {
int curr = static_cast<unsigned char>(wordlist[j]);
if (!wordSeparator[curr] && wordSeparator[prev])
words++;
prev = curr;
}
char **keywords = new char *[words + 1];
if (keywords) {
words = 0;
prev = '\0';
size_t slen = strlen(wordlist);
for (size_t k = 0; k < slen; k++) {
if (!wordSeparator[static_cast<unsigned char>(wordlist[k])]) {
if (!prev) {
keywords[words] = &wordlist[k];
words++;
}
} else {
wordlist[k] = '\0';
}
prev = wordlist[k];
}
keywords[words] = &wordlist[slen];
*len = words;
} else {
*len = 0;
}
return keywords;
}
void WordList::Clear() {
if (words) {
delete []list;
delete []words;
}
words = 0;
list = 0;
len = 0;
sorted = false;
}
void WordList::Set(const char *s) {
list = new char[strlen(s) + 1];
strcpy(list, s);
sorted = false;
words = ArrayFromWordList(list, &len, onlyLineEnds);
}
extern "C" int cmpString(const void *a1, const void *a2) {
// Can't work out the correct incantation to use modern casts here
return strcmp(*(char**)(a1), *(char**)(a2));
}
static void SortWordList(char **words, unsigned int len) {
qsort(reinterpret_cast<void*>(words), len, sizeof(*words),
cmpString);
}
bool WordList::InList(const char *s) {
if (0 == words)
return false;
if (!sorted) {
sorted = true;
SortWordList(words, len);
for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
starts[k] = -1;
for (int l = len - 1; l >= 0; l--) {
unsigned char indexChar = words[l][0];
starts[indexChar] = l;
}
}
unsigned char firstChar = s[0];
int j = starts[firstChar];
if (j >= 0) {
while ((unsigned char)words[j][0] == firstChar) {
if (s[1] == words[j][1]) {
const char *a = words[j] + 1;
const char *b = s + 1;
while (*a && *a == *b) {
a++;
b++;
}
if (!*a && !*b)
return true;
}
j++;
}
}
j = starts['^'];
if (j >= 0) {
while (words[j][0] == '^') {
const char *a = words[j] + 1;
const char *b = s;
while (*a && *a == *b) {
a++;
b++;
}
if (!*a)
return true;
j++;
}
}
return false;
}
/** similar to InList, but word s can be a substring of keyword.
* eg. the keyword define is defined as def~ine. This means the word must start
* with def to be a keyword, but also defi, defin and define are valid.
* The marker is ~ in this case.
*/
bool WordList::InListAbbreviated(const char *s, const char marker) {
if (0 == words)
return false;
if (!sorted) {
sorted = true;
SortWordList(words, len);
for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
starts[k] = -1;
for (int l = len - 1; l >= 0; l--) {
unsigned char indexChar = words[l][0];
starts[indexChar] = l;
}
}
unsigned char firstChar = s[0];
int j = starts[firstChar];
if (j >= 0) {
while (words[j][0] == firstChar) {
bool isSubword = false;
int start = 1;
if (words[j][1] == marker) {
isSubword = true;
start++;
}
if (s[1] == words[j][start]) {
const char *a = words[j] + start;
const char *b = s + 1;
while (*a && *a == *b) {
a++;
if (*a == marker) {
isSubword = true;
a++;
}
b++;
}
if ((!*a || isSubword) && !*b)
return true;
}
j++;
}
}
j = starts['^'];
if (j >= 0) {
while (words[j][0] == '^') {
const char *a = words[j] + 1;
const char *b = s;
while (*a && *a == *b) {
a++;
b++;
}
if (!*a)
return true;
j++;
}
}
return false;
}
const LexerModule *LexerModule::base = 0;
int LexerModule::nextLanguage = SCLEX_AUTOMATIC+1;
@ -141,7 +327,7 @@ int Scintilla_LinkLexers() {
//++Autogenerated -- run src/LexGen.py to regenerate
//**\(\tLINK_LEXER(\*);\n\)
LINK_LEXER(lmAda);
LINK_LEXER(lmAda);
LINK_LEXER(lmAsm);
LINK_LEXER(lmBash);
LINK_LEXER(lmCaml);

View File

@ -10,6 +10,8 @@
#include <string.h>
#include <stdio.h>
#include <string>
#include "Platform.h"
#include "Accessor.h"
@ -17,7 +19,6 @@
#include "PropSet.h"
#include "KeyWords.h"
#include "SciLexer.h"
#include "SString.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@ -62,8 +63,8 @@ static inline bool IsDelimiterCharacter(int ch);
static inline bool IsNumberStartCharacter(int ch);
static inline bool IsNumberCharacter(int ch);
static inline bool IsSeparatorOrDelimiterCharacter(int ch);
static bool IsValidIdentifier(const SString& identifier);
static bool IsValidNumber(const SString& number);
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);
@ -117,7 +118,7 @@ static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostroph
sc.Forward();
sc.Forward();
SString identifier;
std::string identifier;
while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
identifier += static_cast<char>(tolower(sc.ch));
@ -144,7 +145,7 @@ static void ColouriseLabel(StyleContext& sc, WordList& keywords, bool& apostroph
static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
apostropheStartsAttribute = true;
SString number;
std::string number;
sc.SetState(SCE_ADA_NUMBER);
// Get all characters up to a delimiter or a separator, including points, but excluding
@ -192,7 +193,7 @@ static void ColouriseWord(StyleContext& sc, WordList& keywords, bool& apostrophe
apostropheStartsAttribute = true;
sc.SetState(SCE_ADA_IDENTIFIER);
SString word;
std::string word;
while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
word += static_cast<char>(tolower(sc.ch));
@ -321,7 +322,7 @@ static inline bool IsSeparatorOrDelimiterCharacter(int ch) {
return IsASpace(ch) || IsDelimiterCharacter(ch);
}
static bool IsValidIdentifier(const SString& identifier) {
static bool IsValidIdentifier(const std::string& identifier) {
// First character can't be '_', so initialize the flag to true
bool lastWasUnderscore = true;
@ -355,8 +356,8 @@ static bool IsValidIdentifier(const SString& identifier) {
return true;
}
static bool IsValidNumber(const SString& number) {
int hashPos = number.search("#");
static bool IsValidNumber(const std::string& number) {
size_t hashPos = number.find("#");
bool seenDot = false;
size_t i = 0;
@ -366,7 +367,7 @@ static bool IsValidNumber(const SString& number) {
return false; // Just in case
// Decimal number
if (hashPos == -1) {
if (hashPos == std::string::npos) {
bool canBeSpecial = false;
for (; i < length; i++) {

View File

@ -27,6 +27,7 @@
#include "Platform.h"
#include "PropSet.h"
#include "PropSetSimple.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
@ -143,7 +144,7 @@ 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)
PropSet ps;
PropSetSimple ps;
ps.SetMultiple(props);
WindowAccessor wa(window, ps);
// create and initialize WordList(s)

View File

@ -13,6 +13,7 @@
#include "Platform.h"
#include "CharClassify.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"

View File

@ -69,6 +69,22 @@ static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int en
s[i] = '\0';
}
static const char *GetNextWord(Accessor &styler, unsigned int start, char *s, size_t sLen) {
size_t i = 0;
for (; i < sLen-1; i++) {
char ch = static_cast<char>(styler.SafeGetCharAt(start + i));
if ((i == 0) && !IsAWordStart(ch))
break;
if ((i > 0) && !IsAWordChar(ch))
break;
s[i] = ch;
}
s[i] = '\0';
return s;
}
static script_type segIsScriptingIndicator(Accessor &styler, unsigned int start, unsigned int end, script_type prevValue) {
char s[100];
GetTextSegment(styler, start, end, s, sizeof(s));
@ -474,6 +490,23 @@ static bool isOKBeforeRE(int ch) {
return (ch == '(') || (ch == '=') || (ch == ',');
}
static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType) {
if (strlen(blockType) == 0) {
return ((ch == '%') && (chNext == '>'));
} else if ((0 == strcmp(blockType, "inherit")) ||
(0 == strcmp(blockType, "namespace")) ||
(0 == strcmp(blockType, "include")) ||
(0 == strcmp(blockType, "page"))) {
return ((ch == '/') && (chNext == '>'));
} else if (0 == strcmp(blockType, "%")) {
return isLineEnd(ch);
} else if (0 == strcmp(blockType, "{")) {
return ch == '}';
} else {
return (ch == '>');
}
}
static bool isPHPStringState(int state) {
return
(state == SCE_HPHP_HSTRING) ||
@ -542,10 +575,14 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
styler.StartAt(startPos, static_cast<char>(STYLE_MAX));
char prevWord[200];
prevWord[0] = '\0';
char nextWord[200];
nextWord[0] = '\0';
char phpStringDelimiter[200]; // PHP is not limited in length, we are
phpStringDelimiter[0] = '\0';
int StateToPrint = initStyle;
int state = stateForPrintState(StateToPrint);
char makoBlockType[200];
makoBlockType[0] = '\0';
// If inside a tag, it may be a script tag, so reread from the start to ensure any language tags are seen
if (InTagState(state)) {
@ -627,6 +664,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
// Set to 0 to disable scripts in XML.
const bool allowScripts = styler.GetPropertyInt("lexer.xml.allow.scripts", 1) != 0;
// property lexer.html.mako
// Set to 1 to enable the mako template language.
const bool isMako = styler.GetPropertyInt("lexer.html.mako", 0) != 0;
const CharacterSet setHTMLWord(CharacterSet::setAlphaNum, ".-_:!#", 0x80, true);
const CharacterSet setTagContinue(CharacterSet::setAlphaNum, ".-_:!#[", 0x80, true);
const CharacterSet setAttributeContinue(CharacterSet::setAlphaNum, ".-_:!#/", 0x80, true);
@ -634,6 +675,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
int visibleChars = 0;
int lineStartVisibleChars = 0;
int chPrev = ' ';
int ch = ' ';
@ -674,6 +716,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
if ((!IsASpace(ch) || !foldCompact) && fold)
visibleChars++;
if (!IsASpace(ch))
lineStartVisibleChars++;
// decide what is the current state to print (depending of the script tag)
StateToPrint = statePrintForState(state, inScriptType);
@ -742,6 +786,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
levelPrev = levelCurrent;
}
lineCurrent++;
lineStartVisibleChars = 0;
styler.SetLineState(lineCurrent,
((inScriptType & 0x03) << 0) |
((tagOpened & 0x01) << 2) |
@ -751,6 +796,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
((beforePreProc & 0xFF) << 12));
}
// Allow falling through to mako handling code if newline is going to end a block
if (((ch == '\r' && chNext != '\n') || (ch == '\n')) &&
(!isMako || (0 != strcmp(makoBlockType, "%")))) {
}
// generic end of script processing
else if ((inScriptType == eNonHtmlScript) && (ch == '<') && (chNext == '/')) {
// Check if it's the end of the script tag (or any other HTML tag)
@ -835,8 +885,54 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
continue;
}
// handle the start Mako template Python code
else if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') ||
(lineStartVisibleChars == 1 && ch == '%') ||
(ch == '$' && chNext == '{') ||
(ch == '<' && chNext == '/' && chNext2 == '%'))) {
if (ch == '%')
strcpy(makoBlockType, "%");
else if (ch == '$')
strcpy(makoBlockType, "{");
else if (chNext == '/')
GetNextWord(styler, i+3, makoBlockType, sizeof(makoBlockType));
else
GetNextWord(styler, i+2, makoBlockType, sizeof(makoBlockType));
styler.ColourTo(i - 1, StateToPrint);
beforePreProc = state;
if (inScriptType == eNonHtmlScript)
inScriptType = eNonHtmlScriptPreProc;
else
inScriptType = eNonHtmlPreProc;
if (chNext == '/') {
i += 2;
visibleChars += 2;
} else if (ch != '%') {
i++;
visibleChars++;
}
state = SCE_HP_START;
scriptLanguage = eScriptPython;
styler.ColourTo(i, SCE_H_ASP);
if (foldHTMLPreprocessor && ch == '<')
levelCurrent++;
if (ch != '%' && ch != '$') {
i += strlen(makoBlockType);
visibleChars += strlen(makoBlockType);
if (keywords4.InList(makoBlockType))
styler.ColourTo(i, SCE_HP_WORD);
else
styler.ColourTo(i, SCE_H_TAGUNKNOWN);
}
ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
continue;
}
// handle the start of ASP pre-processor = Non-HTML
else if (!isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
else if (!isMako && !isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
styler.ColourTo(i - 1, StateToPrint);
beforePreProc = state;
if (inScriptType == eNonHtmlScript)
@ -901,12 +997,43 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
continue;
}
// handle the end of Mako Python code
else if (isMako &&
((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
(scriptLanguage != eScriptNone) && stateAllowsTermination(state) &&
isMakoBlockEnd(ch, chNext, makoBlockType)) {
if (state == SCE_H_ASPAT) {
aspScript = segIsScriptingIndicator(styler,
styler.GetStartSegment(), i - 1, aspScript);
}
if (state == SCE_HP_WORD) {
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
} else {
styler.ColourTo(i - 1, StateToPrint);
}
if (0 != strcmp(makoBlockType, "%") && (0 != strcmp(makoBlockType, "{")) && ch != '>') {
i++;
visibleChars++;
}
if (0 != strcmp(makoBlockType, "%")) {
styler.ColourTo(i, SCE_H_ASP);
}
state = beforePreProc;
if (inScriptType == eNonHtmlScriptPreProc)
inScriptType = eNonHtmlScript;
else
inScriptType = eHtml;
if (foldHTMLPreprocessor && ch != '\n' && ch != '\r') {
levelCurrent--;
}
scriptLanguage = eScriptNone;
continue;
}
// handle the end of a pre-processor = Non-HTML
else if ((
((inScriptType == eNonHtmlPreProc)
|| (inScriptType == eNonHtmlScriptPreProc)) && (
((scriptLanguage != eScriptNone) && stateAllowsTermination(state) && ((ch == '%') || (ch == '?')))
) && (chNext == '>')) ||
else if ((!isMako && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
(((scriptLanguage != eScriptNone) && stateAllowsTermination(state))) &&
(((ch == '%') || (ch == '?')) && (chNext == '>'))) ||
((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) {
if (state == SCE_H_ASPAT) {
aspScript = segIsScriptingIndicator(styler,

View File

@ -25,6 +25,7 @@
#include "Platform.h"
#include "PropSet.h"
#include "PropSetSimple.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
@ -225,7 +226,7 @@ static const char* LexerName = "haskell";
void EXT_LEXER_DECL Lex(unsigned int lexer, unsigned int startPos, int length, int initStyle,
char *words[], WindowID window, char *props)
{
PropSet ps;
PropSetSimple ps;
ps.SetMultiple(props);
WindowAccessor wa(window, ps);

View File

@ -13,6 +13,7 @@
#include "Platform.h"
#include "CharClassify.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
@ -77,7 +78,7 @@ static bool NsisNextLineHasElse(unsigned int start, unsigned int end, Accessor &
}
}
if( nNextLine == -1 ) // We never foudn the next line...
if( nNextLine == -1 ) // We never found the next line...
return false;
for( unsigned int firstChar = nNextLine; firstChar < end; firstChar++ )
@ -145,7 +146,7 @@ static int calculateFoldNsis(unsigned int start, unsigned int end, int foldlevel
if( s[0] == '!' )
{
if( NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!macro", bIgnoreCase ) == 0 )
if( NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrodef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrondef", bIgnoreCase ) == 0 || NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!macro", bIgnoreCase ) == 0 )
newFoldlevel++;
else if( NsisCmp(s, "!endif", bIgnoreCase) == 0 || NsisCmp(s, "!macroend", bIgnoreCase ) == 0 )
newFoldlevel--;
@ -190,16 +191,16 @@ static int classifyWordNsis(unsigned int start, unsigned int end, WordList *keyw
}
// Check for special words...
if( NsisCmp(s, "!macro", bIgnoreCase ) == 0 || NsisCmp(s, "!macroend", bIgnoreCase) == 0 ) // Covers !micro and !microend
if( NsisCmp(s, "!macro", bIgnoreCase ) == 0 || NsisCmp(s, "!macroend", bIgnoreCase) == 0 ) // Covers !macro and !macroend
return SCE_NSIS_MACRODEF;
if( NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!endif", bIgnoreCase) == 0 )
if( NsisCmp(s, "!ifdef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!endif", bIgnoreCase) == 0 ) // Covers !ifdef, !ifndef and !endif
return SCE_NSIS_IFDEFINEDEF;
if( NsisCmp(s, "!else", bIgnoreCase ) == 0 ) // || NsisCmp(s, "!ifndef", bIgnoreCase) == 0 || NsisCmp(s, "!endif", bIgnoreCase) == 0 )
if( NsisCmp(s, "!if", bIgnoreCase ) == 0 || NsisCmp(s, "!else", bIgnoreCase ) == 0 ) // Covers !if and else
return SCE_NSIS_IFDEFINEDEF;
if( NsisCmp(s, "!if", bIgnoreCase ) == 0 )
if (NsisCmp(s, "!ifmacrodef", bIgnoreCase ) == 0 || NsisCmp(s, "!ifmacrondef", bIgnoreCase ) == 0 ) // Covers !ifmacrodef and !ifnmacrodef
return SCE_NSIS_IFDEFINEDEF;
if( NsisCmp(s, "SectionGroup", bIgnoreCase) == 0 || NsisCmp(s, "SectionGroupEnd", bIgnoreCase) == 0 ) // Covers SectionGroup and SectionGroupEnd

View File

@ -14,6 +14,7 @@
#include "Platform.h"
#include "CharClassify.h"
#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"

View File

@ -158,6 +158,10 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
if (styler.GetPropertyInt("lexer.python.strings.b", 1))
allowedLiterals = static_cast<literalsAllowed>(allowedLiterals | litB);
// property lexer.python.strings.over.newline
// Set to 1 to allow strings to span newline characters.
bool stringsOverNewline = styler.GetPropertyInt("lexer.python.strings.over.newline") != 0;
initStyle = initStyle & 31;
if (initStyle == SCE_P_STRINGEOL) {
initStyle = SCE_P_DEFAULT;
@ -204,7 +208,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
}
lineCurrent++;
if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) {
if (inContinuedString) {
if (inContinuedString || stringsOverNewline) {
inContinuedString = false;
} else {
sc.ChangeState(SCE_P_STRINGEOL);
@ -416,6 +420,8 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
// This option enables folding multi-line quoted strings when using the Python lexer.
const bool foldQuotes = styler.GetPropertyInt("fold.quotes.python") != 0;
const bool foldCompact = styler.GetPropertyInt("fold.compact") != 0;
// Backtrack to previous non-blank line so we can determine indent level
// for any white space lines (needed esp. within triple quoted strings)
// and so we can fix any preceding fold level (which is why we go back
@ -514,12 +520,21 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
while (--skipLine > lineCurrent) {
int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);
if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
skipLevel = levelBeforeComments;
if (foldCompact) {
if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
skipLevel = levelBeforeComments;
int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;
styler.SetLevel(skipLine, skipLevel | whiteFlag);
styler.SetLevel(skipLine, skipLevel | whiteFlag);
} else {
if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments &&
!(skipLineIndent & SC_FOLDLEVELWHITEFLAG) &&
!IsCommentLine(skipLine, styler))
skipLevel = levelBeforeComments;
styler.SetLevel(skipLine, skipLevel);
}
}
// Set fold header on non-quote/non-comment line

View File

@ -231,6 +231,10 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
bool foldOnlyBegin = styler.GetPropertyInt("fold.sql.only.begin", 0) != 0;
// property fold.sql.exists
// Enables "EXISTS" to end a fold as is started by "IF" in "DROP TABLE IF EXISTS".
bool foldSqlExists = styler.GetPropertyInt("fold.sql.exists", 1) != 0;
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
@ -303,9 +307,13 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
}
} else if (strcmp(s, "begin") == 0) {
levelNext++;
} else if (strcmp(s, "end") == 0 ||
// DROP TABLE IF EXISTS or CREATE TABLE IF NOT EXISTS
strcmp(s, "exists") == 0) {
} else if ((strcmp(s, "end") == 0) ||
// // DROP TABLE IF EXISTS or CREATE TABLE IF NOT EXISTS
(foldSqlExists && (strcmp(s, "exists") == 0)) ||
// // SQL Anywhere permits IF ... ELSE ... ENDIF
// // will only be active if "endif" appears in the
// // keyword list.
(strcmp(s, "endif") == 0)) {
endFound = true;
levelNext--;
if (levelNext < SC_FOLDLEVELBASE) {

View File

@ -54,6 +54,7 @@ PropSet.cxx \
RESearch.cxx \
RunStyles.cxx \
ScintillaBase.cxx \
Selection.cxx \
StyleContext.cxx \
Style.cxx \
UniConversion.cxx \
@ -82,10 +83,12 @@ LineMarker.h \
Partitioning.h \
PerLine.h \
PositionCache.h \
PropSetSimple.h \
RESearch.h \
RunStyles.h \
ScintillaBase.h \
scintilla-marshal.h \
Selection.h \
SplitVector.h \
StyleContext.h \
Style.h \

View File

@ -188,11 +188,14 @@ int LineMarkers::AddMark(int line, int markerNum, int lines) {
// No existing markers so allocate one element per line
markers.InsertValue(0, lines, 0);
}
if (line >= markers.Length()) {
return -1;
}
if (!markers[line]) {
// Need new structure to hold marker handle
markers[line] = new MarkerHandleSet();
if (!markers[line])
return - 1;
return -1;
}
markers[line]->InsertHandle(handleCurrent, markerNum);
@ -359,6 +362,7 @@ void LineAnnotation::Init() {
void LineAnnotation::InsertLine(int line) {
if (annotations.Length()) {
annotations.EnsureLength(line);
annotations.Insert(line, 0);
}
}

View File

@ -352,6 +352,7 @@ static void GenerateFontSpecStrings(const char *fontName, int characterSet,
char tmp[300];
char *d1 = NULL, *d2 = NULL, *d3 = NULL;
strncpy(tmp, fontName, sizeof(tmp) - 1);
tmp[sizeof(tmp) - 1] = '\0';
d1 = strchr(tmp, '-');
// we know the first dash exists
d2 = strchr(d1 + 1, '-');
@ -666,7 +667,7 @@ Font::Font() : fid(0) {}
Font::~Font() {}
void Font::Create(const char *faceName, int characterSet, int size,
bool bold, bool italic, bool) {
bool bold, bool italic, int) {
Release();
fid = FontCached::FindOrCreate(faceName, characterSet, size, bold, italic);
}
@ -1287,7 +1288,11 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
pango_layout_set_text(layout, utfForm, len);
}
pango_layout_set_font_description(layout, PFont(font_)->pfd);
#ifdef PANGO_VERSION
PangoLayoutLine *pll = pango_layout_get_line_readonly(layout,0);
#else
PangoLayoutLine *pll = pango_layout_get_line(layout,0);
#endif
gdk_draw_layout_line(drawable, gc, xText, ybase, pll);
if (useGFree) {
g_free(utfForm);
@ -1371,6 +1376,44 @@ void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, int ybase, con
}
}
#ifdef USE_PANGO
class ClusterIterator {
PangoLayoutIter *iter;
PangoRectangle pos;
int lenPositions;
public:
bool finished;
int positionStart;
int position;
int distance;
int curIndex;
ClusterIterator(PangoLayout *layout, int len) : lenPositions(len), finished(false),
positionStart(0), position(0), distance(0) {
iter = pango_layout_get_iter(layout);
pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
}
~ClusterIterator() {
pango_layout_iter_free(iter);
}
void Next() {
positionStart = position;
if (pango_layout_iter_next_cluster(iter)) {
pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
position = PANGO_PIXELS(pos.x);
curIndex = pango_layout_iter_get_index(iter);
} else {
finished = true;
position = PANGO_PIXELS(pos.x + pos.width);
curIndex = lenPositions;
}
distance = position - positionStart;
}
};
#endif
void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positions) {
if (font_.GetID()) {
int totalWidth = 0;
@ -1384,32 +1427,24 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
return;
}
}
PangoRectangle pos;
pango_layout_set_font_description(layout, PFont(font_)->pfd);
if (et == UTF8) {
// Simple and direct as UTF-8 is native Pango encoding
pango_layout_set_text(layout, s, len);
PangoLayoutIter *iter = pango_layout_get_iter(layout);
pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
int i = 0;
while (pango_layout_iter_next_cluster(iter)) {
pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
int position = PANGO_PIXELS(pos.x);
int curIndex = pango_layout_iter_get_index(iter);
int places = curIndex - i;
int distance = position - positions[i-1];
while (i < curIndex) {
pango_layout_set_text(layout, s, len);
ClusterIterator iti(layout, lenPositions);
while (!iti.finished) {
iti.Next();
int places = iti.curIndex - i;
while (i < iti.curIndex) {
// Evenly distribute space among bytes of this cluster.
// Would be better to find number of characters and then
// divide evenly between characters with each byte of a character
// being at the same position.
positions[i] = position - (curIndex - 1 - i) * distance / places;
positions[i] = iti.position - (iti.curIndex - 1 - i) * iti.distance / places;
i++;
}
}
while (i < lenPositions)
positions[i++] = PANGO_PIXELS(pos.x + pos.width);
pango_layout_iter_free(iter);
PLATFORM_ASSERT(i == lenPositions);
} else {
int positionsCalculated = 0;
@ -1423,26 +1458,23 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
Converter convMeasure("UCS-2", CharacterSetID(characterSet), false);
pango_layout_set_text(layout, utfForm, strlen(utfForm));
int i = 0;
int utfIndex = 0;
PangoLayoutIter *iter = pango_layout_get_iter(layout);
pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
while (pango_layout_iter_next_cluster(iter)) {
pango_layout_iter_get_cluster_extents (iter, NULL, &pos);
int position = PANGO_PIXELS(pos.x);
int utfIndexNext = pango_layout_iter_get_index(iter);
while (utfIndex < utfIndexNext) {
int clusterStart = 0;
ClusterIterator iti(layout, strlen(utfForm));
while (!iti.finished) {
iti.Next();
int clusterEnd = iti.curIndex;
int places = g_utf8_strlen(utfForm + clusterStart, clusterEnd - clusterStart);
int place = 1;
while (clusterStart < clusterEnd) {
size_t lenChar = MultiByteLenFromIconv(convMeasure, s+i, len-i);
//size_t lenChar = mblen(s+i, MB_CUR_MAX);
while (lenChar--) {
positions[i++] = position;
positions[i++] = iti.position - (places - place) * iti.distance / places;
positionsCalculated++;
}
utfIndex += UTF8CharLength(utfForm+utfIndex);
clusterStart += UTF8CharLength(utfForm+clusterStart);
place++;
}
}
while (i < lenPositions)
positions[i++] = PANGO_PIXELS(pos.x + pos.width);
pango_layout_iter_free(iter);
delete []utfForm;
PLATFORM_ASSERT(i == lenPositions);
}
@ -1456,29 +1488,21 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
utfForm = UTF8FromLatin1(s, len);
}
pango_layout_set_text(layout, utfForm, len);
PangoLayoutIter *iter = pango_layout_get_iter(layout);
pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
int i = 0;
int positionStart = 0;
int clusterStart = 0;
// Each Latin1 input character may take 1 or 2 bytes in UTF-8
// and groups of up to 3 may be represented as ligatures.
while (pango_layout_iter_next_cluster(iter)) {
pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
int position = PANGO_PIXELS(pos.x);
int distance = position - positionStart;
int clusterEnd = pango_layout_iter_get_index(iter);
ClusterIterator iti(layout, strlen(utfForm));
while (!iti.finished) {
iti.Next();
int clusterEnd = iti.curIndex;
int ligatureLength = g_utf8_strlen(utfForm + clusterStart, clusterEnd - clusterStart);
PLATFORM_ASSERT(ligatureLength > 0 && ligatureLength <= 3);
for (int charInLig=0; charInLig<ligatureLength; charInLig++) {
positions[i++] = position - (ligatureLength - 1 - charInLig) * distance / ligatureLength;
positions[i++] = iti.position - (ligatureLength - 1 - charInLig) * iti.distance / ligatureLength;
}
positionStart = position;
clusterStart = clusterEnd;
}
while (i < lenPositions)
positions[i++] = PANGO_PIXELS(pos.x + pos.width);
pango_layout_iter_free(iter);
if (useGFree) {
g_free(utfForm);
} else {
@ -1575,7 +1599,11 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
}
pango_layout_set_text(layout, utfForm, len);
}
PangoLayoutLine *pangoLine = pango_layout_get_line(layout, 0);
#ifdef PANGO_VERSION
PangoLayoutLine *pangoLine = pango_layout_get_line_readonly(layout,0);
#else
PangoLayoutLine *pangoLine = pango_layout_get_line(layout,0);
#endif
pango_layout_line_get_extents(pangoLine, NULL, &pos);
if (useGFree) {
g_free(utfForm);
@ -1967,9 +1995,7 @@ class ListBoxX : public ListBox {
#if GTK_MAJOR_VERSION >= 2
GtkCellRenderer* pixbuf_renderer;
#endif
int lineHeight;
XPMSet xset;
bool unicodeMode;
int desiredVisibleRows;
unsigned int maxItemCharacters;
unsigned int aveCharWidth;
@ -1977,8 +2003,9 @@ public:
CallBackAction doubleClickAction;
void *doubleClickActionData;
ListBoxX() : list(0), pixhash(NULL), desiredVisibleRows(5), maxItemCharacters(0),
doubleClickAction(NULL), doubleClickActionData(NULL) {
ListBoxX() : list(0), pixhash(NULL),
desiredVisibleRows(5), maxItemCharacters(0),
aveCharWidth(1), doubleClickAction(NULL), doubleClickActionData(NULL) {
#if GTK_MAJOR_VERSION < 2
current = 0;
#endif
@ -2718,16 +2745,35 @@ long Platform::SendScintillaPointer(
reinterpret_cast<sptr_t>(lParam));
}
bool Platform::IsDBCSLeadByte(int /* codePage */, char /* ch */) {
bool Platform::IsDBCSLeadByte(int codePage, char ch) {
// Byte ranges found in Wikipedia articles with relevant search strings in each case
unsigned char uch = static_cast<unsigned char>(ch);
switch (codePage) {
case 932:
// Shift_jis
return ((uch >= 0x81) && (uch <= 0x9F)) ||
((uch >= 0xE0) && (uch <= 0xEF));
case 936:
// GBK
return (uch >= 0x81) && (uch <= 0xFE);
case 950:
// Big5
return (uch >= 0x81) && (uch <= 0xFE);
// Korean EUC-KR may be code page 949.
}
return false;
}
int Platform::DBCSCharLength(int, const char *s) {
int bytes = mblen(s, MB_CUR_MAX);
if (bytes >= 1)
return bytes;
else
return 1;
int Platform::DBCSCharLength(int codePage, const char *s) {
if (codePage == 932 || codePage == 936 || codePage == 950) {
return IsDBCSLeadByte(codePage, s[0]) ? 2 : 1;
} else {
int bytes = mblen(s, MB_CUR_MAX);
if (bytes >= 1)
return bytes;
else
return 1;
}
}
int Platform::DBCSCharMaxLength() {

View File

@ -10,6 +10,8 @@
#include <stdio.h>
#include <ctype.h>
#include <vector>
#include "Platform.h"
#include "Scintilla.h"
@ -28,6 +30,7 @@
#include "CharClassify.h"
#include "Decoration.h"
#include "Document.h"
#include "Selection.h"
#include "PositionCache.h"
#ifdef SCI_NAMESPACE
@ -46,11 +49,11 @@ LineLayout::LineLayout(int maxLineLength_) :
inCache(false),
maxLineLength(-1),
numCharsInLine(0),
numCharsBeforeEOL(0),
validity(llInvalid),
xHighlightGuide(0),
highlightColumn(0),
selStart(0),
selEnd(0),
psel(NULL),
containsCaret(false),
edgeColumn(0),
chars(0),
@ -115,12 +118,7 @@ int LineLayout::LineLastVisible(int line) const {
if (line < 0) {
return 0;
} else if ((line >= lines-1) || !lineStarts) {
int startLine = LineStart(line);
int endLine = numCharsInLine;
while ((endLine > startLine) && IsEOLChar(chars[endLine-1])) {
endLine--;
}
return endLine;
return numCharsBeforeEOL;
} else {
return lineStarts[line+1];
}
@ -135,8 +133,6 @@ void LineLayout::SetLineStart(int line, int start) {
if ((line >= lenLineStarts) && (line != 0)) {
int newMaxLines = line + 20;
int *newLineStarts = new int[newMaxLines];
if (!newLineStarts)
return;
for (int i = 0; i < newMaxLines; i++) {
if (i < lenLineStarts)
newLineStarts[i] = lineStarts[i];
@ -201,6 +197,10 @@ int LineLayout::FindBefore(int x, int lower, int upper) const {
return lower;
}
int LineLayout::EndLineStyle() const {
return styles[numCharsBeforeEOL > 0 ? numCharsBeforeEOL-1 : 0];
}
LineLayoutCache::LineLayoutCache() :
level(0), length(0), size(0), cache(0),
allInvalidated(false), styleClock(-1), useCount(0) {
@ -386,7 +386,7 @@ static int NextBadU(const char *s, int p, int len, int &trailBytes) {
return -1;
}
BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart) :
BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection) :
ll(ll_),
lineStart(lineStart_),
lineEnd(lineEnd_),
@ -412,9 +412,19 @@ BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posL
nextBreak--;
}
if (ll->selStart != ll->selEnd) {
Insert(ll->selStart - posLineStart - 1);
Insert(ll->selEnd - posLineStart - 1);
if (breakForSelection) {
SelectionPosition posStart(posLineStart);
SelectionPosition posEnd(posLineStart + lineEnd);
SelectionSegment segmentLine(posStart, posEnd);
for (size_t r=0; r<ll->psel->Count(); r++) {
SelectionSegment portion = ll->psel->Range(r).Intersect(segmentLine);
if (!(portion.start == portion.end)) {
if (portion.start.IsValid())
Insert(portion.start.Position() - posLineStart - 1);
if (portion.end.IsValid())
Insert(portion.end.Position() - posLineStart - 1);
}
}
}
Insert(ll->edgeColumn - 1);

View File

@ -2,7 +2,7 @@
/** @file PositionCache.h
** Classes for caching layout information.
**/
// Copyright 1998-2007 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef POSITIONCACHE_H
@ -30,11 +30,11 @@ public:
enum { wrapWidthInfinite = 0x7ffffff };
int maxLineLength;
int numCharsInLine;
int numCharsBeforeEOL;
enum validLevel { llInvalid, llCheckTextAndStyle, llPositions, llLines } validity;
int xHighlightGuide;
bool highlightColumn;
int selStart;
int selEnd;
Selection *psel;
bool containsCaret;
int edgeColumn;
char *chars;
@ -66,6 +66,7 @@ public:
char bracesMatchStyle, int xHighlight);
void RestoreBracesHighlight(Range rangeLine, Position braces[]);
int FindBefore(int x, int lower, int upper) const;
int EndLineStyle() const;
};
/**
@ -135,7 +136,7 @@ class BreakFinder {
int subBreak;
void Insert(int val);
public:
BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart);
BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection);
~BreakFinder();
int First();
int Next();

View File

@ -11,370 +11,53 @@
#include <string.h>
#include <stdio.h>
#ifdef _MSC_VER
// Visual C++ doesn't like unreachable code or long decorated names in its own headers.
#pragma warning(disable: 4018 4100 4245 4511 4512 4663 4702 4786)
#endif
#include <string>
#include <map>
#include "Platform.h"
#include "PropSet.h"
#include "PropSetSimple.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
// The comparison and case changing functions here assume ASCII
// or extended ASCII such as the normal Windows code page.
typedef std::map<std::string, std::string> mapss;
static inline char MakeUpperCase(char ch) {
if (ch < 'a' || ch > 'z')
return ch;
else
return static_cast<char>(ch - 'a' + 'A');
PropSetSimple::PropSetSimple() {
mapss *props = new mapss;
impl = static_cast<void *>(props);
}
static inline bool IsLetter(char ch) {
return ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'));
PropSetSimple::~PropSetSimple() {
mapss *props = static_cast<mapss *>(impl);
delete props;
impl = 0;
}
inline bool IsASpace(unsigned int ch) {
return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
}
int CompareCaseInsensitive(const char *a, const char *b) {
while (*a && *b) {
if (*a != *b) {
char upperA = MakeUpperCase(*a);
char upperB = MakeUpperCase(*b);
if (upperA != upperB)
return upperA - upperB;
}
a++;
b++;
}
// Either *a or *b is nul
return *a - *b;
}
int CompareNCaseInsensitive(const char *a, const char *b, size_t len) {
while (*a && *b && len) {
if (*a != *b) {
char upperA = MakeUpperCase(*a);
char upperB = MakeUpperCase(*b);
if (upperA != upperB)
return upperA - upperB;
}
a++;
b++;
len--;
}
if (len == 0)
return 0;
else
// Either *a or *b is nul
return *a - *b;
}
bool EqualCaseInsensitive(const char *a, const char *b) {
return 0 == CompareCaseInsensitive(a, b);
}
// Since the CaseInsensitive functions declared in SString
// are implemented here, I will for now put the non-inline
// implementations of the SString members here as well, so
// that I can quickly see what effect this has.
SString::SString(int i) : sizeGrowth(sizeGrowthDefault) {
char number[32];
sprintf(number, "%0d", i);
s = StringAllocate(number);
sSize = sLen = (s) ? strlen(s) : 0;
}
SString::SString(double d, int precision) : sizeGrowth(sizeGrowthDefault) {
char number[32];
sprintf(number, "%.*f", precision, d);
s = StringAllocate(number);
sSize = sLen = (s) ? strlen(s) : 0;
}
bool SString::grow(lenpos_t lenNew) {
while (sizeGrowth * 6 < lenNew) {
sizeGrowth *= 2;
}
char *sNew = new char[lenNew + sizeGrowth + 1];
if (sNew) {
if (s) {
memcpy(sNew, s, sLen);
delete []s;
}
s = sNew;
s[sLen] = '\0';
sSize = lenNew + sizeGrowth;
}
return sNew != 0;
}
SString &SString::assign(const char *sOther, lenpos_t sSize_) {
if (!sOther) {
sSize_ = 0;
} else if (sSize_ == measure_length) {
sSize_ = strlen(sOther);
}
if (sSize > 0 && sSize_ <= sSize) { // Does not allocate new buffer if the current is big enough
if (s && sSize_) {
memcpy(s, sOther, sSize_);
}
s[sSize_] = '\0';
sLen = sSize_;
} else {
delete []s;
s = StringAllocate(sOther, sSize_);
if (s) {
sSize = sSize_; // Allow buffer bigger than real string, thus providing space to grow
sLen = sSize_;
} else {
sSize = sLen = 0;
}
}
return *this;
}
bool SString::operator==(const SString &sOther) const {
if ((s == 0) && (sOther.s == 0))
return true;
if ((s == 0) || (sOther.s == 0))
return false;
return strcmp(s, sOther.s) == 0;
}
bool SString::operator==(const char *sOther) const {
if ((s == 0) && (sOther == 0))
return true;
if ((s == 0) || (sOther == 0))
return false;
return strcmp(s, sOther) == 0;
}
SString SString::substr(lenpos_t subPos, lenpos_t subLen) const {
if (subPos >= sLen) {
return SString(); // return a null string if start index is out of bounds
}
if ((subLen == measure_length) || (subPos + subLen > sLen)) {
subLen = sLen - subPos; // can't substr past end of source string
}
return SString(s, subPos, subPos + subLen);
}
SString &SString::lowercase(lenpos_t subPos, lenpos_t subLen) {
if ((subLen == measure_length) || (subPos + subLen > sLen)) {
subLen = sLen - subPos; // don't apply past end of string
}
for (lenpos_t i = subPos; i < subPos + subLen; i++) {
if (s[i] < 'A' || s[i] > 'Z')
continue;
else
s[i] = static_cast<char>(s[i] - 'A' + 'a');
}
return *this;
}
SString &SString::uppercase(lenpos_t subPos, lenpos_t subLen) {
if ((subLen == measure_length) || (subPos + subLen > sLen)) {
subLen = sLen - subPos; // don't apply past end of string
}
for (lenpos_t i = subPos; i < subPos + subLen; i++) {
if (s[i] < 'a' || s[i] > 'z')
continue;
else
s[i] = static_cast<char>(s[i] - 'a' + 'A');
}
return *this;
}
SString &SString::append(const char *sOther, lenpos_t sLenOther, char sep) {
if (!sOther) {
return *this;
}
if (sLenOther == measure_length) {
sLenOther = strlen(sOther);
}
int lenSep = 0;
if (sLen && sep) { // Only add a separator if not empty
lenSep = 1;
}
lenpos_t lenNew = sLen + sLenOther + lenSep;
// Conservative about growing the buffer: don't do it, unless really needed
if ((lenNew < sSize) || (grow(lenNew))) {
if (lenSep) {
s[sLen] = sep;
sLen++;
}
memcpy(&s[sLen], sOther, sLenOther);
sLen += sLenOther;
s[sLen] = '\0';
}
return *this;
}
SString &SString::insert(lenpos_t pos, const char *sOther, lenpos_t sLenOther) {
if (!sOther || pos > sLen) {
return *this;
}
if (sLenOther == measure_length) {
sLenOther = strlen(sOther);
}
lenpos_t lenNew = sLen + sLenOther;
// Conservative about growing the buffer: don't do it, unless really needed
if ((lenNew < sSize) || grow(lenNew)) {
lenpos_t moveChars = sLen - pos + 1;
for (lenpos_t i = moveChars; i > 0; i--) {
s[pos + sLenOther + i - 1] = s[pos + i - 1];
}
memcpy(s + pos, sOther, sLenOther);
sLen = lenNew;
}
return *this;
}
/**
* Remove @a len characters from the @a pos position, included.
* Characters at pos + len and beyond replace characters at pos.
* If @a len is 0, or greater than the length of the string
* starting at @a pos, the string is just truncated at @a pos.
*/
void SString::remove(lenpos_t pos, lenpos_t len) {
if (pos >= sLen) {
return;
}
if (len < 1 || pos + len >= sLen) {
s[pos] = '\0';
sLen = pos;
} else {
for (lenpos_t i = pos; i < sLen - len + 1; i++) {
s[i] = s[i+len];
}
sLen -= len;
}
}
bool SString::startswith(const char *prefix) {
lenpos_t lenPrefix = strlen(prefix);
if (lenPrefix > sLen) {
return false;
}
return strncmp(s, prefix, lenPrefix) == 0;
}
bool SString::endswith(const char *suffix) {
lenpos_t lenSuffix = strlen(suffix);
if (lenSuffix > sLen) {
return false;
}
return strncmp(s + sLen - lenSuffix, suffix, lenSuffix) == 0;
}
int SString::search(const char *sFind, lenpos_t start) const {
if (start < sLen) {
const char *sFound = strstr(s + start, sFind);
if (sFound) {
return sFound - s;
}
}
return -1;
}
int SString::substitute(char chFind, char chReplace) {
int c = 0;
char *t = s;
while (t) {
t = strchr(t, chFind);
if (t) {
*t = chReplace;
t++;
c++;
}
}
return c;
}
int SString::substitute(const char *sFind, const char *sReplace) {
int c = 0;
lenpos_t lenFind = strlen(sFind);
lenpos_t lenReplace = strlen(sReplace);
int posFound = search(sFind);
while (posFound >= 0) {
remove(posFound, lenFind);
insert(posFound, sReplace, lenReplace);
posFound = search(sFind, posFound + lenReplace);
c++;
}
return c;
}
char *SContainer::StringAllocate(lenpos_t len) {
if (len != measure_length) {
return new char[len + 1];
} else {
return 0;
}
}
char *SContainer::StringAllocate(const char *s, lenpos_t len) {
if (s == 0) {
return 0;
}
if (len == measure_length) {
len = strlen(s);
}
char *sNew = new char[len + 1];
if (sNew) {
memcpy(sNew, s, len);
sNew[len] = '\0';
}
return sNew;
}
// End SString functions
PropSet::PropSet() {
superPS = 0;
for (int root = 0; root < hashRoots; root++)
props[root] = 0;
}
PropSet::~PropSet() {
superPS = 0;
Clear();
}
void PropSet::Set(const char *key, const char *val, int lenKey, int lenVal) {
void PropSetSimple::Set(const char *key, const char *val, int lenKey, int lenVal) {
mapss *props = static_cast<mapss *>(impl);
if (!*key) // Empty keys are not supported
return;
if (lenKey == -1)
lenKey = static_cast<int>(strlen(key));
if (lenVal == -1)
lenVal = static_cast<int>(strlen(val));
unsigned int hash = HashString(key, lenKey);
for (Property *p = props[hash % hashRoots]; p; p = p->next) {
if ((hash == p->hash) &&
((strlen(p->key) == static_cast<unsigned int>(lenKey)) &&
(0 == strncmp(p->key, key, lenKey)))) {
// Replace current value
delete [](p->val);
p->val = StringDup(val, lenVal);
return;
}
}
// Not found
Property *pNew = new Property;
if (pNew) {
pNew->hash = hash;
pNew->key = StringDup(key, lenKey);
pNew->val = StringDup(val, lenVal);
pNew->next = props[hash % hashRoots];
props[hash % hashRoots] = pNew;
}
(*props)[std::string(key, lenKey)] = std::string(val, lenVal);
}
void PropSet::Set(const char *keyVal) {
while (IsASpace(*keyVal))
static bool IsASpaceCharacter(unsigned int ch) {
return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
}
void PropSetSimple::Set(const char *keyVal) {
while (IsASpaceCharacter(*keyVal))
keyVal++;
const char *endVal = keyVal;
while (*endVal && (*endVal != '\n'))
@ -387,34 +70,7 @@ void PropSet::Set(const char *keyVal) {
}
}
void PropSet::Unset(const char *key, int lenKey) {
if (!*key) // Empty keys are not supported
return;
if (lenKey == -1)
lenKey = static_cast<int>(strlen(key));
unsigned int hash = HashString(key, lenKey);
Property *pPrev = NULL;
for (Property *p = props[hash % hashRoots]; p; p = p->next) {
if ((hash == p->hash) &&
((strlen(p->key) == static_cast<unsigned int>(lenKey)) &&
(0 == strncmp(p->key, key, lenKey)))) {
if (pPrev)
pPrev->next = p->next;
else
props[hash % hashRoots] = p->next;
if (p == enumnext)
enumnext = p->next; // Not that anyone should mix enum and Set / Unset.
delete [](p->key);
delete [](p->val);
delete p;
return;
} else {
pPrev = p;
}
}
}
void PropSet::SetMultiple(const char *s) {
void PropSetSimple::SetMultiple(const char *s) {
const char *eol = strchr(s, '\n');
while (eol) {
Set(s);
@ -424,16 +80,11 @@ void PropSet::SetMultiple(const char *s) {
Set(s);
}
SString PropSet::Get(const char *key) const {
unsigned int hash = HashString(key, strlen(key));
for (Property *p = props[hash % hashRoots]; p; p = p->next) {
if ((hash == p->hash) && (0 == strcmp(p->key, key))) {
return p->val;
}
}
if (superPS) {
// Failed here, so try in base property set
return superPS->Get(key);
const char *PropSetSimple::Get(const char *key) const {
mapss *props = static_cast<mapss *>(impl);
mapss::const_iterator keyPos = props->find(std::string(key));
if (keyPos != props->end()) {
return keyPos->second.c_str();
} else {
return "";
}
@ -456,300 +107,70 @@ struct VarChain {
const VarChain *link;
};
static int ExpandAllInPlace(const PropSet &props, SString &withVars, int maxExpands, const VarChain &blankVars = VarChain()) {
int varStart = withVars.search("$(");
while ((varStart >= 0) && (maxExpands > 0)) {
int varEnd = withVars.search(")", varStart+2);
if (varEnd < 0) {
static int ExpandAllInPlace(const PropSetSimple &props, std::string &withVars, int maxExpands, const VarChain &blankVars) {
size_t varStart = withVars.find("$(");
while ((varStart != std::string::npos) && (maxExpands > 0)) {
size_t varEnd = withVars.find(")", varStart+2);
if (varEnd == std::string::npos) {
break;
}
// For consistency, when we see '$(ab$(cde))', expand the inner variable first,
// regardless whether there is actually a degenerate variable named 'ab$(cde'.
int innerVarStart = withVars.search("$(", varStart+2);
while ((innerVarStart > varStart) && (innerVarStart < varEnd)) {
size_t innerVarStart = withVars.find("$(", varStart+2);
while ((innerVarStart != std::string::npos) && (innerVarStart > varStart) && (innerVarStart < varEnd)) {
varStart = innerVarStart;
innerVarStart = withVars.search("$(", varStart+2);
innerVarStart = withVars.find("$(", varStart+2);
}
SString var(withVars.c_str(), varStart + 2, varEnd);
SString val = props.Get(var.c_str());
std::string var(withVars.c_str(), varStart + 2, varEnd - varStart - 2);
std::string val = props.Get(var.c_str());
if (blankVars.contains(var.c_str())) {
val.clear(); // treat blankVar as an empty string (e.g. to block self-reference)
val = ""; // treat blankVar as an empty string (e.g. to block self-reference)
}
if (--maxExpands >= 0) {
maxExpands = ExpandAllInPlace(props, val, maxExpands, VarChain(var.c_str(), &blankVars));
}
withVars.remove(varStart, varEnd-varStart+1);
withVars.erase(varStart, varEnd-varStart+1);
withVars.insert(varStart, val.c_str(), val.length());
varStart = withVars.search("$(");
varStart = withVars.find("$(");
}
return maxExpands;
}
SString PropSet::GetExpanded(const char *key) const {
SString val = Get(key);
char *PropSetSimple::Expanded(const char *key) const {
std::string val = Get(key);
ExpandAllInPlace(*this, val, 100, VarChain(key));
return val;
}
SString PropSet::Expand(const char *withVars, int maxExpands) const {
SString val = withVars;
ExpandAllInPlace(*this, val, maxExpands);
return val;
}
int PropSet::GetInt(const char *key, int defaultValue) const {
SString val = GetExpanded(key);
if (val.length())
return val.value();
return defaultValue;
}
bool isprefix(const char *target, const char *prefix) {
while (*target && *prefix) {
if (*target != *prefix)
return false;
target++;
prefix++;
}
if (*prefix)
return false;
else
return true;
}
void PropSet::Clear() {
for (int root = 0; root < hashRoots; root++) {
Property *p = props[root];
while (p) {
Property *pNext = p->next;
p->hash = 0;
delete []p->key;
p->key = 0;
delete []p->val;
p->val = 0;
delete p;
p = pNext;
}
props[root] = 0;
}
}
char *PropSet::ToString() const {
size_t len=0;
for (int r = 0; r < hashRoots; r++) {
for (Property *p = props[r]; p; p = p->next) {
len += strlen(p->key) + 1;
len += strlen(p->val) + 1;
}
}
if (len == 0)
len = 1; // Return as empty string
char *ret = new char [len];
if (ret) {
char *w = ret;
for (int root = 0; root < hashRoots; root++) {
for (Property *p = props[root]; p; p = p->next) {
strcpy(w, p->key);
w += strlen(p->key);
*w++ = '=';
strcpy(w, p->val);
w += strlen(p->val);
*w++ = '\n';
}
}
ret[len-1] = '\0';
}
char *ret = new char [val.size() + 1];
strcpy(ret, val.c_str());
return ret;
}
/**
* Creates an array that points into each word in the string and puts \0 terminators
* after each word.
*/
static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) {
int prev = '\n';
int words = 0;
// For rapid determination of whether a character is a separator, build
// a look up table.
bool wordSeparator[256];
for (int i=0;i<256; i++) {
wordSeparator[i] = false;
char *PropSetSimple::ToString() const {
mapss *props = static_cast<mapss *>(impl);
std::string sval;
for (mapss::const_iterator it=props->begin(); it != props->end(); it++) {
sval += it->first;
sval += "=";
sval += it->second;
sval += "\n";
}
wordSeparator['\r'] = true;
wordSeparator['\n'] = true;
if (!onlyLineEnds) {
wordSeparator[' '] = true;
wordSeparator['\t'] = true;
}
for (int j = 0; wordlist[j]; j++) {
int curr = static_cast<unsigned char>(wordlist[j]);
if (!wordSeparator[curr] && wordSeparator[prev])
words++;
prev = curr;
}
char **keywords = new char *[words + 1];
if (keywords) {
words = 0;
prev = '\0';
size_t slen = strlen(wordlist);
for (size_t k = 0; k < slen; k++) {
if (!wordSeparator[static_cast<unsigned char>(wordlist[k])]) {
if (!prev) {
keywords[words] = &wordlist[k];
words++;
}
} else {
wordlist[k] = '\0';
}
prev = wordlist[k];
}
keywords[words] = &wordlist[slen];
*len = words;
} else {
*len = 0;
}
return keywords;
char *ret = new char [sval.size() + 1];
strcpy(ret, sval.c_str());
return ret;
}
void WordList::Clear() {
if (words) {
delete []list;
delete []words;
int PropSetSimple::GetInt(const char *key, int defaultValue) const {
char *val = Expanded(key);
if (val) {
int retVal = val[0] ? atoi(val) : defaultValue;
delete []val;
return retVal;
}
words = 0;
list = 0;
len = 0;
sorted = false;
}
void WordList::Set(const char *s) {
list = StringDup(s);
sorted = false;
words = ArrayFromWordList(list, &len, onlyLineEnds);
}
extern "C" int cmpString(const void *a1, const void *a2) {
// Can't work out the correct incantation to use modern casts here
return strcmp(*(char**)(a1), *(char**)(a2));
}
static void SortWordList(char **words, unsigned int len) {
qsort(reinterpret_cast<void*>(words), len, sizeof(*words),
cmpString);
}
bool WordList::InList(const char *s) {
if (0 == words)
return false;
if (!sorted) {
sorted = true;
SortWordList(words, len);
for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
starts[k] = -1;
for (int l = len - 1; l >= 0; l--) {
unsigned char indexChar = words[l][0];
starts[indexChar] = l;
}
}
unsigned char firstChar = s[0];
int j = starts[firstChar];
if (j >= 0) {
while ((unsigned char)words[j][0] == firstChar) {
if (s[1] == words[j][1]) {
const char *a = words[j] + 1;
const char *b = s + 1;
while (*a && *a == *b) {
a++;
b++;
}
if (!*a && !*b)
return true;
}
j++;
}
}
j = starts['^'];
if (j >= 0) {
while (words[j][0] == '^') {
const char *a = words[j] + 1;
const char *b = s;
while (*a && *a == *b) {
a++;
b++;
}
if (!*a)
return true;
j++;
}
}
return false;
}
/** similar to InList, but word s can be a substring of keyword.
* eg. the keyword define is defined as def~ine. This means the word must start
* with def to be a keyword, but also defi, defin and define are valid.
* The marker is ~ in this case.
*/
bool WordList::InListAbbreviated(const char *s, const char marker) {
if (0 == words)
return false;
if (!sorted) {
sorted = true;
SortWordList(words, len);
for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
starts[k] = -1;
for (int l = len - 1; l >= 0; l--) {
unsigned char indexChar = words[l][0];
starts[indexChar] = l;
}
}
unsigned char firstChar = s[0];
int j = starts[firstChar];
if (j >= 0) {
while (words[j][0] == firstChar) {
bool isSubword = false;
int start = 1;
if (words[j][1] == marker) {
isSubword = true;
start++;
}
if (s[1] == words[j][start]) {
const char *a = words[j] + start;
const char *b = s + 1;
while (*a && *a == *b) {
a++;
if (*a == marker) {
isSubword = true;
a++;
}
b++;
}
if ((!*a || isSubword) && !*b)
return true;
}
j++;
}
}
j = starts['^'];
if (j >= 0) {
while (words[j][0] == '^') {
const char *a = words[j] + 1;
const char *b = s;
while (*a && *a == *b) {
a++;
b++;
}
if (!*a)
return true;
j++;
}
}
return false;
return defaultValue;
}

33
scintilla/PropSetSimple.h Normal file
View File

@ -0,0 +1,33 @@
// Scintilla source code edit control
/** @file PropSetSimple.h
** A basic string to string map.
**/
// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef PROPSETSIMPLE_H
#define PROPSETSIMPLE_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
class PropSetSimple : public PropertyGet {
void *impl;
void Set(const char *keyVal);
public:
PropSetSimple();
virtual ~PropSetSimple();
void Set(const char *key, const char *val, int lenKey=-1, int lenVal=-1);
void SetMultiple(const char *);
const char *Get(const char *key) const;
char *Expanded(const char *key) const;
char *ToString() const;
int GetInt(const char *key, int defaultValue=0) const;
};
#ifdef SCI_NAMESPACE
}
#endif
#endif

View File

@ -198,6 +198,8 @@
* matches: foo-foo fo-fo fob-fob foobar-foobar ...
*/
#include <stdlib.h>
#include "CharClassify.h"
#include "RESearch.h"
@ -416,6 +418,7 @@ int RESearch::GetBackslashExpression(
ChSet(static_cast<unsigned char>(c));
}
}
break;
case 'w':
for (c = 0; c < MAXCHR; c++) {
if (iswordc(static_cast<unsigned char>(c))) {

View File

@ -23,7 +23,6 @@ class SVector {
int *v; ///< The vector
unsigned int size; ///< Number of elements allocated
unsigned int len; ///< Number of elements used in vector
bool allocFailure; ///< A memory allocation call has failed
/** Internally allocate more elements than the user wants
* to avoid thrashing the memory allocator. */
@ -33,12 +32,8 @@ class SVector {
else
newSize = (newSize * 3) / 2;
int* newv = new int[newSize];
if (!newv) {
allocFailure = true;
return;
}
size = newSize;
unsigned int i=0;
unsigned int i=0;
for (; i<len; i++) {
newv[i] = v[i];
}
@ -51,7 +46,6 @@ class SVector {
public:
SVector() {
allocFailure = false;
v = 0;
len = 0;
size = 0;
@ -61,33 +55,27 @@ public:
}
/// Constructor from another vector.
SVector(const SVector &other) {
allocFailure = false;
v = 0;
len = 0;
size = 0;
if (other.Length() > 0) {
SizeTo(other.Length());
if (!allocFailure) {
for (int i=0;i<other.Length();i++)
v[i] = other.v[i];
len = other.Length();
}
for (int i=0;i<other.Length();i++)
v[i] = other.v[i];
len = other.Length();
}
}
/// Copy constructor.
SVector &operator=(const SVector &other) {
if (this != &other) {
delete []v;
allocFailure = false;
v = 0;
len = 0;
size = 0;
if (other.Length() > 0) {
SizeTo(other.Length());
if (!allocFailure) {
for (int i=0;i<other.Length();i++)
v[i] = other.v[i];
}
for (int i=0;i<other.Length();i++)
v[i] = other.v[i];
len = other.Length();
}
}

View File

@ -10,10 +10,13 @@
#include <stdio.h>
#include <ctype.h>
#include <vector>
#include "Platform.h"
#include "Scintilla.h"
#include "PropSet.h"
#include "PropSetSimple.h"
#ifdef SCI_LEXER
#include "SciLexer.h"
#include "Accessor.h"
@ -36,6 +39,7 @@
#include "CharClassify.h"
#include "Decoration.h"
#include "Document.h"
#include "Selection.h"
#include "PositionCache.h"
#include "Editor.h"
#include "ScintillaBase.h"
@ -190,7 +194,7 @@ int ScintillaBase::KeyCommand(unsigned int iMessage) {
ct.CallTipCancel();
}
if ((iMessage == SCI_DELETEBACK) || (iMessage == SCI_DELETEBACKNOTLINE)) {
if (currentPos <= ct.posStartCallTip) {
if (sel.MainCaret() <= ct.posStartCallTip) {
ct.CallTipCancel();
}
}
@ -212,24 +216,24 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
const char *typeSep = strchr(list, ac.GetTypesep());
size_t lenInsert = (typeSep) ? (typeSep-list) : strlen(list);
if (ac.ignoreCase) {
SetEmptySelection(currentPos - lenEntered);
pdoc->DeleteChars(currentPos, lenEntered);
SetEmptySelection(currentPos);
pdoc->InsertString(currentPos, list, lenInsert);
SetEmptySelection(currentPos + lenInsert);
SetEmptySelection(sel.MainCaret() - lenEntered);
pdoc->DeleteChars(sel.MainCaret(), lenEntered);
SetEmptySelection(sel.MainCaret());
pdoc->InsertString(sel.MainCaret(), list, lenInsert);
SetEmptySelection(sel.MainCaret() + lenInsert);
} else {
SetEmptySelection(currentPos);
pdoc->InsertString(currentPos, list + lenEntered, lenInsert - lenEntered);
SetEmptySelection(currentPos + lenInsert - lenEntered);
SetEmptySelection(sel.MainCaret());
pdoc->InsertString(sel.MainCaret(), list + lenEntered, lenInsert - lenEntered);
SetEmptySelection(sel.MainCaret() + lenInsert - lenEntered);
}
return;
}
}
ac.Start(wMain, idAutoComplete, currentPos, LocationFromPosition(currentPos),
ac.Start(wMain, idAutoComplete, sel.MainCaret(), PointMainCaret(),
lenEntered, vs.lineHeight, IsUnicodeMode());
PRectangle rcClient = GetClientRectangle();
Point pt = LocationFromPosition(currentPos - lenEntered);
Point pt = LocationFromPosition(sel.MainCaret() - lenEntered);
PRectangle rcPopupBounds = wMain.GetMonitorRect(pt);
if (rcPopupBounds.Height() == 0)
rcPopupBounds = rcClient;
@ -239,7 +243,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
if (pt.x >= rcClient.right - widthLB) {
HorizontalScrollTo(xOffset + pt.x - rcClient.right + widthLB);
Redraw();
pt = LocationFromPosition(currentPos);
pt = PointMainCaret();
}
PRectangle rcac;
rcac.left = pt.x - ac.lb->CaretFromEdge();
@ -305,7 +309,7 @@ void ScintillaBase::AutoCompleteMoveToCurrentWord() {
char wordCurrent[1000];
int i;
int startWord = ac.posStart - ac.startLen;
for (i = startWord; i < currentPos && i - startWord < 1000; i++)
for (i = startWord; i < sel.MainCaret() && i - startWord < 1000; i++)
wordCurrent[i - startWord] = pdoc->CharAt(i);
wordCurrent[Platform::Minimum(i - startWord, 999)] = '\0';
ac.Select(wordCurrent);
@ -322,9 +326,9 @@ void ScintillaBase::AutoCompleteCharacterAdded(char ch) {
}
void ScintillaBase::AutoCompleteCharacterDeleted() {
if (currentPos < ac.posStart - ac.startLen) {
if (sel.MainCaret() < ac.posStart - ac.startLen) {
AutoCompleteCancel();
} else if (ac.cancelAtStartPos && (currentPos <= ac.posStart)) {
} else if (ac.cancelAtStartPos && (sel.MainCaret() <= ac.posStart)) {
AutoCompleteCancel();
} else {
AutoCompleteMoveToCurrentWord();
@ -349,7 +353,6 @@ void ScintillaBase::AutoCompleteCompleted() {
ac.Show(false);
listSelected = selected;
SCNotification scn = {0};
scn.nmhdr.code = listType > 0 ? SCN_USERLISTSELECTION : SCN_AUTOCSELECTION;
scn.message = 0;
@ -357,7 +360,7 @@ void ScintillaBase::AutoCompleteCompleted() {
scn.listType = listType;
Position firstPos = ac.posStart - ac.startLen;
scn.lParam = firstPos;
scn.text = listSelected.c_str();
scn.text = selected;
NotifyParent(scn);
if (!ac.Active())
@ -367,22 +370,20 @@ void ScintillaBase::AutoCompleteCompleted() {
if (listType > 0)
return;
Position endPos = currentPos;
Position endPos = sel.MainCaret();
if (ac.dropRestOfWord)
endPos = pdoc->ExtendWordSelect(endPos, 1, true);
if (endPos < firstPos)
return;
pdoc->BeginUndoAction();
UndoGroup ug(pdoc);
if (endPos != firstPos) {
pdoc->DeleteChars(firstPos, endPos - firstPos);
}
SetEmptySelection(ac.posStart);
if (item != -1) {
SString piece = selected;
pdoc->InsertCString(firstPos, piece.c_str());
SetEmptySelection(firstPos + static_cast<int>(piece.length()));
pdoc->InsertCString(firstPos, selected);
SetEmptySelection(firstPos + static_cast<int>(strlen(selected)));
}
pdoc->EndUndoAction();
}
int ScintillaBase::AutoCompleteGetCurrent() {
@ -418,7 +419,7 @@ void ScintillaBase::CallTipShow(Point pt, const char *defn) {
if (ct.UseStyleCallTip()) {
ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back);
}
PRectangle rc = ct.CallTipStart(currentPos, pt,
PRectangle rc = ct.CallTipStart(sel.MainCaret(), pt,
defn,
vs.styles[ctStyle].fontName,
vs.styles[ctStyle].sizeZoomed,
@ -453,10 +454,10 @@ void ScintillaBase::ContextMenu(Point pt) {
AddToPopUp("Undo", idcmdUndo, writable && pdoc->CanUndo());
AddToPopUp("Redo", idcmdRedo, writable && pdoc->CanRedo());
AddToPopUp("");
AddToPopUp("Cut", idcmdCut, writable && currentPos != anchor);
AddToPopUp("Copy", idcmdCopy, currentPos != anchor);
AddToPopUp("Cut", idcmdCut, writable && !sel.Empty());
AddToPopUp("Copy", idcmdCopy, !sel.Empty());
AddToPopUp("Paste", idcmdPaste, writable && WndProc(SCI_CANPASTE, 0, 0));
AddToPopUp("Delete", idcmdDelete, writable && currentPos != anchor);
AddToPopUp("Delete", idcmdDelete, writable && !sel.Empty());
AddToPopUp("");
AddToPopUp("Select All", idcmdSelectAll);
popup.Show(pt, wMain);
@ -480,6 +481,8 @@ void ScintillaBase::SetLexer(uptr_t wParam) {
lexCurrent = LexerModule::Find(lexLanguage);
if (!lexCurrent)
lexCurrent = LexerModule::Find(SCLEX_NULL);
int bits = lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
vs.EnsureStyle((1 << bits) - 1);
}
void ScintillaBase::SetLexerLanguage(const char *languageName) {
@ -489,6 +492,8 @@ void ScintillaBase::SetLexerLanguage(const char *languageName) {
lexCurrent = LexerModule::Find(SCLEX_NULL);
if (lexCurrent)
lexLanguage = lexCurrent->GetLanguage();
int bits = lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
vs.EnsureStyle((1 << bits) - 1);
}
void ScintillaBase::Colourise(int start, int end) {
@ -725,25 +730,17 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
reinterpret_cast<const char *>(lParam));
break;
case SCI_GETPROPERTY: {
SString val = props.Get(reinterpret_cast<const char *>(wParam));
const int n = val.length();
if (lParam != 0) {
char *ptr = reinterpret_cast<char *>(lParam);
memcpy(ptr, val.c_str(), n);
ptr[n] = '\0'; // terminate
}
return n; // Not including NUL
}
case SCI_GETPROPERTY:
return StringResult(lParam, props.Get(reinterpret_cast<const char *>(wParam)));
case SCI_GETPROPERTYEXPANDED: {
SString val = props.GetExpanded(reinterpret_cast<const char *>(wParam));
const int n = val.length();
char *val = props.Expanded(reinterpret_cast<const char *>(wParam));
const int n = strlen(val);
if (lParam != 0) {
char *ptr = reinterpret_cast<char *>(lParam);
memcpy(ptr, val.c_str(), n);
ptr[n] = '\0'; // terminate
strcpy(ptr, val);
}
delete []val;
return n; // Not including NUL
}
@ -761,8 +758,12 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
SetLexerLanguage(reinterpret_cast<const char *>(lParam));
break;
case SCI_GETLEXERLANGUAGE:
return StringResult(lParam, lexCurrent ? lexCurrent->languageName : "");
case SCI_GETSTYLEBITSNEEDED:
return lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
#endif
default:

View File

@ -16,8 +16,8 @@ namespace Scintilla {
*/
class ScintillaBase : public Editor {
// Private so ScintillaBase objects can not be copied
ScintillaBase(const ScintillaBase &) : Editor() {}
ScintillaBase &operator=(const ScintillaBase &) { return *this; }
ScintillaBase(const ScintillaBase &);
ScintillaBase &operator=(const ScintillaBase &);
protected:
/** Enumeration of commands and child windows. */
@ -41,15 +41,13 @@ protected:
CallTip ct;
int listType; ///< 0 is an autocomplete list
SString listSelected; ///< Receives listbox selected string
int maxListWidth; /// Maximum width of list, in average character widths
bool performingStyle; ///< Prevent reentrance
#ifdef SCI_LEXER
bool performingStyle; ///< Prevent reentrance
int lexLanguage;
const LexerModule *lexCurrent;
PropSet props;
PropSetSimple props;
enum {numWordLists=KEYWORDSET_MAX+1};
WordList *keyWordLists[numWordLists+1];
void SetLexer(uptr_t wParam);

View File

@ -10,6 +10,9 @@
#include <ctype.h>
#include <time.h>
#include <string>
#include <vector>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
@ -24,6 +27,7 @@
#ifdef SCI_LEXER
#include "SciLexer.h"
#include "PropSet.h"
#include "PropSetSimple.h"
#include "Accessor.h"
#include "KeyWords.h"
#endif
@ -44,9 +48,9 @@
#include "Decoration.h"
#include "CharClassify.h"
#include "Document.h"
#include "Selection.h"
#include "PositionCache.h"
#include "Editor.h"
#include "SString.h"
#include "ScintillaBase.h"
#include "UniConversion.h"
@ -116,6 +120,7 @@ class ScintillaGTK : public ScintillaBase {
bool capturedMouse;
bool dragWasDropped;
int lastKey;
int rectangularSelectionModifier;
GtkWidgetClass *parentClass;
@ -151,8 +156,8 @@ class ScintillaGTK : public ScintillaBase {
GdkRegion *rgnUpdate;
// Private so ScintillaGTK objects can not be copied
ScintillaGTK(const ScintillaGTK &) : ScintillaBase() {}
ScintillaGTK &operator=(const ScintillaGTK &) { return * this; }
ScintillaGTK(const ScintillaGTK &);
ScintillaGTK &operator=(const ScintillaGTK &);
public:
ScintillaGTK(_ScintillaObject *sci_);
@ -346,7 +351,7 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) :
adjustmentv(0), adjustmenth(0),
scrollBarWidth(30), scrollBarHeight(30),
capturedMouse(false), dragWasDropped(false),
lastKey(0), parentClass(0),
lastKey(0), rectangularSelectionModifier(SCMOD_CTRL), parentClass(0),
#ifdef INTERNATIONAL_INPUT
#if GTK_MAJOR_VERSION < 2
ic(NULL),
@ -361,6 +366,12 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) :
sci = sci_;
wMain = GTK_WIDGET(sci);
#if PLAT_GTK_WIN32
rectangularSelectionModifier = SCMOD_ALT;
#else
rectangularSelectionModifier = SCMOD_CTRL;
#endif
#if PLAT_GTK_WIN32
// There does not seem to be a real standard for indicating that the clipboard
// contains a rectangular selection, so copy Developer Studio.
@ -990,7 +1001,12 @@ int ScintillaGTK::EncodedFromUTF8(char *utf8, char *encoded) {
}
bool ScintillaGTK::ValidCodePage(int codePage) const {
return codePage == 0 || codePage == SC_CP_UTF8 || codePage == SC_CP_DBCS;
return codePage == 0
|| codePage == SC_CP_UTF8
|| codePage == 932
|| codePage == 936
|| codePage == 950
|| codePage == SC_CP_DBCS;
}
sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
@ -1019,6 +1035,13 @@ sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam
return EncodedFromUTF8(reinterpret_cast<char*>(wParam),
reinterpret_cast<char*>(lParam));
case SCI_SETRECTANGULARSELECTIONMODIFIER:
rectangularSelectionModifier = wParam;
break;
case SCI_GETRECTANGULARSELECTIONMODIFIER:
return rectangularSelectionModifier;
default:
return ScintillaBase::WndProc(iMessage, wParam, lParam);
}
@ -1345,7 +1368,7 @@ void ScintillaGTK::CopyToClipboard(const SelectionText &selectedText) {
}
void ScintillaGTK::Copy() {
if (currentPos != anchor) {
if (!sel.Empty()) {
#ifndef USE_GTK_CLIPBOARD
CopySelectionRange(&copyText);
gtk_selection_owner_set(GTK_WIDGET(PWidget(wMain)),
@ -1357,7 +1380,7 @@ void ScintillaGTK::Copy() {
StoreOnClipboard(clipText);
#endif
#if PLAT_GTK_WIN32
if (selType == selRectangle) {
if (sel.IsRectangular()) {
::OpenClipboard(NULL);
::SetClipboardData(cfColumnSelect, 0);
::CloseClipboard();
@ -1433,7 +1456,7 @@ bool ScintillaGTK::OwnPrimarySelection() {
void ScintillaGTK::ClaimSelection() {
// X Windows has a 'primary selection' as well as the clipboard.
// Whenever the user selects some text, we become the primary selection
if (currentPos != anchor && GTK_WIDGET_REALIZED(GTK_WIDGET(PWidget(wMain)))) {
if (!sel.Empty() && GTK_WIDGET_REALIZED(GTK_WIDGET(PWidget(wMain)))) {
primarySelection = true;
gtk_selection_owner_set(GTK_WIDGET(PWidget(wMain)),
GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
@ -1513,19 +1536,22 @@ void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) {
SelectionText selText;
GetGtkSelectionText(selection_data, selText);
pdoc->BeginUndoAction();
UndoGroup ug(pdoc);
if (selection_data->selection != GDK_SELECTION_PRIMARY) {
ClearSelection();
}
int selStart = SelectionStart();
SelectionPosition selStart = sel.IsRectangular() ?
sel.Rectangular().Start() :
sel.Range(sel.Main()).Start();
if (selText.rectangular) {
PasteRectangular(selStart, selText.s, selText.len);
} else {
pdoc->InsertString(currentPos, selText.s, selText.len);
SetEmptySelection(currentPos + selText.len);
selStart = SelectionPosition(InsertSpace(selStart.Position(), selStart.VirtualSpace()));
if (pdoc->InsertString(selStart.Position(),selText.s, selText.len)) {
SetEmptySelection(selStart.Position() + selText.len);
}
}
pdoc->EndUndoAction();
EnsureCaretVisible();
}
}
@ -1595,18 +1621,19 @@ void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, Se
// All other tested aplications behave benignly by ignoring the \0.
// The #if is here because on Windows cfColumnSelect clip entry is used
// instead as standard indicator of rectangularness (so no need to kludge)
int len = strlen(text->s);
const char *textData = text->s ? text->s : "";
int len = strlen(textData);
#if PLAT_GTK_WIN32 == 0
if (text->rectangular)
len++;
#endif
if (info == TARGET_UTF8_STRING) {
gtk_selection_data_set_text(selection_data, text->s, len);
gtk_selection_data_set_text(selection_data, textData, len);
} else {
gtk_selection_data_set(selection_data,
static_cast<GdkAtom>(GDK_SELECTION_TYPE_STRING),
8, reinterpret_cast<unsigned char *>(text->s), len);
8, reinterpret_cast<const unsigned char *>(textData), len);
}
delete converted;
@ -1780,6 +1807,21 @@ static void SetAdjustmentValue(GtkObject *object, int value) {
gtk_adjustment_set_value(adjustment, value);
}
static int modifierTranslated(int sciModifier) {
switch (sciModifier) {
case SCMOD_SHIFT:
return GDK_SHIFT_MASK;
case SCMOD_CTRL:
return GDK_CONTROL_MASK;
case SCMOD_ALT:
return GDK_MOD1_MASK;
case SCMOD_SUPER:
return GDK_MOD4_MASK;
default:
return 0;
}
}
gint ScintillaGTK::PressThis(GdkEventButton *event) {
try {
//Platform::DebugPrintf("Press %x time=%d state = %x button = %x\n",this,event->time, event->state, event->button);
@ -1803,22 +1845,16 @@ gint ScintillaGTK::PressThis(GdkEventButton *event) {
gtk_widget_grab_focus(PWidget(wMain));
if (event->button == 1) {
// On X, instead of sending literal modifiers use control instead of alt
// On X, instead of sending literal modifiers use the user specified
// modifier, defaulting to control instead of alt.
// This is because most X window managers grab alt + click for moving
#if !PLAT_GTK_WIN32
ButtonDown(pt, event->time,
(event->state & GDK_SHIFT_MASK) != 0,
(event->state & GDK_CONTROL_MASK) != 0,
(event->state & GDK_CONTROL_MASK) != 0);
#else
ButtonDown(pt, event->time,
(event->state & GDK_SHIFT_MASK) != 0,
(event->state & GDK_CONTROL_MASK) != 0,
(event->state & GDK_MOD1_MASK) != 0);
#endif
(event->state & modifierTranslated(rectangularSelectionModifier)) != 0);
} else if (event->button == 2) {
// Grab the primary selection if it exists
Position pos = PositionFromLocation(pt);
SelectionPosition pos = SPositionFromLocation(pt);
if (OwnPrimarySelection() && primary.s == NULL)
CopySelectionRange(&primary);
@ -2222,7 +2258,7 @@ void ScintillaGTK::PreeditChangedThis() {
gint x, y;
gdk_window_get_origin((PWidget(wText))->window, &x, &y);
Point pt = LocationFromPosition(currentPos);
Point pt = PointMainCaret();
if (pt.x < 0)
pt.x = 0;
if (pt.y < 0)
@ -2309,7 +2345,7 @@ void ScintillaGTK::Draw(GtkWidget *widget, GdkRectangle *area) {
}
#ifdef INTERNATIONAL_INPUT
Point pt = sciThis->LocationFromPosition(sciThis->currentPos);
Point pt = sciThis->PointMainCaret();
pt.y += sciThis->vs.lineHeight - 2;
if (pt.x < 0) pt.x = 0;
if (pt.y < 0) pt.y = 0;
@ -2493,10 +2529,10 @@ gboolean ScintillaGTK::DragMotionThis(GdkDragContext *context,
gint x, gint y, guint dragtime) {
try {
Point npt(x, y);
SetDragPosition(PositionFromLocation(npt));
SetDragPosition(SPositionFromLocation(npt, false, false, UserVirtualSpace()));
GdkDragAction preferredAction = context->suggested_action;
int pos = PositionFromLocation(npt);
if ((inDragDrop == ddDragging) && (0 == PositionInSelection(pos))) {
SelectionPosition pos = SPositionFromLocation(npt);
if ((inDragDrop == ddDragging) && (PositionInSelection(pos.Position()))) {
// Avoid dragging selection onto itself as that produces a move
// with no real effect but which creates undo actions.
preferredAction = static_cast<GdkDragAction>(0);
@ -2520,7 +2556,7 @@ gboolean ScintillaGTK::DragMotion(GtkWidget *widget, GdkDragContext *context,
void ScintillaGTK::DragLeave(GtkWidget *widget, GdkDragContext * /*context*/, guint) {
ScintillaGTK *sciThis = ScintillaFromWidget(widget);
try {
sciThis->SetDragPosition(invalidPosition);
sciThis->SetDragPosition(SelectionPosition(invalidPosition));
//Platform::DebugPrintf("DragLeave %x\n", sciThis);
} catch (...) {
sciThis->errorStatus = SC_STATUS_FAILURE;
@ -2533,7 +2569,7 @@ void ScintillaGTK::DragEnd(GtkWidget *widget, GdkDragContext * /*context*/) {
// If drag did not result in drop here or elsewhere
if (!sciThis->dragWasDropped)
sciThis->SetEmptySelection(sciThis->posDrag);
sciThis->SetDragPosition(invalidPosition);
sciThis->SetDragPosition(SelectionPosition(invalidPosition));
//Platform::DebugPrintf("DragEnd %x %d\n", sciThis, sciThis->dragWasDropped);
sciThis->inDragDrop = ddNone;
} catch (...) {
@ -2546,7 +2582,7 @@ gboolean ScintillaGTK::Drop(GtkWidget *widget, GdkDragContext * /*context*/,
ScintillaGTK *sciThis = ScintillaFromWidget(widget);
try {
//Platform::DebugPrintf("Drop %x\n", sciThis);
sciThis->SetDragPosition(invalidPosition);
sciThis->SetDragPosition(SelectionPosition(invalidPosition));
} catch (...) {
sciThis->errorStatus = SC_STATUS_FAILURE;
}
@ -2558,7 +2594,7 @@ void ScintillaGTK::DragDataReceived(GtkWidget *widget, GdkDragContext * /*contex
ScintillaGTK *sciThis = ScintillaFromWidget(widget);
try {
sciThis->ReceivedDrop(selection_data);
sciThis->SetDragPosition(invalidPosition);
sciThis->SetDragPosition(SelectionPosition(invalidPosition));
} catch (...) {
sciThis->errorStatus = SC_STATUS_FAILURE;
}
@ -2569,22 +2605,22 @@ void ScintillaGTK::DragDataGet(GtkWidget *widget, GdkDragContext *context,
ScintillaGTK *sciThis = ScintillaFromWidget(widget);
try {
sciThis->dragWasDropped = true;
if (sciThis->currentPos != sciThis->anchor) {
if (!sciThis->sel.Empty()) {
sciThis->GetSelection(selection_data, info, &sciThis->drag);
}
if (context->action == GDK_ACTION_MOVE) {
int selStart = sciThis->SelectionStart();
int selEnd = sciThis->SelectionEnd();
if (sciThis->posDrop > selStart) {
if (sciThis->posDrop > selEnd)
sciThis->posDrop = sciThis->posDrop - (selEnd - selStart);
else
sciThis->posDrop = selStart;
sciThis->posDrop = sciThis->pdoc->ClampPositionIntoDocument(sciThis->posDrop);
for (size_t r=0; r<sciThis->sel.Count(); r++) {
if (sciThis->posDrop >= sciThis->sel.Range(r).Start()) {
if (sciThis->posDrop > sciThis->sel.Range(r).End()) {
sciThis->posDrop.Add(-sciThis->sel.Range(r).Length());
} else {
sciThis->posDrop.Add(-SelectionRange(sciThis->posDrop, sciThis->sel.Range(r).Start()).Length());
}
}
}
sciThis->ClearSelection();
}
sciThis->SetDragPosition(invalidPosition);
sciThis->SetDragPosition(SelectionPosition(invalidPosition));
} catch (...) {
sciThis->errorStatus = SC_STATUS_FAILURE;
}

366
scintilla/Selection.cxx Normal file
View File

@ -0,0 +1,366 @@
// Scintilla source code edit control
/** @file Selection.cxx
** Classes maintaining the selection.
**/
// Copyright 2009 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <vector>
#include "Platform.h"
#include "Scintilla.h"
#include "Selection.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int length) {
if (insertion) {
if (position > startChange) {
position += length;
}
} else {
if (position > startChange) {
int endDeletion = startChange + length;
if (position > endDeletion) {
position -= length;
} else {
position = startChange;
}
}
}
}
bool SelectionPosition::operator <(const SelectionPosition &other) const {
if (position == other.position)
return virtualSpace < other.virtualSpace;
else
return position < other.position;
}
bool SelectionPosition::operator >(const SelectionPosition &other) const {
if (position == other.position)
return virtualSpace > other.virtualSpace;
else
return position > other.position;
}
bool SelectionPosition::operator <=(const SelectionPosition &other) const {
if (position == other.position && virtualSpace == other.virtualSpace)
return true;
else
return other > *this;
}
bool SelectionPosition::operator >=(const SelectionPosition &other) const {
if (position == other.position && virtualSpace == other.virtualSpace)
return true;
else
return *this > other;
}
int SelectionRange::Length() const {
if (anchor > caret) {
return anchor.Position() - caret.Position();
} else {
return caret.Position() - anchor.Position();
}
}
bool SelectionRange::Contains(int pos) const {
if (anchor > caret)
return (pos >= caret.Position()) && (pos <= anchor.Position());
else
return (pos >= anchor.Position()) && (pos <= caret.Position());
}
bool SelectionRange::Contains(SelectionPosition sp) const {
if (anchor > caret)
return (sp >= caret) && (sp <= anchor);
else
return (sp >= anchor) && (sp <= caret);
}
bool SelectionRange::ContainsCharacter(int posCharacter) const {
if (anchor > caret)
return (posCharacter >= caret.Position()) && (posCharacter < anchor.Position());
else
return (posCharacter >= anchor.Position()) && (posCharacter < caret.Position());
}
SelectionSegment SelectionRange::Intersect(SelectionSegment check) const {
SelectionSegment inOrder(caret, anchor);
if ((inOrder.start <= check.end) || (inOrder.end >= check.start)) {
SelectionSegment portion = check;
if (portion.start < inOrder.start)
portion.start = inOrder.start;
if (portion.end > inOrder.end)
portion.end = inOrder.end;
if (portion.start > portion.end)
return SelectionSegment();
else
return portion;
} else {
return SelectionSegment();
}
}
bool SelectionRange::Trim(SelectionRange range) {
SelectionPosition startRange = range.Start();
SelectionPosition endRange = range.End();
SelectionPosition start = Start();
SelectionPosition end = End();
PLATFORM_ASSERT(start <= end);
PLATFORM_ASSERT(startRange <= endRange);
if ((startRange <= end) && (endRange >= start)) {
if ((start > startRange) && (end < endRange)) {
// Completely covered by range -> empty at start
end = start;
} else if ((start < startRange) && (end > endRange)) {
// Completely covers range -> empty at start
end = start;
} else if (start <= startRange) {
// Trim end
end = startRange;
} else { //
PLATFORM_ASSERT(end >= endRange);
// Trim start
start = endRange;
}
if (anchor > caret) {
caret = start;
anchor = end;
} else {
anchor = start;
caret = end;
}
return Empty();
} else {
return false;
}
}
// If range is all virtual collapse to start of virtual space
void SelectionRange::MinimizeVirtualSpace() {
if (caret.Position() == anchor.Position()) {
int virtualSpace = caret.VirtualSpace();
if (virtualSpace > anchor.VirtualSpace())
virtualSpace = anchor.VirtualSpace();
caret.SetVirtualSpace(virtualSpace);
anchor.SetVirtualSpace(virtualSpace);
}
}
Selection::Selection() : mainRange(0), moveExtends(false), tentativeMain(false), selType(selStream) {
AddSelection(SelectionPosition(0));
}
Selection::~Selection() {
}
bool Selection::IsRectangular() const {
return (selType == selRectangle) || (selType == selThin);
}
int Selection::MainCaret() const {
return ranges[mainRange].caret.Position();
}
int Selection::MainAnchor() const {
return ranges[mainRange].anchor.Position();
}
SelectionRange &Selection::Rectangular() {
return rangeRectangular;
}
SelectionSegment Selection::Limits() const {
if (ranges.empty()) {
return SelectionSegment();
} else {
SelectionSegment sr(ranges[0].anchor, ranges[0].caret);
for (size_t i=1; i<ranges.size(); i++) {
sr.Extend(ranges[i].anchor);
sr.Extend(ranges[i].caret);
}
return sr;
}
}
SelectionSegment Selection::LimitsForRectangularElseMain() const {
if (IsRectangular()) {
return Limits();
} else {
return SelectionSegment(ranges[mainRange].caret, ranges[mainRange].anchor);
}
}
size_t Selection::Count() const {
return ranges.size();
}
size_t Selection::Main() const {
return mainRange;
}
void Selection::SetMain(size_t r) {
PLATFORM_ASSERT(r < ranges.size());
mainRange = r;
}
SelectionRange &Selection::Range(size_t r) {
return ranges[r];
}
SelectionRange &Selection::RangeMain() {
return ranges[mainRange];
}
bool Selection::MoveExtends() const {
return moveExtends;
}
void Selection::SetMoveExtends(bool moveExtends_) {
moveExtends = moveExtends_;
}
bool Selection::Empty() const {
for (size_t i=0; i<ranges.size(); i++) {
if (!ranges[i].Empty())
return false;
}
return true;
}
SelectionPosition Selection::Last() const {
SelectionPosition lastPosition;
for (size_t i=0; i<ranges.size(); i++) {
if (lastPosition < ranges[i].caret)
lastPosition = ranges[i].caret;
if (lastPosition < ranges[i].anchor)
lastPosition = ranges[i].anchor;
}
return lastPosition;
}
int Selection::Length() const {
int len = 0;
for (size_t i=0; i<ranges.size(); i++) {
len += ranges[i].Length();
}
return len;
}
void Selection::MovePositions(bool insertion, int startChange, int length) {
for (size_t i=0; i<ranges.size(); i++) {
ranges[i].caret.MoveForInsertDelete(insertion, startChange, length);
ranges[i].anchor.MoveForInsertDelete(insertion, startChange, length);
}
}
void Selection::TrimSelection(SelectionRange range) {
for (size_t i=0; i<ranges.size();) {
if ((i != mainRange) && (ranges[i].Trim(range))) {
// Trimmed to empty so remove
for (size_t j=i;j<ranges.size()-1;j++) {
ranges[j] = ranges[j+1];
if (j == mainRange-1)
mainRange--;
}
ranges.pop_back();
} else {
i++;
}
}
}
void Selection::SetSelection(SelectionRange range) {
ranges.clear();
ranges.push_back(range);
mainRange = ranges.size() - 1;
}
void Selection::AddSelection(SelectionRange range) {
TrimSelection(range);
ranges.push_back(range);
mainRange = ranges.size() - 1;
}
void Selection::TentativeSelection(SelectionRange range) {
if (!tentativeMain) {
rangesSaved = ranges;
}
ranges = rangesSaved;
AddSelection(range);
TrimSelection(ranges[mainRange]);
tentativeMain = true;
}
void Selection::CommitTentative() {
rangesSaved.clear();
tentativeMain = false;
}
int Selection::CharacterInSelection(int posCharacter) const {
for (size_t i=0; i<ranges.size(); i++) {
if (ranges[i].ContainsCharacter(posCharacter))
return i == mainRange ? 1 : 2;
}
return 0;
}
int Selection::InSelectionForEOL(int pos) const {
for (size_t i=0; i<ranges.size(); i++) {
if (!ranges[i].Empty() && (pos > ranges[i].Start().Position()) && (pos <= ranges[i].End().Position()))
return i == mainRange ? 1 : 2;
}
return 0;
}
int Selection::VirtualSpaceFor(int pos) const {
int virtualSpace = 0;
for (size_t i=0; i<ranges.size(); i++) {
if ((ranges[i].caret.Position() == pos) && (virtualSpace < ranges[i].caret.VirtualSpace()))
virtualSpace = ranges[i].caret.VirtualSpace();
if ((ranges[i].anchor.Position() == pos) && (virtualSpace < ranges[i].anchor.VirtualSpace()))
virtualSpace = ranges[i].anchor.VirtualSpace();
}
return virtualSpace;
}
void Selection::Clear() {
ranges.clear();
ranges.push_back(SelectionRange());
mainRange = ranges.size() - 1;
selType = selStream;
moveExtends = false;
ranges[mainRange].Reset();
rangeRectangular.Reset();
}
void Selection::RemoveDuplicates() {
for (size_t i=0; i<ranges.size()-1; i++) {
if (ranges[i].Empty()) {
size_t j=i+1;
while (j<ranges.size()) {
if (ranges[i] == ranges[j]) {
ranges.erase(ranges.begin() + j);
if (mainRange >= j)
mainRange--;
} else {
j++;
}
}
}
}
}
void Selection::RotateMain() {
mainRange = (mainRange + 1) % ranges.size();
}

187
scintilla/Selection.h Normal file
View File

@ -0,0 +1,187 @@
// Scintilla source code edit control
/** @file Selection.h
** Classes maintaining the selection.
**/
// Copyright 2009 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef SELECTION_H
#define SELECTION_H
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
class SelectionPosition {
int position;
int virtualSpace;
public:
explicit SelectionPosition(int position_=INVALID_POSITION, int virtualSpace_=0) : position(position_), virtualSpace(virtualSpace_) {
PLATFORM_ASSERT(virtualSpace < 800000);
if (virtualSpace < 0)
virtualSpace = 0;
}
void Reset() {
position = 0;
virtualSpace = 0;
}
void MoveForInsertDelete(bool insertion, int startChange, int length);
bool operator ==(const SelectionPosition &other) const {
return position == other.position && virtualSpace == other.virtualSpace;
}
bool operator <(const SelectionPosition &other) const;
bool operator >(const SelectionPosition &other) const;
bool operator <=(const SelectionPosition &other) const;
bool operator >=(const SelectionPosition &other) const;
int Position() const {
return position;
}
void SetPosition(int position_) {
position = position_;
virtualSpace = 0;
}
int VirtualSpace() const {
return virtualSpace;
}
void SetVirtualSpace(int virtualSpace_) {
PLATFORM_ASSERT(virtualSpace_ < 800000);
if (virtualSpace_ >= 0)
virtualSpace = virtualSpace_;
}
void Add(int increment) {
position = position + increment;
}
bool IsValid() const {
return position >= 0;
}
};
// Ordered range to make drawing simpler
struct SelectionSegment {
SelectionPosition start;
SelectionPosition end;
SelectionSegment() {
}
SelectionSegment(SelectionPosition a, SelectionPosition b) {
if (a < b) {
start = a;
end = b;
} else {
start = b;
end = a;
}
}
bool Empty() const {
return start == end;
}
void Extend(SelectionPosition p) {
if (start > p)
start = p;
if (end < p)
end = p;
}
};
struct SelectionRange {
SelectionPosition caret;
SelectionPosition anchor;
SelectionRange() {
}
SelectionRange(SelectionPosition single) : caret(single), anchor(single) {
}
SelectionRange(int single) : caret(single), anchor(single) {
}
SelectionRange(SelectionPosition caret_, SelectionPosition anchor_) : caret(caret_), anchor(anchor_) {
}
SelectionRange(int caret_, int anchor_) : caret(caret_), anchor(anchor_) {
}
bool Empty() const {
return anchor == caret;
}
int Length() const;
// int Width() const; // Like Length but takes virtual space into account
bool operator ==(const SelectionRange &other) const {
return caret == other.caret && anchor == other.anchor;
}
bool operator <(const SelectionRange &other) const {
return caret < other.caret || ((caret == other.caret) && (anchor < other.anchor));
}
void Reset() {
anchor.Reset();
caret.Reset();
}
void ClearVirtualSpace() {
anchor.SetVirtualSpace(0);
caret.SetVirtualSpace(0);
}
bool Contains(int pos) const;
bool Contains(SelectionPosition sp) const;
bool ContainsCharacter(int posCharacter) const;
SelectionSegment Intersect(SelectionSegment check) const;
SelectionPosition Start() const {
return (anchor < caret) ? anchor : caret;
}
SelectionPosition End() const {
return (anchor < caret) ? caret : anchor;
}
bool Trim(SelectionRange range);
// If range is all virtual collapse to start of virtual space
void MinimizeVirtualSpace();
};
class Selection {
std::vector<SelectionRange> ranges;
std::vector<SelectionRange> rangesSaved;
SelectionRange rangeRectangular;
size_t mainRange;
bool moveExtends;
bool tentativeMain;
public:
enum selTypes { noSel, selStream, selRectangle, selLines, selThin };
selTypes selType;
Selection();
~Selection();
bool IsRectangular() const;
int MainCaret() const;
int MainAnchor() const;
SelectionRange &Rectangular();
SelectionSegment Limits() const;
// This is for when you want to move the caret in response to a
// user direction command - for rectangular selections, use the range
// that covers all selected text otherwise return the main selection.
SelectionSegment LimitsForRectangularElseMain() const;
size_t Count() const;
size_t Main() const;
void SetMain(size_t r);
SelectionRange &Range(size_t r);
SelectionRange &RangeMain();
bool MoveExtends() const;
void SetMoveExtends(bool moveExtends_);
bool Empty() const;
SelectionPosition Last() const;
int Length() const;
void MovePositions(bool insertion, int startChange, int length);
void TrimSelection(SelectionRange range);
void SetSelection(SelectionRange range);
void AddSelection(SelectionRange range);
void TentativeSelection(SelectionRange range);
void CommitTentative();
int CharacterInSelection(int posCharacter) const;
int InSelectionForEOL(int pos) const;
int VirtualSpaceFor(int pos) const;
void Clear();
void RemoveDuplicates();
void RotateMain();
bool Tentative() const { return tentativeMain; }
std::vector<SelectionRange> RangesCopy() const {
return ranges;
}
};
#ifdef SCI_NAMESPACE
}
#endif
#endif

View File

@ -126,7 +126,7 @@ bool Style::EquivalentFontTo(const Style *other) const {
return strcmp(fontName, other->fontName) == 0;
}
void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle, bool extraFontFlag) {
void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle, int extraFontFlag) {
sizeZoomed = size + zoomLevel;
if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1
sizeZoomed = 2;

View File

@ -53,7 +53,7 @@ public:
bool visible_, bool changeable_, bool hotspot_);
void ClearTo(const Style &source);
bool EquivalentFontTo(const Style *other) const;
void Realise(Surface &surface, int zoomLevel, Style *defaultStyle = 0, bool extraFontFlag = false);
void Realise(Surface &surface, int zoomLevel, Style *defaultStyle = 0, int extraFontFlag = 0);
bool IsProtected() const { return !(changeable && visible);};
};

View File

@ -16,9 +16,7 @@ namespace Scintilla {
class StyleContext {
Accessor &styler;
unsigned int endPos;
StyleContext& operator=(const StyleContext&) {
return *this;
}
StyleContext& operator=(const StyleContext&);
void GetNextChar(unsigned int pos) {
chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1));
if (styler.IsLeadByte(static_cast<char>(chNext))) {

View File

@ -92,10 +92,13 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
selforeset = source.selforeset;
selforeground.desired = source.selforeground.desired;
selAdditionalForeground.desired = source.selAdditionalForeground.desired;
selbackset = source.selbackset;
selbackground.desired = source.selbackground.desired;
selAdditionalBackground.desired = source.selAdditionalBackground.desired;
selbackground2.desired = source.selbackground2.desired;
selAlpha = source.selAlpha;
selAdditionalAlpha = source.selAdditionalAlpha;
selEOLFilled = source.selEOLFilled;
foldmarginColourSet = source.foldmarginColourSet;
@ -117,6 +120,7 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
selbar.desired = source.selbar.desired;
selbarlight.desired = source.selbarlight.desired;
caretcolour.desired = source.caretcolour.desired;
additionalCaretColour.desired = source.additionalCaretColour.desired;
showCaretLineBackground = source.showCaretLineBackground;
caretLineBackground.desired = source.caretLineBackground.desired;
caretLineAlpha = source.caretLineAlpha;
@ -135,6 +139,7 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
fixedColumnWidth = source.fixedColumnWidth;
zoomLevel = source.zoomLevel;
viewWhitespace = source.viewWhitespace;
whitespaceSize = source.whitespaceSize;
viewIndentationGuides = source.viewIndentationGuides;
viewEOL = source.viewEOL;
showMarkedLines = source.showMarkedLines;
@ -176,10 +181,13 @@ void ViewStyle::Init(size_t stylesSize_) {
selforeset = false;
selforeground.desired = ColourDesired(0xff, 0, 0);
selAdditionalForeground.desired = ColourDesired(0xff, 0, 0);
selbackset = true;
selbackground.desired = ColourDesired(0xc0, 0xc0, 0xc0);
selAdditionalBackground.desired = ColourDesired(0xd7, 0xd7, 0xd7);
selbackground2.desired = ColourDesired(0xb0, 0xb0, 0xb0);
selAlpha = SC_ALPHA_NOALPHA;
selAdditionalAlpha = SC_ALPHA_NOALPHA;
selEOLFilled = false;
foldmarginColourSet = false;
@ -196,6 +204,7 @@ void ViewStyle::Init(size_t stylesSize_) {
styles[STYLE_LINENUMBER].fore.desired = ColourDesired(0, 0, 0);
styles[STYLE_LINENUMBER].back.desired = Platform::Chrome();
caretcolour.desired = ColourDesired(0, 0, 0);
additionalCaretColour.desired = ColourDesired(0x7f, 0x7f, 0x7f);
showCaretLineBackground = false;
caretLineBackground.desired = ColourDesired(0xff, 0xff, 0);
caretLineAlpha = SC_ALPHA_NOALPHA;
@ -234,10 +243,11 @@ void ViewStyle::Init(size_t stylesSize_) {
}
zoomLevel = 0;
viewWhitespace = wsInvisible;
whitespaceSize = 1;
viewIndentationGuides = ivNone;
viewEOL = false;
showMarkedLines = true;
extraFontFlag = false;
extraFontFlag = 0;
extraAscent = 0;
extraDescent = 0;
marginStyleOffset = 0;
@ -258,7 +268,9 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
markers[i].RefreshColourPalette(pal, want);
}
pal.WantFind(selforeground, want);
pal.WantFind(selAdditionalForeground, want);
pal.WantFind(selbackground, want);
pal.WantFind(selAdditionalBackground, want);
pal.WantFind(selbackground2, want);
pal.WantFind(foldmarginColour, want);
@ -269,6 +281,7 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(selbar, want);
pal.WantFind(selbarlight, want);
pal.WantFind(caretcolour, want);
pal.WantFind(additionalCaretColour, want);
pal.WantFind(caretLineBackground, want);
pal.WantFind(edgecolour, want);
pal.WantFind(hotspotForeground, want);

View File

@ -58,10 +58,13 @@ public:
unsigned int spaceWidth;
bool selforeset;
ColourPair selforeground;
ColourPair selAdditionalForeground;
bool selbackset;
ColourPair selbackground;
ColourPair selAdditionalBackground;
ColourPair selbackground2;
int selAlpha;
int selAdditionalAlpha;
bool selEOLFilled;
bool whitespaceForegroundSet;
ColourPair whitespaceForeground;
@ -89,10 +92,12 @@ public:
int fixedColumnWidth;
int zoomLevel;
WhiteSpaceVisibility viewWhitespace;
int whitespaceSize;
IndentView viewIndentationGuides;
bool viewEOL;
bool showMarkedLines;
ColourPair caretcolour;
ColourPair additionalCaretColour;
bool showCaretLineBackground;
ColourPair caretLineBackground;
int caretLineAlpha;
@ -101,7 +106,7 @@ public:
int caretStyle;
int caretWidth;
bool someStylesProtected;
bool extraFontFlag;
int extraFontFlag;
int extraAscent;
int extraDescent;
int marginStyleOffset;

View File

@ -9,6 +9,29 @@
namespace Scintilla {
#endif
/**
*/
class WordList {
public:
// Each word contains at least one character - a empty word acts as sentinel at the end.
char **words;
char *list;
int len;
bool onlyLineEnds; ///< Delimited by any white space or only line ends
bool sorted;
int starts[256];
WordList(bool onlyLineEnds_ = false) :
words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_),
sorted(false)
{}
~WordList() { Clear(); }
operator bool() { return len ? true : false; }
void Clear();
void Set(const char *s);
bool InList(const char *s);
bool InListAbbreviated(const char *s, const char marker);
};
typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle,
WordList *keywordlists[], Accessor &styler);

View File

@ -295,7 +295,7 @@ public:
virtual ~Font();
virtual void Create(const char *faceName, int characterSet, int size,
bool bold, bool italic, bool extraFontFlag=false);
bool bold, bool italic, int extraFontFlag=0);
virtual void Release();
FontID GetID() { return fid; }

View File

@ -1,104 +1,26 @@
// Scintilla source code edit control
/** @file PropSet.h
** A Java style properties file module.
** An interface to the methods needed for access to property sets inside lexers.
**/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2009 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef PROPSET_H
#define PROPSET_H
#include "SString.h"
bool EqualCaseInsensitive(const char *a, const char *b);
bool isprefix(const char *target, const char *prefix);
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
struct Property {
unsigned int hash;
char *key;
char *val;
Property *next;
Property() : hash(0), key(0), val(0), next(0) {}
};
/**
*/
class PropSet {
protected:
enum { hashRoots=31 };
Property *props[hashRoots];
Property *enumnext;
int enumhash;
static unsigned int HashString(const char *s, size_t len) {
unsigned int ret = 0;
while (len--) {
ret <<= 4;
ret ^= *s;
s++;
}
return ret;
}
class PropertyGet {
public:
PropSet *superPS;
PropSet();
~PropSet();
void Set(const char *key, const char *val, int lenKey=-1, int lenVal=-1);
void Set(const char *keyVal);
void Unset(const char *key, int lenKey=-1);
void SetMultiple(const char *s);
SString Get(const char *key) const;
SString GetExpanded(const char *key) const;
SString Expand(const char *withVars, int maxExpands=100) const;
int GetInt(const char *key, int defaultValue=0) const;
void Clear();
char *ToString() const; // Caller must delete[] the return value
private:
// copy-value semantics not implemented
PropSet(const PropSet &copy);
void operator=(const PropSet &assign);
virtual char *ToString() const=0; // Caller must delete[] the return value
virtual int GetInt(const char *key, int defaultValue=0) const=0;
virtual ~PropertyGet() {}
};
/**
*/
class WordList {
public:
// Each word contains at least one character - a empty word acts as sentinel at the end.
char **words;
char *list;
int len;
bool onlyLineEnds; ///< Delimited by any white space or only line ends
bool sorted;
int starts[256];
WordList(bool onlyLineEnds_ = false) :
words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_),
sorted(false)
{}
~WordList() { Clear(); }
operator bool() { return len ? true : false; }
void Clear();
void Set(const char *s);
bool InList(const char *s);
bool InListAbbreviated(const char *s, const char marker);
};
inline bool IsAlphabetic(unsigned int ch) {
return ((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z'));
}
#ifdef SCI_NAMESPACE
}
#endif
#ifdef _MSC_VER
// Visual C++ doesn't like the private copy idiom for disabling
// the default copy constructor and operator=, but it's fine.
#pragma warning(disable: 4511 4512)
#endif
#endif

View File

@ -789,8 +789,19 @@
#define SCE_ERLANG_CHARACTER 9
#define SCE_ERLANG_MACRO 10
#define SCE_ERLANG_RECORD 11
#define SCE_ERLANG_SEPARATOR 12
#define SCE_ERLANG_PREPROC 12
#define SCE_ERLANG_NODE_NAME 13
#define SCE_ERLANG_COMMENT_FUNCTION 14
#define SCE_ERLANG_COMMENT_MODULE 15
#define SCE_ERLANG_COMMENT_DOC 16
#define SCE_ERLANG_COMMENT_DOC_MACRO 17
#define SCE_ERLANG_ATOM_QUOTED 18
#define SCE_ERLANG_MACRO_QUOTED 19
#define SCE_ERLANG_RECORD_QUOTED 20
#define SCE_ERLANG_NODE_NAME_QUOTED 21
#define SCE_ERLANG_BIFS 22
#define SCE_ERLANG_MODULES 23
#define SCE_ERLANG_MODULES_ATT 24
#define SCE_ERLANG_UNKNOWN 31
#define SCE_MSSQL_DEFAULT 0
#define SCE_MSSQL_COMMENT 1
@ -1097,7 +1108,6 @@
#define SCE_INNO_PARAMETER 3
#define SCE_INNO_SECTION 4
#define SCE_INNO_PREPROC 5
#define SCE_INNO_PREPROC_INLINE 6
#define SCE_INNO_INLINE_EXPANSION 6
#define SCE_INNO_COMMENT_PASCAL 7
#define SCE_INNO_KEYWORD_PASCAL 8
@ -1278,28 +1288,6 @@
#define SCE_MYSQL_USER2 19
#define SCE_MYSQL_USER3 20
#define SCE_MYSQL_HIDDENCOMMAND 21
#define SCE_MARKDOWN_DEFAULT 0
#define SCE_MARKDOWN_LINE_BEGIN 1
#define SCE_MARKDOWN_STRONG1 2
#define SCE_MARKDOWN_STRONG2 3
#define SCE_MARKDOWN_EM1 4
#define SCE_MARKDOWN_EM2 5
#define SCE_MARKDOWN_HEADER1 6
#define SCE_MARKDOWN_HEADER2 7
#define SCE_MARKDOWN_HEADER3 8
#define SCE_MARKDOWN_HEADER4 9
#define SCE_MARKDOWN_HEADER5 10
#define SCE_MARKDOWN_HEADER6 11
#define SCE_MARKDOWN_PRECHAR 12
#define SCE_MARKDOWN_ULIST_ITEM 13
#define SCE_MARKDOWN_OLIST_ITEM 14
#define SCE_MARKDOWN_BLOCKQUOTE 15
#define SCE_MARKDOWN_STRIKEOUT 16
#define SCE_MARKDOWN_HRULE 17
#define SCE_MARKDOWN_LINK 18
#define SCE_MARKDOWN_CODE 19
#define SCE_MARKDOWN_CODE2 20
#define SCE_MARKDOWN_CODEBK 21
#define SCE_PO_DEFAULT 0
#define SCE_PO_COMMENT 1
#define SCE_PO_MSGID 2
@ -1366,6 +1354,28 @@
#define SCE_SML_COMMENT1 13
#define SCE_SML_COMMENT2 14
#define SCE_SML_COMMENT3 15
#define SCE_MARKDOWN_DEFAULT 0
#define SCE_MARKDOWN_LINE_BEGIN 1
#define SCE_MARKDOWN_STRONG1 2
#define SCE_MARKDOWN_STRONG2 3
#define SCE_MARKDOWN_EM1 4
#define SCE_MARKDOWN_EM2 5
#define SCE_MARKDOWN_HEADER1 6
#define SCE_MARKDOWN_HEADER2 7
#define SCE_MARKDOWN_HEADER3 8
#define SCE_MARKDOWN_HEADER4 9
#define SCE_MARKDOWN_HEADER5 10
#define SCE_MARKDOWN_HEADER6 11
#define SCE_MARKDOWN_PRECHAR 12
#define SCE_MARKDOWN_ULIST_ITEM 13
#define SCE_MARKDOWN_OLIST_ITEM 14
#define SCE_MARKDOWN_BLOCKQUOTE 15
#define SCE_MARKDOWN_STRIKEOUT 16
#define SCE_MARKDOWN_HRULE 17
#define SCE_MARKDOWN_LINK 18
#define SCE_MARKDOWN_CODE 19
#define SCE_MARKDOWN_CODE2 20
#define SCE_MARKDOWN_CODEBK 21
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
#endif

View File

@ -15,6 +15,10 @@
typedef BOOL bool;
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if PLAT_WIN
/* Return false on failure: */
bool Scintilla_RegisterClasses(void *hInstance);
@ -22,6 +26,10 @@ bool Scintilla_ReleaseResources();
#endif
int Scintilla_LinkLexers();
#ifdef __cplusplus
}
#endif
/* Here should be placed typedefs for uptr_t, an unsigned integer type large enough to
* hold a pointer and sptr_t, a signed integer large enough to hold a pointer.
* May need to be changed for 64 bit platforms. */
@ -254,6 +262,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_INDICGETUNDER 2511
#define SCI_SETWHITESPACEFORE 2084
#define SCI_SETWHITESPACEBACK 2085
#define SCI_SETWHITESPACESIZE 2086
#define SCI_GETWHITESPACESIZE 2087
#define SCI_SETSTYLEBITS 2090
#define SCI_GETSTYLEBITS 2091
#define SCI_SETLINESTATE 2092
@ -468,6 +478,14 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_APPENDTEXT 2282
#define SCI_GETTWOPHASEDRAW 2283
#define SCI_SETTWOPHASEDRAW 2284
#define SC_EFF_QUALITY_MASK 0xF
#define SC_EFF_QUALITY_DEFAULT 0
#define SC_EFF_QUALITY_NON_ANTIALIASED 1
#define SC_EFF_QUALITY_ANTIALIASED 2
#define SC_EFF_QUALITY_LCD_OPTIMIZED 3
#define SCI_SETFONTQUALITY 2611
#define SCI_GETFONTQUALITY 2612
#define SCI_SETFIRSTVISIBLELINE 2613
#define SCI_TARGETFROMSELECTION 2287
#define SCI_LINESJOIN 2288
#define SCI_LINESSPLIT 2289
@ -617,6 +635,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SC_SEL_STREAM 0
#define SC_SEL_RECTANGLE 1
#define SC_SEL_LINES 2
#define SC_SEL_THIN 3
#define SCI_SETSELECTIONMODE 2422
#define SCI_GETSELECTIONMODE 2423
#define SCI_GETLINESELSTARTPOSITION 2424
@ -714,6 +733,55 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_ADDUNDOACTION 2560
#define SCI_CHARPOSITIONFROMPOINT 2561
#define SCI_CHARPOSITIONFROMPOINTCLOSE 2562
#define SCI_SETMULTIPLESELECTION 2563
#define SCI_GETMULTIPLESELECTION 2564
#define SCI_SETADDITIONALSELECTIONTYPING 2565
#define SCI_GETADDITIONALSELECTIONTYPING 2566
#define SCI_SETADDITIONALCARETSBLINK 2567
#define SCI_GETADDITIONALCARETSBLINK 2568
#define SCI_SETADDITIONALCARETSVISIBLE 2608
#define SCI_GETADDITIONALCARETSVISIBLE 2609
#define SCI_GETSELECTIONS 2570
#define SCI_CLEARSELECTIONS 2571
#define SCI_SETSELECTION 2572
#define SCI_ADDSELECTION 2573
#define SCI_SETMAINSELECTION 2574
#define SCI_GETMAINSELECTION 2575
#define SCI_SETSELECTIONNCARET 2576
#define SCI_GETSELECTIONNCARET 2577
#define SCI_SETSELECTIONNANCHOR 2578
#define SCI_GETSELECTIONNANCHOR 2579
#define SCI_SETSELECTIONNCARETVIRTUALSPACE 2580
#define SCI_GETSELECTIONNCARETVIRTUALSPACE 2581
#define SCI_SETSELECTIONNANCHORVIRTUALSPACE 2582
#define SCI_GETSELECTIONNANCHORVIRTUALSPACE 2583
#define SCI_SETSELECTIONNSTART 2584
#define SCI_GETSELECTIONNSTART 2585
#define SCI_SETSELECTIONNEND 2586
#define SCI_GETSELECTIONNEND 2587
#define SCI_SETRECTANGULARSELECTIONCARET 2588
#define SCI_GETRECTANGULARSELECTIONCARET 2589
#define SCI_SETRECTANGULARSELECTIONANCHOR 2590
#define SCI_GETRECTANGULARSELECTIONANCHOR 2591
#define SCI_SETRECTANGULARSELECTIONCARETVIRTUALSPACE 2592
#define SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE 2593
#define SCI_SETRECTANGULARSELECTIONANCHORVIRTUALSPACE 2594
#define SCI_GETRECTANGULARSELECTIONANCHORVIRTUALSPACE 2595
#define SCVS_NONE 0
#define SCVS_RECTANGULARSELECTION 1
#define SCVS_USERACCESSIBLE 2
#define SCI_SETVIRTUALSPACEOPTIONS 2596
#define SCI_GETVIRTUALSPACEOPTIONS 2597
#define SCI_SETRECTANGULARSELECTIONMODIFIER 2598
#define SCI_GETRECTANGULARSELECTIONMODIFIER 2599
#define SCI_SETADDITIONALSELFORE 2600
#define SCI_SETADDITIONALSELBACK 2601
#define SCI_SETADDITIONALSELALPHA 2602
#define SCI_GETADDITIONALSELALPHA 2603
#define SCI_SETADDITIONALCARETFORE 2604
#define SCI_GETADDITIONALCARETFORE 2605
#define SCI_ROTATESELECTION 2606
#define SCI_SWAPMAINANCHORCARET 2607
#define SCI_STARTRECORD 3001
#define SCI_STOPRECORD 3002
#define SCI_SETLEXER 4001
@ -728,6 +796,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETPROPERTYEXPANDED 4009
#define SCI_GETPROPERTYINT 4010
#define SCI_GETSTYLEBITSNEEDED 4011
#define SCI_GETLEXERLANGUAGE 4012
#define SC_MOD_INSERTTEXT 0x1
#define SC_MOD_DELETETEXT 0x2
#define SC_MOD_CHANGESTYLE 0x4
@ -775,6 +844,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCMOD_SHIFT 1
#define SCMOD_CTRL 2
#define SCMOD_ALT 4
#define SCMOD_SUPER 8
#define SCN_STYLENEEDED 2000
#define SCN_CHARADDED 2001
#define SCN_SAVEPOINTREACHED 2002

View File

@ -477,10 +477,10 @@ set void StyleSetCharacterSet=2066(int style, int characterSet)
# Set a style to be a hotspot or not.
set void StyleSetHotSpot=2409(int style, bool hotspot)
# Set the foreground colour of the selection and whether to use this setting.
# Set the foreground colour of the main and additional selections and whether to use this setting.
fun void SetSelFore=2067(bool useSetting, colour fore)
# Set the background colour of the selection and whether to use this setting.
# Set the background colour of the main and additional selections and whether to use this setting.
fun void SetSelBack=2068(bool useSetting, colour back)
# Get the alpha of the selection.
@ -571,6 +571,12 @@ fun void SetWhitespaceFore=2084(bool useSetting, colour fore)
# Set the background colour of all whitespace and whether to use this setting.
fun void SetWhitespaceBack=2085(bool useSetting, colour back)
# Set the size of the dots used to mark space characters.
set void SetWhitespaceSize=2086(int size,)
# Get the size of the dots used to mark space characters.
get int GetWhitespaceSize=2087(,)
# Divide each styling byte into lexical class bits (default: 5) and indicator
# bits (default: 3). If a lexer requires more than 32 lexical states, then this
# is used to expand the possible states.
@ -1199,6 +1205,24 @@ get bool GetTwoPhaseDraw=2283(,)
# and then the foreground. This avoids chopping off characters that overlap the next run.
set void SetTwoPhaseDraw=2284(bool twoPhase,)
# Control font anti-aliasing.
enu FontQuality=SC_EFF_
val SC_EFF_QUALITY_MASK=0xF
val SC_EFF_QUALITY_DEFAULT=0
val SC_EFF_QUALITY_NON_ANTIALIASED=1
val SC_EFF_QUALITY_ANTIALIASED=2
val SC_EFF_QUALITY_LCD_OPTIMIZED=3
# Choose the quality level for text from the FontQuality enumeration.
set void SetFontQuality=2611(int fontQuality,)
# Retrieve the quality level for text.
get int GetFontQuality=2612(,)
# Scroll so that a display line is at the top of the display.
set void SetFirstVisibleLine=2613(int lineDisplay,)
# Make the target range start and end be the same as the selection range start and end.
fun void TargetFromSelection=2287(,)
@ -1637,8 +1661,9 @@ enu SelectionMode=SC_SEL_
val SC_SEL_STREAM=0
val SC_SEL_RECTANGLE=1
val SC_SEL_LINES=2
val SC_SEL_THIN=3
# Set the selection mode to stream (SC_SEL_STREAM) or rectangular (SC_SEL_RECTANGLE) or
# Set the selection mode to stream (SC_SEL_STREAM) or rectangular (SC_SEL_RECTANGLE/SC_SEL_THIN) or
# by lines (SC_SEL_LINES).
set void SetSelectionMode=2422(int mode,)
@ -1930,6 +1955,122 @@ fun position CharPositionFromPoint=2561(int x, int y)
# Return INVALID_POSITION if not close to text.
fun position CharPositionFromPointClose=2562(int x, int y)
# Set whether multiple selections can be made
set void SetMultipleSelection=2563(bool multipleSelection,)
# Whether multiple selections can be made
get bool GetMultipleSelection=2564(,)
# Set whether typing can be performed into multiple selections
set void SetAdditionalSelectionTyping=2565(bool additionalSelectionTyping,)
# Whether typing can be performed into multiple selections
get bool GetAdditionalSelectionTyping=2566(,)
# Set whether additional carets will blink
set void SetAdditionalCaretsBlink=2567(bool additionalCaretsBlink,)
# Whether additional carets will blink
get bool GetAdditionalCaretsBlink=2568(,)
# Set whether additional carets are visible
set void SetAdditionalCaretsVisible=2608(bool additionalCaretsBlink,)
# Whether additional carets are visible
get bool GetAdditionalCaretsVisible=2609(,)
# How many selections are there?
get int GetSelections=2570(,)
# Clear selections to a single empty stream selection
fun void ClearSelections=2571(,)
# Set a simple selection
fun int SetSelection=2572(int caret,int anchor)
# Add a selection
fun int AddSelection=2573(int caret,int anchor)
# Set the main selection
set void SetMainSelection=2574(int selection,)
# Which selection is the main selection
get int GetMainSelection=2575(,)
set void SetSelectionNCaret=2576(int selection, position pos)
get position GetSelectionNCaret=2577(int selection,)
set void SetSelectionNAnchor=2578(int selection, position posAnchor)
get position GetSelectionNAnchor=2579(int selection,)
set void SetSelectionNCaretVirtualSpace=2580(int selection, int space)
get int GetSelectionNCaretVirtualSpace=2581(int selection,)
set void SetSelectionNAnchorVirtualSpace=2582(int selection, int space)
get int GetSelectionNAnchorVirtualSpace=2583(int selection,)
# Sets the position that starts the selection - this becomes the anchor.
set void SetSelectionNStart=2584(int selection, position pos)
# Returns the position at the start of the selection.
get position GetSelectionNStart=2585(int selection,)
# Sets the position that ends the selection - this becomes the currentPosition.
set void SetSelectionNEnd=2586(int selection, position pos,)
# Returns the position at the end of the selection.
get position GetSelectionNEnd=2587(int selection,)
set void SetRectangularSelectionCaret=2588(position pos,)
get position GetRectangularSelectionCaret=2589(,)
set void SetRectangularSelectionAnchor=2590(position posAnchor,)
get position GetRectangularSelectionAnchor=2591(,)
set void SetRectangularSelectionCaretVirtualSpace=2592(int space,)
get int GetRectangularSelectionCaretVirtualSpace=2593(,)
set void SetRectangularSelectionAnchorVirtualSpace=2594(int space,)
get int GetRectangularSelectionAnchorVirtualSpace=2595(,)
enu VirtualSpace=SCVS_
val SCVS_NONE=0
val SCVS_RECTANGULARSELECTION=1
val SCVS_USERACCESSIBLE=2
set void SetVirtualSpaceOptions=2596(int virtualSpaceOptions,)
get int GetVirtualSpaceOptions=2597(,)
# On GTK+, allow selecting the modifier key to use for mouse-based
# rectangular selection. Often the window manager requires Alt+Mouse Drag
# for moving windows.
# Valid values are SCMOD_CTRL(default), SCMOD_ALT, or SCMOD_SUPER.
set void SetRectangularSelectionModifier=2598(int modifier,)
# Get the modifier key used for rectangular selection.
get int GetRectangularSelectionModifier=2599(,)
# Set the foreground colour of additional selections.
# Must have previously called SetSelFore with non-zero first argument for this to have an effect.
set void SetAdditionalSelFore=2600(colour fore,)
# Set the background colour of additional selections.
# Must have previously called SetSelBack with non-zero first argument for this to have an effect.
set void SetAdditionalSelBack=2601(colour back,)
# Set the alpha of the selection.
set void SetAdditionalSelAlpha=2602(int alpha,)
# Get the alpha of the selection.
get int GetAdditionalSelAlpha=2603(,)
# Set the foreground colour of additional carets.
set void SetAdditionalCaretFore=2604(colour fore,)
# Get the foreground colour of additional carets.
get colour GetAdditionalCaretFore=2605(,)
# Set the main selection to the next selection.
fun void RotateSelection=2606(,)
# Swap that caret and anchor of the main selection.
fun void SwapMainAnchorCaret=2607(,)
# Start notifying the container of all key presses and commands.
fun void StartRecord=3001(,)
@ -1974,6 +2115,10 @@ get int GetPropertyInt=4010(string key,)
# Retrieve the number of bits the current lexer needs for styling.
get int GetStyleBitsNeeded=4011(,)
# Retrieve the name of the lexer.
# Return the length of the text.
get int GetLexerLanguage=4012(, stringresult text)
# Notifications
# Type of modification and the action which caused the modification.
# These are defined as a bit mask to make it easy to specify which notifications are wanted.
@ -2039,6 +2184,7 @@ val SCMOD_NORM=0
val SCMOD_SHIFT=1
val SCMOD_CTRL=2
val SCMOD_ALT=4
val SCMOD_SUPER=8
################################################
# For SciLexer.h
@ -2922,8 +3068,19 @@ val SCE_ERLANG_FUNCTION_NAME=8
val SCE_ERLANG_CHARACTER=9
val SCE_ERLANG_MACRO=10
val SCE_ERLANG_RECORD=11
val SCE_ERLANG_SEPARATOR=12
val SCE_ERLANG_PREPROC=12
val SCE_ERLANG_NODE_NAME=13
val SCE_ERLANG_COMMENT_FUNCTION=14
val SCE_ERLANG_COMMENT_MODULE=15
val SCE_ERLANG_COMMENT_DOC=16
val SCE_ERLANG_COMMENT_DOC_MACRO=17
val SCE_ERLANG_ATOM_QUOTED=18
val SCE_ERLANG_MACRO_QUOTED=19
val SCE_ERLANG_RECORD_QUOTED=20
val SCE_ERLANG_NODE_NAME_QUOTED=21
val SCE_ERLANG_BIFS=22
val SCE_ERLANG_MODULES=23
val SCE_ERLANG_MODULES_ATT=24
val SCE_ERLANG_UNKNOWN=31
# Lexical states for SCLEX_OCTAVE are identical to MatLab
lex Octave=SCLEX_OCTAVE SCE_MATLAB_
@ -3269,7 +3426,6 @@ val SCE_INNO_KEYWORD=2
val SCE_INNO_PARAMETER=3
val SCE_INNO_SECTION=4
val SCE_INNO_PREPROC=5
val SCE_INNO_PREPROC_INLINE=6
val SCE_INNO_INLINE_EXPANSION=6
val SCE_INNO_COMMENT_PASCAL=7
val SCE_INNO_KEYWORD_PASCAL=8

View File

@ -12,13 +12,14 @@ namespace Scintilla {
/**
*/
class WindowAccessor : public Accessor {
// Private so WindowAccessor objects can not be copied
WindowAccessor(const WindowAccessor &source) : Accessor(), props(source.props) {}
WindowAccessor &operator=(const WindowAccessor &) { return *this; }
protected:
WindowID id;
PropSet &props;
PropertyGet &props;
int lenDoc;
char styleBuf[bufferSize];
@ -30,7 +31,7 @@ protected:
bool InternalIsLeadByte(char ch);
void Fill(int position);
public:
WindowAccessor(WindowID id_, PropSet &props_) :
WindowAccessor(WindowID id_, PropertyGet &props_) :
Accessor(), id(id_), props(props_),
lenDoc(-1), validLen(0), chFlags(0), chWhile(0) {
}

View File

@ -75,7 +75,7 @@ $(COMPLIB): DocumentAccessor.o WindowAccessor.o KeyWords.o StyleContext.o Docume
ScintillaBase.o ContractionState.o Editor.o ExternalLexer.o PropSet.o PlatGTK.o \
KeyMap.o LineMarker.o ScintillaGTK.o CellBuffer.o ViewStyle.o \
RESearch.o Style.o Indicator.o AutoComplete.o UniConversion.o CharClassify.o XPM.o \
RunStyles.o Decoration.o PositionCache.o PerLine.o \
RunStyles.o Decoration.o PositionCache.o PerLine.o Selection.o \
$(MARSHALLER) $(LEXOBJS)
$(AR) rc $@ $^
$(RANLIB) $@

View File

@ -1,162 +1,41 @@
A patch to Scintilla 1.79 containing our changes to Scintilla
(the column mode editing patch, removing unused lexers and an updated marshallers file).
diff -Naurp scintilla_orig/Editor.cxx scintilla/Editor.cxx
--- scintilla_orig/Editor.cxx 2009-06-27 08:02:37.000000000 +0200
+++ scintilla/Editor.cxx 2009-07-04 09:54:55.000000000 +0200
@@ -3509,22 +3509,51 @@ void Editor::AddChar(char ch) {
// AddCharUTF inserts an array of bytes which may or may not be in UTF-8.
void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
bool wasSelection = currentPos != anchor;
- ClearSelection();
- bool charReplaceAction = false;
- if (inOverstrike && !wasSelection && !RangeContainsProtected(currentPos, currentPos + 1)) {
- if (currentPos < (pdoc->Length())) {
- if (!IsEOLChar(pdoc->CharAt(currentPos))) {
- charReplaceAction = true;
- pdoc->BeginUndoAction();
- pdoc->DelChar(currentPos);
+ if(wasSelection && selType == selRectangle ) {
+ int startPos;
+ int endPos;
+
+ int c1 = pdoc->GetColumn(currentPos);
+ int c2 = pdoc->GetColumn(anchor);
+ int offset = c1 < c2 ? c1 : c2;
+
+ pdoc->BeginUndoAction();
+ SelectionLineIterator lineIterator(this, false);
+ while (lineIterator.Iterate()) {
+ startPos = lineIterator.startPos;
+ endPos = lineIterator.endPos;
+
+ if(pdoc->GetColumn(endPos) >= offset){
+ unsigned int chars = endPos - startPos;
+ if (0 != chars) {
+ pdoc->DeleteChars(startPos, chars);
+ }
+ pdoc->InsertString(startPos, s, len);
+ }
+ }
+ anchor += len;
+ currentPos += len;
+ SetRectangularRange();
+ pdoc->EndUndoAction();
+
+ } else {
+ ClearSelection();
+ bool charReplaceAction = false;
+ if (inOverstrike && !wasSelection && !RangeContainsProtected(currentPos, currentPos + 1)) {
+ if (currentPos < (pdoc->Length())) {
+ if (!IsEOLChar(pdoc->CharAt(currentPos))) {
+ charReplaceAction = true;
+ pdoc->BeginUndoAction();
+ pdoc->DelChar(currentPos);
+ }
}
}
- }
- if (pdoc->InsertString(currentPos, s, len)) {
- SetEmptySelection(currentPos + len);
- }
- if (charReplaceAction) {
- pdoc->EndUndoAction();
+ if (pdoc->InsertString(currentPos, s, len)) {
+ SetEmptySelection(currentPos + len);
+ }
+ if (charReplaceAction) {
+ pdoc->EndUndoAction();
+ }
}
// If in wrap mode rewrap current line so EnsureCaretVisible has accurate information
if (wrapState != eWrapNone) {
@@ -3698,14 +3727,41 @@ bool Editor::CanPaste() {
}
void Editor::Clear() {
- if (currentPos == anchor) {
+ bool wasSelection = currentPos != anchor;
+ if(wasSelection && selType == selRectangle ) {
+ int startPos;
+ int endPos;
+
+ int c1 = pdoc->GetColumn(currentPos);
+ int c2 = pdoc->GetColumn(anchor);
+ int offset = c1 < c2 ? c1 : c2;
+
+ pdoc->BeginUndoAction();
+ SelectionLineIterator lineIterator(this, false);
+ while (lineIterator.Iterate()) {
+ startPos = lineIterator.startPos;
+ endPos = lineIterator.endPos;
+
+ if(pdoc->GetColumn(endPos) >= offset){
+ unsigned int chars = endPos - startPos;
+ if (0 != chars) {
+ pdoc->DeleteChars(startPos, chars);
+ } else
+ pdoc->DelChar(startPos);
+ }
+ }
+ SetRectangularRange();
+ pdoc->EndUndoAction();
+
+ } else if (currentPos == anchor) {
if (!RangeContainsProtected(currentPos, currentPos + 1)) {
DelChar();
}
} else {
ClearSelection();
}
- SetEmptySelection(currentPos);
+ if( !wasSelection )
+ SetEmptySelection(currentPos);
}
void Editor::SelectAll() {
@@ -3741,7 +3797,33 @@ void Editor::DelChar() {
}
void Editor::DelCharBack(bool allowLineStartDeletion) {
- if (currentPos == anchor) {
+ bool wasSelection = currentPos != anchor;
+ if(wasSelection && selType == selRectangle ) {
+ int startPos;
+ int endPos;
+
+ int c1 = pdoc->GetColumn(currentPos);
+ int c2 = pdoc->GetColumn(anchor);
+ int offset = c1 < c2 ? c1 : c2;
+
+ pdoc->BeginUndoAction();
+ SelectionLineIterator lineIterator(this, false);
+ while (lineIterator.Iterate()) {
+ startPos = lineIterator.startPos;
+ endPos = lineIterator.endPos;
+
+ if(pdoc->GetColumn(endPos) >= offset){
+ unsigned int chars = endPos - startPos;
+ if (0 != chars) {
+ pdoc->DeleteChars(startPos, chars);
+ } else
+ pdoc->DelCharBack(startPos);
+ }
+ }
+ SetRectangularRange();
+ pdoc->EndUndoAction();
+
+ } else if (currentPos == anchor) {
if (!RangeContainsProtected(currentPos - 1, currentPos)) {
int lineCurrentPos = pdoc->LineFromPosition(currentPos);
if (allowLineStartDeletion || (pdoc->LineStart(lineCurrentPos) != currentPos)) {
diff -Naurp scintilla_orig/KeyWords.cxx scintilla/KeyWords.cxx
--- scintilla_orig/KeyWords.cxx 2009-05-15 12:20:26.000000000 +0200
+++ scintilla/KeyWords.cxx 2009-07-04 09:55:30.000000000 +0200
@@ -141,97 +141,35 @@ int Scintilla_LinkLexers() {
A patch to Scintilla 2.03 containing our changes to Scintilla
(removing unused lexers and an updated marshallers file).
diff -Naur scintilla_orig//gtk/scintilla-marshal.c scintilla/gtk/scintilla-marshal.c
--- scintilla_orig//gtk/scintilla-marshal.c 2004-04-04 11:59:37.000000000 +0200
+++ scintilla/gtk/scintilla-marshal.c 2010-03-07 10:39:08.000000000 +0100
@@ -35,8 +35,8 @@
#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_enum(v) (v)->data[0].v_long
+#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
#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
@@ -50,10 +50,10 @@
/* NONE:INT,POINTER (scintilla-marshal.list:1) */
void
scintilla_marshal_VOID__INT_POINTER (GClosure *closure,
- GValue *return_value,
+ GValue *return_value G_GNUC_UNUSED,
guint n_param_values,
const GValue *param_values,
- gpointer invocation_hint,
+ gpointer invocation_hint G_GNUC_UNUSED,
gpointer marshal_data)
{
typedef void (*GMarshalFunc_VOID__INT_POINTER) (gpointer data1,
diff -Naur scintilla_orig//src/KeyWords.cxx scintilla/src/KeyWords.cxx
--- scintilla_orig//src/KeyWords.cxx 2009-08-27 03:20:38.000000000 +0200
+++ scintilla/src/KeyWords.cxx 2010-03-07 10:38:53.000000000 +0100
@@ -327,99 +327,37 @@
//++Autogenerated -- run src/LexGen.py to regenerate
//**\(\tLINK_LEXER(\*);\n\)
- LINK_LEXER(lmAbaqus);
LINK_LEXER(lmAda);
- LINK_LEXER(lmAda);
- LINK_LEXER(lmAns1);
- LINK_LEXER(lmAPDL);
LINK_LEXER(lmAsm);
@ -203,6 +82,7 @@ diff -Naurp scintilla_orig/KeyWords.cxx scintilla/KeyWords.cxx
LINK_LEXER(lmLua);
- LINK_LEXER(lmMagikSF);
LINK_LEXER(lmMake);
LINK_LEXER(lmMarkdown);
LINK_LEXER(lmMatlab);
- LINK_LEXER(lmMETAPOST);
- LINK_LEXER(lmMMIXAL);
@ -247,32 +127,7 @@ diff -Naurp scintilla_orig/KeyWords.cxx scintilla/KeyWords.cxx
- LINK_LEXER(lmVBScript);
- LINK_LEXER(lmVerilog);
LINK_LEXER(lmVHDL);
+ LINK_LEXER(lmVerilog);
LINK_LEXER(lmXML);
LINK_LEXER(lmYAML);
diff -Naurp scintilla_orig/scintilla-marshal.c scintilla/scintilla-marshal.c
--- scintilla_orig/scintilla-marshal.c 2004-04-04 11:59:37.000000000 +0200
+++ scintilla/scintilla-marshal.c 2009-06-21 23:17:08.000000000 +0200
@@ -35,8 +35,8 @@
#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_enum(v) (v)->data[0].v_long
+#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
#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
@@ -50,10 +50,10 @@
/* NONE:INT,POINTER (scintilla-marshal.list:1) */
void
scintilla_marshal_VOID__INT_POINTER (GClosure *closure,
- GValue *return_value,
+ GValue *return_value G_GNUC_UNUSED,
guint n_param_values,
const GValue *param_values,
- gpointer invocation_hint,
+ gpointer invocation_hint G_GNUC_UNUSED,
gpointer marshal_data)
{
typedef void (*GMarshalFunc_VOID__INT_POINTER) (gpointer data1,

View File

@ -99,7 +99,7 @@ scintilla_sources = [
'scintilla/PlatGTK.cxx',
'scintilla/PositionCache.cxx', 'scintilla/PropSet.cxx', 'scintilla/RESearch.cxx',
'scintilla/RunStyles.cxx', 'scintilla/ScintillaBase.cxx', 'scintilla/ScintillaGTK.cxx',
'scintilla/scintilla-marshal.c', 'scintilla/StyleContext.cxx', 'scintilla/Style.cxx',
'scintilla/scintilla-marshal.c', 'scintilla/Selection.cxx', 'scintilla/StyleContext.cxx', 'scintilla/Style.cxx',
'scintilla/UniConversion.cxx', 'scintilla/ViewStyle.cxx', 'scintilla/WindowAccessor.cxx',
'scintilla/XPM.cxx' ]