Merge branch 'scintilla/update-373'
Update Scintilla to version 3.7.3 plus a fix for a regression on it. Closes #1320.
This commit is contained in:
commit
b07c8b01c0
@ -17,6 +17,10 @@ commentblock=comment
|
||||
stringeol=string_eol
|
||||
word2=keyword_2
|
||||
decorator=decorator
|
||||
fstring=string_1
|
||||
fcharacter=character
|
||||
ftriple=string_2
|
||||
ftripledouble=string_2
|
||||
|
||||
[keywords]
|
||||
# all items must be in one line
|
||||
|
@ -1034,10 +1034,30 @@ void Window::SetPosition(PRectangle rc) {
|
||||
gtk_widget_size_allocate(PWidget(wid), &alloc);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
GdkRectangle MonitorRectangleForWidget(GtkWidget *wid) {
|
||||
GdkWindow *wnd = WindowFromWidget(wid);
|
||||
GdkRectangle rcScreen = GdkRectangle();
|
||||
#if GTK_CHECK_VERSION(3,22,0)
|
||||
GdkDisplay *pdisplay = gtk_widget_get_display(wid);
|
||||
GdkMonitor *monitor = gdk_display_get_monitor_at_window(pdisplay, wnd);
|
||||
gdk_monitor_get_geometry(monitor, &rcScreen);
|
||||
#else
|
||||
GdkScreen* screen = gtk_widget_get_screen(wid);
|
||||
gint monitor_num = gdk_screen_get_monitor_at_window(screen, wnd);
|
||||
gdk_screen_get_monitor_geometry(screen, monitor_num, &rcScreen);
|
||||
#endif
|
||||
return rcScreen;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Window::SetPositionRelative(PRectangle rc, Window relativeTo) {
|
||||
int ox = 0;
|
||||
int oy = 0;
|
||||
gdk_window_get_origin(WindowFromWidget(PWidget(relativeTo.wid)), &ox, &oy);
|
||||
GdkWindow *wndRelativeTo = WindowFromWidget(PWidget(relativeTo.wid));
|
||||
gdk_window_get_origin(wndRelativeTo, &ox, &oy);
|
||||
ox += rc.left;
|
||||
if (ox < 0)
|
||||
ox = 0;
|
||||
@ -1045,11 +1065,13 @@ void Window::SetPositionRelative(PRectangle rc, Window relativeTo) {
|
||||
if (oy < 0)
|
||||
oy = 0;
|
||||
|
||||
GdkRectangle rcScreen = MonitorRectangleForWidget(PWidget(relativeTo.wid));
|
||||
|
||||
/* do some corrections to fit into screen */
|
||||
int sizex = rc.right - rc.left;
|
||||
int sizey = rc.bottom - rc.top;
|
||||
int screenWidth = gdk_screen_width();
|
||||
int screenHeight = gdk_screen_height();
|
||||
const int screenWidth = rcScreen.width;
|
||||
const int screenHeight = rcScreen.height;
|
||||
if (sizex > screenWidth)
|
||||
ox = 0; /* the best we can do */
|
||||
else if (ox + sizex > screenWidth)
|
||||
@ -1145,13 +1167,19 @@ PRectangle Window::GetMonitorRect(Point pt) {
|
||||
|
||||
gdk_window_get_origin(WindowFromWidget(PWidget(wid)), &x_offset, &y_offset);
|
||||
|
||||
GdkScreen* screen;
|
||||
gint monitor_num;
|
||||
GdkRectangle rect;
|
||||
|
||||
screen = gtk_widget_get_screen(PWidget(wid));
|
||||
monitor_num = gdk_screen_get_monitor_at_point(screen, pt.x + x_offset, pt.y + y_offset);
|
||||
#if GTK_CHECK_VERSION(3,22,0)
|
||||
GdkDisplay *pdisplay = gtk_widget_get_display(PWidget(wid));
|
||||
GdkMonitor *monitor = gdk_display_get_monitor_at_point(pdisplay,
|
||||
pt.x + x_offset, pt.y + y_offset);
|
||||
gdk_monitor_get_geometry(monitor, &rect);
|
||||
#else
|
||||
GdkScreen* screen = gtk_widget_get_screen(PWidget(wid));
|
||||
gint monitor_num = gdk_screen_get_monitor_at_point(screen,
|
||||
pt.x + x_offset, pt.y + y_offset);
|
||||
gdk_screen_get_monitor_geometry(screen, monitor_num, &rect);
|
||||
#endif
|
||||
rect.x -= x_offset;
|
||||
rect.y -= y_offset;
|
||||
return PRectangle(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height);
|
||||
@ -1401,7 +1429,7 @@ static void StyleSet(GtkWidget *w, GtkStyle*, void*) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void ListBoxX::Create(Window &, int, Point, int, bool, int) {
|
||||
void ListBoxX::Create(Window &parent, int, Point, int, bool, int) {
|
||||
if (widCached != 0) {
|
||||
wid = widCached;
|
||||
return;
|
||||
@ -1475,6 +1503,10 @@ void ListBoxX::Create(Window &, int, Point, int, bool, int) {
|
||||
gtk_widget_show(widget);
|
||||
g_signal_connect(G_OBJECT(widget), "button_press_event",
|
||||
G_CALLBACK(ButtonPress), this);
|
||||
|
||||
GtkWidget *top = gtk_widget_get_toplevel(static_cast<GtkWidget *>(parent.GetID()));
|
||||
gtk_window_set_transient_for(GTK_WINDOW(static_cast<GtkWidget *>(wid)),
|
||||
GTK_WINDOW(top));
|
||||
}
|
||||
|
||||
void ListBoxX::SetFont(Font &scint_font) {
|
||||
@ -1882,17 +1914,24 @@ void Menu::Destroy() {
|
||||
mid = 0;
|
||||
}
|
||||
|
||||
#if !GTK_CHECK_VERSION(3,22,0)
|
||||
static void MenuPositionFunc(GtkMenu *, gint *x, gint *y, gboolean *, gpointer userData) {
|
||||
sptr_t intFromPointer = GPOINTER_TO_INT(userData);
|
||||
*x = intFromPointer & 0xffff;
|
||||
*y = intFromPointer >> 16;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Menu::Show(Point pt, Window &) {
|
||||
int screenHeight = gdk_screen_height();
|
||||
int screenWidth = gdk_screen_width();
|
||||
void Menu::Show(Point pt, Window &wnd) {
|
||||
GtkMenu *widget = static_cast<GtkMenu *>(mid);
|
||||
gtk_widget_show_all(GTK_WIDGET(widget));
|
||||
#if GTK_CHECK_VERSION(3,22,0)
|
||||
// Rely on GTK+ to do the right thing with positioning
|
||||
gtk_menu_popup_at_pointer(widget, NULL);
|
||||
#else
|
||||
GdkRectangle rcScreen = MonitorRectangleForWidget(PWidget(wnd.GetID()));
|
||||
const int screenWidth = rcScreen.width;
|
||||
const int screenHeight = rcScreen.height;
|
||||
GtkRequisition requisition;
|
||||
#if GTK_CHECK_VERSION(3,0,0)
|
||||
gtk_widget_get_preferred_size(GTK_WIDGET(widget), NULL, &requisition);
|
||||
@ -1908,6 +1947,7 @@ void Menu::Show(Point pt, Window &) {
|
||||
gtk_menu_popup(widget, NULL, NULL, MenuPositionFunc,
|
||||
GINT_TO_POINTER((static_cast<int>(pt.y) << 16) | static_cast<int>(pt.x)), 0,
|
||||
gtk_get_current_event_time());
|
||||
#endif
|
||||
}
|
||||
|
||||
ElapsedTime::ElapsedTime() {
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
@ -22,6 +23,9 @@
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#if defined(GDK_WINDOWING_WAYLAND)
|
||||
#include <gdk/gdkwayland.h>
|
||||
#endif
|
||||
|
||||
#if defined(__WIN32__) || defined(_MSC_VER)
|
||||
#include <windows.h>
|
||||
@ -165,6 +169,8 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) :
|
||||
im_context(NULL), lastNonCommonScript(PANGO_SCRIPT_INVALID_CODE),
|
||||
lastWheelMouseDirection(0),
|
||||
wheelMouseIntensity(0),
|
||||
smoothScrollY(0),
|
||||
smoothScrollX(0),
|
||||
rgnUpdate(0),
|
||||
repaintFullWindow(false),
|
||||
styleIdleID(0),
|
||||
@ -545,11 +551,21 @@ void ScintillaGTK::Initialise() {
|
||||
parentClass = reinterpret_cast<GtkWidgetClass *>(
|
||||
g_type_class_ref(gtk_container_get_type()));
|
||||
|
||||
gint maskSmooth = 0;
|
||||
#if defined(GDK_WINDOWING_WAYLAND)
|
||||
GdkDisplay *pdisplay = gdk_display_get_default();
|
||||
if (GDK_IS_WAYLAND_DISPLAY(pdisplay)) {
|
||||
// On Wayland, touch pads only produce smooth scroll events
|
||||
maskSmooth = GDK_SMOOTH_SCROLL_MASK;
|
||||
}
|
||||
#endif
|
||||
|
||||
gtk_widget_set_can_focus(PWidget(wMain), TRUE);
|
||||
gtk_widget_set_sensitive(PWidget(wMain), TRUE);
|
||||
gtk_widget_set_events(PWidget(wMain),
|
||||
GDK_EXPOSURE_MASK
|
||||
| GDK_SCROLL_MASK
|
||||
| maskSmooth
|
||||
| GDK_STRUCTURE_MASK
|
||||
| GDK_KEY_PRESS_MASK
|
||||
| GDK_KEY_RELEASE_MASK
|
||||
@ -1301,6 +1317,9 @@ void ScintillaGTK::CreateCallTipWindow(PRectangle rc) {
|
||||
G_CALLBACK(ScintillaGTK::PressCT), static_cast<void *>(this));
|
||||
gtk_widget_set_events(widcdrw,
|
||||
GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
|
||||
GtkWidget *top = gtk_widget_get_toplevel(static_cast<GtkWidget *>(wMain.GetID()));
|
||||
gtk_window_set_transient_for(GTK_WINDOW(static_cast<GtkWidget *>(PWidget(ct.wCallTip))),
|
||||
GTK_WINDOW(top));
|
||||
}
|
||||
gtk_widget_set_size_request(PWidget(ct.wDraw), rc.Width(), rc.Height());
|
||||
ct.wDraw.Show();
|
||||
@ -1781,6 +1800,25 @@ gint ScintillaGTK::ScrollEvent(GtkWidget *widget, GdkEventScroll *event) {
|
||||
if (widget == NULL || event == NULL)
|
||||
return FALSE;
|
||||
|
||||
#if defined(GDK_WINDOWING_WAYLAND)
|
||||
if (event->direction == GDK_SCROLL_SMOOTH && GDK_IS_WAYLAND_WINDOW (event->window)) {
|
||||
const int smoothScrollFactor = 4;
|
||||
sciThis->smoothScrollY += event->delta_y * smoothScrollFactor;
|
||||
sciThis->smoothScrollX += event->delta_x * smoothScrollFactor;;
|
||||
if (ABS(sciThis->smoothScrollY) >= 1.0) {
|
||||
const int scrollLines = trunc(sciThis->smoothScrollY);
|
||||
sciThis->ScrollTo(sciThis->topLine + scrollLines);
|
||||
sciThis->smoothScrollY -= scrollLines;
|
||||
}
|
||||
if (ABS(sciThis->smoothScrollX) >= 1.0) {
|
||||
const int scrollPixels = trunc(sciThis->smoothScrollX);
|
||||
sciThis->HorizontalScrollTo(sciThis->xOffset + scrollPixels);
|
||||
sciThis->smoothScrollX -= scrollPixels;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Compute amount and direction to scroll (even tho on win32 there is
|
||||
// intensity of scrolling info in the native message, gtk doesn't
|
||||
// support this so we simulate similarly adaptive scrolling)
|
||||
@ -2397,7 +2435,9 @@ void ScintillaGTK::StyleSetText(GtkWidget *widget, GtkStyle *, void*) {
|
||||
void ScintillaGTK::RealizeText(GtkWidget *widget, void*) {
|
||||
// Set NULL background to avoid automatic clearing so Scintilla responsible for all drawing
|
||||
if (WindowFromWidget(widget)) {
|
||||
#if GTK_CHECK_VERSION(3,0,0)
|
||||
#if GTK_CHECK_VERSION(3,22,0)
|
||||
// Appears unnecessary
|
||||
#elif GTK_CHECK_VERSION(3,0,0)
|
||||
gdk_window_set_background_pattern(WindowFromWidget(widget), NULL);
|
||||
#else
|
||||
gdk_window_set_back_pixmap(WindowFromWidget(widget), NULL, FALSE);
|
||||
|
@ -57,6 +57,8 @@ class ScintillaGTK : public ScintillaBase {
|
||||
GTimeVal lastWheelMouseTime;
|
||||
gint lastWheelMouseDirection;
|
||||
gint wheelMouseIntensity;
|
||||
gdouble smoothScrollY;
|
||||
gdouble smoothScrollX;
|
||||
|
||||
#if GTK_CHECK_VERSION(3,0,0)
|
||||
cairo_rectangle_list_t *rgnUpdate;
|
||||
|
@ -151,6 +151,10 @@
|
||||
#define SCE_P_STRINGEOL 13
|
||||
#define SCE_P_WORD2 14
|
||||
#define SCE_P_DECORATOR 15
|
||||
#define SCE_P_FSTRING 16
|
||||
#define SCE_P_FCHARACTER 17
|
||||
#define SCE_P_FTRIPLE 18
|
||||
#define SCE_P_FTRIPLEDOUBLE 19
|
||||
#define SCE_C_DEFAULT 0
|
||||
#define SCE_C_COMMENT 1
|
||||
#define SCE_C_COMMENTLINE 2
|
||||
|
@ -2354,10 +2354,10 @@ get bool GetSelectionEmpty=2650(,)
|
||||
fun void ClearSelections=2571(,)
|
||||
|
||||
# Set a simple selection
|
||||
fun int SetSelection=2572(position caret, position anchor)
|
||||
fun void SetSelection=2572(position caret, position anchor)
|
||||
|
||||
# Add a selection
|
||||
fun int AddSelection=2573(position caret, position anchor)
|
||||
fun void AddSelection=2573(position caret, position anchor)
|
||||
|
||||
# Drop one selection
|
||||
fun void DropSelectionN=2671(int selection,)
|
||||
@ -2914,6 +2914,10 @@ val SCE_P_COMMENTBLOCK=12
|
||||
val SCE_P_STRINGEOL=13
|
||||
val SCE_P_WORD2=14
|
||||
val SCE_P_DECORATOR=15
|
||||
val SCE_P_FSTRING=16
|
||||
val SCE_P_FCHARACTER=17
|
||||
val SCE_P_FTRIPLE=18
|
||||
val SCE_P_FTRIPLEDOUBLE=19
|
||||
# Lexical states for SCLEX_CPP, SCLEX_BULLANT, SCLEX_COBOL, SCLEX_TACL, SCLEX_TAL
|
||||
lex Cpp=SCLEX_CPP SCE_C_
|
||||
lex BullAnt=SCLEX_BULLANT SCE_C_
|
||||
|
@ -51,8 +51,10 @@ static void ColouriseDiffLine(char *lineBuffer, Sci_Position endLine, Accessor &
|
||||
styler.ColourTo(endLine, SCE_DIFF_POSITION);
|
||||
else if (lineBuffer[3] == '\r' || lineBuffer[3] == '\n')
|
||||
styler.ColourTo(endLine, SCE_DIFF_POSITION);
|
||||
else
|
||||
else if (lineBuffer[3] == ' ')
|
||||
styler.ColourTo(endLine, SCE_DIFF_HEADER);
|
||||
else
|
||||
styler.ColourTo(endLine, SCE_DIFF_DELETED);
|
||||
} else if (0 == strncmp(lineBuffer, "+++ ", 4)) {
|
||||
// I don't know of any diff where "+++ " is a position marker, but for
|
||||
// consistency, do the same as with "--- " and "*** ".
|
||||
|
@ -89,8 +89,8 @@ static void ColouriseLuaDoc(
|
||||
}
|
||||
|
||||
StyleContext sc(startPos, length, initStyle, styler);
|
||||
if (startPos == 0 && sc.ch == '#') {
|
||||
// shbang line: # is a comment only if first char of the script
|
||||
if (startPos == 0 && sc.ch == '#' && sc.chNext == '!') {
|
||||
// shbang line: "#!" is a comment only if located at the start of the script
|
||||
sc.SetState(SCE_LUA_COMMENTLINE);
|
||||
}
|
||||
for (; sc.More(); sc.Forward()) {
|
||||
|
@ -18,6 +18,9 @@
|
||||
**
|
||||
** Changes by John Donoghue 2016/11/15
|
||||
** - update matlab code folding
|
||||
**
|
||||
** Changes by John Donoghue 2017/01/18
|
||||
** - update matlab block comment detection
|
||||
**/
|
||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
@ -73,6 +76,15 @@ static int CheckKeywordFoldPoint(char *str) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool IsSpaceToEOL(Sci_Position startPos, Accessor &styler) {
|
||||
Sci_Position line = styler.GetLine(startPos);
|
||||
Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
|
||||
for (Sci_Position i = startPos; i < eol_pos; i++) {
|
||||
char ch = styler[i];
|
||||
if(!IsASpace(ch)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ColouriseMatlabOctaveDoc(
|
||||
Sci_PositionU startPos, Sci_Position length, int initStyle,
|
||||
@ -180,7 +192,7 @@ static void ColouriseMatlabOctaveDoc(
|
||||
}
|
||||
} else if (sc.state == SCE_MATLAB_COMMENT) {
|
||||
// end or start of a nested a block comment?
|
||||
if( IsCommentChar(sc.ch) && sc.chNext == '}' && nonSpaceColumn == column) {
|
||||
if( IsCommentChar(sc.ch) && sc.chNext == '}' && nonSpaceColumn == column && IsSpaceToEOL(sc.currentPos+2, styler)) {
|
||||
if(commentDepth > 0) commentDepth --;
|
||||
|
||||
curLine = styler.GetLine(sc.currentPos);
|
||||
@ -192,7 +204,7 @@ static void ColouriseMatlabOctaveDoc(
|
||||
transpose = false;
|
||||
}
|
||||
}
|
||||
else if( IsCommentChar(sc.ch) && sc.chNext == '{' && nonSpaceColumn == column)
|
||||
else if( IsCommentChar(sc.ch) && sc.chNext == '{' && nonSpaceColumn == column && IsSpaceToEOL(sc.currentPos+2, styler))
|
||||
{
|
||||
commentDepth ++;
|
||||
|
||||
@ -214,8 +226,11 @@ static void ColouriseMatlabOctaveDoc(
|
||||
if (sc.state == SCE_MATLAB_DEFAULT) {
|
||||
if (IsCommentChar(sc.ch)) {
|
||||
// ncrement depth if we are a block comment
|
||||
if(sc.chNext == '{' && nonSpaceColumn == column)
|
||||
commentDepth ++;
|
||||
if(sc.chNext == '{' && nonSpaceColumn == column) {
|
||||
if(IsSpaceToEOL(sc.currentPos+2, styler)) {
|
||||
commentDepth ++;
|
||||
}
|
||||
}
|
||||
curLine = styler.GetLine(sc.currentPos);
|
||||
styler.SetLineState(curLine, commentDepth);
|
||||
sc.SetState(SCE_MATLAB_COMMENT);
|
||||
@ -284,13 +299,13 @@ static void FoldMatlabOctaveDoc(Sci_PositionU startPos, Sci_Position length, int
|
||||
style = styleNext;
|
||||
styleNext = styler.StyleAt(i + 1);
|
||||
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
|
||||
|
||||
|
||||
// a line that starts with a comment
|
||||
if (style == SCE_MATLAB_COMMENT && IsComment(ch) && visibleChars == 0) {
|
||||
// start/end of block comment
|
||||
if (chNext == '{')
|
||||
// start/end of block comment
|
||||
if (chNext == '{' && IsSpaceToEOL(i+2, styler))
|
||||
levelNext ++;
|
||||
if (chNext == '}')
|
||||
if (chNext == '}' && IsSpaceToEOL(i+2, styler))
|
||||
levelNext --;
|
||||
}
|
||||
// keyword
|
||||
@ -303,7 +318,7 @@ static void FoldMatlabOctaveDoc(Sci_PositionU startPos, Sci_Position length, int
|
||||
if (styleNext != SCE_MATLAB_KEYWORD) {
|
||||
word[wordlen] = '\0';
|
||||
wordlen = 0;
|
||||
|
||||
|
||||
levelNext += CheckKeywordFoldPoint(word);
|
||||
}
|
||||
}
|
||||
|
@ -20,11 +20,13 @@
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "StringCopy.h"
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
#include "StyleContext.h"
|
||||
#include "CharacterSet.h"
|
||||
#include "CharacterCategory.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "SubStyles.h"
|
||||
@ -39,7 +41,7 @@ namespace {
|
||||
/* kwCDef, kwCTypeName only used for Cython */
|
||||
enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName, kwCPDef };
|
||||
|
||||
enum literalsAllowed { litNone = 0, litU = 1, litB = 2 };
|
||||
enum literalsAllowed { litNone = 0, litU = 1, litB = 2, litF = 4 };
|
||||
|
||||
const int indicatorWhitespace = 1;
|
||||
|
||||
@ -50,7 +52,8 @@ bool IsPyComment(Accessor &styler, Sci_Position pos, Sci_Position len) {
|
||||
bool IsPyStringTypeChar(int ch, literalsAllowed allowed) {
|
||||
return
|
||||
((allowed & litB) && (ch == 'b' || ch == 'B')) ||
|
||||
((allowed & litU) && (ch == 'u' || ch == 'U'));
|
||||
((allowed & litU) && (ch == 'u' || ch == 'U')) ||
|
||||
((allowed & litF) && (ch == 'f' || ch == 'F'));
|
||||
}
|
||||
|
||||
bool IsPyStringStart(int ch, int chNext, int chNext2, literalsAllowed allowed) {
|
||||
@ -68,12 +71,44 @@ bool IsPyStringStart(int ch, int chNext, int chNext2, literalsAllowed allowed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsPyFStringState(int st) {
|
||||
return ((st == SCE_P_FCHARACTER) || (st == SCE_P_FSTRING) ||
|
||||
(st == SCE_P_FTRIPLE) || (st == SCE_P_FTRIPLEDOUBLE));
|
||||
}
|
||||
|
||||
bool IsPySingleQuoteStringState(int st) {
|
||||
return ((st == SCE_P_CHARACTER) || (st == SCE_P_STRING) ||
|
||||
(st == SCE_P_FCHARACTER) || (st == SCE_P_FSTRING));
|
||||
}
|
||||
|
||||
bool IsPyTripleQuoteStringState(int st) {
|
||||
return ((st == SCE_P_TRIPLE) || (st == SCE_P_TRIPLEDOUBLE) ||
|
||||
(st == SCE_P_FTRIPLE) || (st == SCE_P_FTRIPLEDOUBLE));
|
||||
}
|
||||
|
||||
void PushStateToStack(int state, int *stack, int stackSize) {
|
||||
for (int i = stackSize-1; i > 0; i--) {
|
||||
stack[i] = stack[i-1];
|
||||
}
|
||||
stack[0] = state;
|
||||
}
|
||||
|
||||
int PopFromStateStack(int *stack, int stackSize) {
|
||||
int top = stack[0];
|
||||
for (int i = 0; i < stackSize - 1; i++) {
|
||||
stack[i] = stack[i+1];
|
||||
}
|
||||
stack[stackSize-1] = 0;
|
||||
return top;
|
||||
}
|
||||
|
||||
/* Return the state to use for the string starting at i; *nextIndex will be set to the first index following the quote(s) */
|
||||
int GetPyStringState(Accessor &styler, Sci_Position i, Sci_PositionU *nextIndex, literalsAllowed allowed) {
|
||||
char ch = styler.SafeGetCharAt(i);
|
||||
char chNext = styler.SafeGetCharAt(i + 1);
|
||||
int firstIsF = (ch == 'f' || ch == 'F');
|
||||
|
||||
// Advance beyond r, u, or ur prefix (or r, b, or br in Python 3.0), but bail if there are any unexpected chars
|
||||
// Advance beyond r, u, or ur prefix (or r, b, or br in Python 2.7+ and r, f, or fr in Python 3.6+), but bail if there are any unexpected chars
|
||||
if (ch == 'r' || ch == 'R') {
|
||||
i++;
|
||||
ch = styler.SafeGetCharAt(i);
|
||||
@ -96,25 +131,45 @@ int GetPyStringState(Accessor &styler, Sci_Position i, Sci_PositionU *nextIndex,
|
||||
*nextIndex = i + 3;
|
||||
|
||||
if (ch == '"')
|
||||
return SCE_P_TRIPLEDOUBLE;
|
||||
return (firstIsF ? SCE_P_FTRIPLEDOUBLE : SCE_P_TRIPLEDOUBLE);
|
||||
else
|
||||
return SCE_P_TRIPLE;
|
||||
return (firstIsF ? SCE_P_FTRIPLE : SCE_P_TRIPLE);
|
||||
} else {
|
||||
*nextIndex = i + 1;
|
||||
|
||||
if (ch == '"')
|
||||
return SCE_P_STRING;
|
||||
return (firstIsF ? SCE_P_FSTRING : SCE_P_STRING);
|
||||
else
|
||||
return SCE_P_CHARACTER;
|
||||
return (firstIsF ? SCE_P_FCHARACTER : SCE_P_CHARACTER);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool IsAWordChar(int ch) {
|
||||
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
|
||||
inline bool IsAWordChar(int ch, bool unicodeIdentifiers) {
|
||||
if (ch < 0x80)
|
||||
return (isalnum(ch) || ch == '.' || ch == '_');
|
||||
|
||||
if (!unicodeIdentifiers)
|
||||
return false;
|
||||
|
||||
// Approximation, Python uses the XID_Continue set from unicode data
|
||||
// see http://unicode.org/reports/tr31/
|
||||
CharacterCategory c = CategoriseCharacter(ch);
|
||||
return (c == ccLl || c == ccLu || c == ccLt || c == ccLm || c == ccLo
|
||||
|| c == ccNl || c == ccMn || c == ccMc || c == ccNd || c == ccPc);
|
||||
}
|
||||
|
||||
inline bool IsAWordStart(int ch) {
|
||||
return (ch < 0x80) && (isalnum(ch) || ch == '_');
|
||||
inline bool IsAWordStart(int ch, bool unicodeIdentifiers) {
|
||||
if (ch < 0x80)
|
||||
return (isalpha(ch) || ch == '_');
|
||||
|
||||
if (!unicodeIdentifiers)
|
||||
return false;
|
||||
|
||||
// Approximation, Python uses the XID_Start set from unicode data
|
||||
// see http://unicode.org/reports/tr31/
|
||||
CharacterCategory c = CategoriseCharacter(ch);
|
||||
return (c == ccLl || c == ccLu || c == ccLt || c == ccLm || c == ccLo
|
||||
|| c == ccNl);
|
||||
}
|
||||
|
||||
static bool IsFirstNonWhitespace(Sci_Position pos, Accessor &styler) {
|
||||
@ -134,28 +189,34 @@ struct OptionsPython {
|
||||
bool base2or8Literals;
|
||||
bool stringsU;
|
||||
bool stringsB;
|
||||
bool stringsF;
|
||||
bool stringsOverNewline;
|
||||
bool keywords2NoSubIdentifiers;
|
||||
bool fold;
|
||||
bool foldQuotes;
|
||||
bool foldCompact;
|
||||
bool unicodeIdentifiers;
|
||||
|
||||
OptionsPython() {
|
||||
whingeLevel = 0;
|
||||
base2or8Literals = true;
|
||||
stringsU = true;
|
||||
stringsB = true;
|
||||
stringsF = true;
|
||||
stringsOverNewline = false;
|
||||
keywords2NoSubIdentifiers = false;
|
||||
fold = false;
|
||||
foldQuotes = false;
|
||||
foldCompact = false;
|
||||
unicodeIdentifiers = true;
|
||||
}
|
||||
|
||||
literalsAllowed AllowedLiterals() const {
|
||||
literalsAllowed allowedLiterals = stringsU ? litU : litNone;
|
||||
if (stringsB)
|
||||
allowedLiterals = static_cast<literalsAllowed>(allowedLiterals | litB);
|
||||
if (stringsF)
|
||||
allowedLiterals = static_cast<literalsAllowed>(allowedLiterals | litF);
|
||||
return allowedLiterals;
|
||||
}
|
||||
};
|
||||
@ -186,6 +247,9 @@ struct OptionSetPython : public OptionSet<OptionsPython> {
|
||||
DefineProperty("lexer.python.strings.b", &OptionsPython::stringsB,
|
||||
"Set to 0 to not recognise Python 3 bytes literals b\"x\".");
|
||||
|
||||
DefineProperty("lexer.python.strings.f", &OptionsPython::stringsF,
|
||||
"Set to 0 to not recognise Python 3.6 f-string literals f\"var={var}\".");
|
||||
|
||||
DefineProperty("lexer.python.strings.over.newline", &OptionsPython::stringsOverNewline,
|
||||
"Set to 1 to allow strings to span newline characters.");
|
||||
|
||||
@ -200,6 +264,9 @@ struct OptionSetPython : public OptionSet<OptionsPython> {
|
||||
|
||||
DefineProperty("fold.compact", &OptionsPython::foldCompact);
|
||||
|
||||
DefineProperty("lexer.python.unicode.identifiers", &OptionsPython::unicodeIdentifiers,
|
||||
"Set to 0 to not recognise Python 3 unicode identifiers.");
|
||||
|
||||
DefineWordListSets(pythonWordListDesc);
|
||||
}
|
||||
};
|
||||
@ -284,6 +351,9 @@ public:
|
||||
static ILexer *LexerFactoryPython() {
|
||||
return new LexerPython();
|
||||
}
|
||||
|
||||
private:
|
||||
void ProcessLineEnd(StyleContext &sc, int *fstringStateStack, bool &inContinuedString) const;
|
||||
};
|
||||
|
||||
Sci_Position SCI_METHOD LexerPython::PropertySet(const char *key, const char *val) {
|
||||
@ -315,9 +385,35 @@ Sci_Position SCI_METHOD LexerPython::WordListSet(int n, const char *wl) {
|
||||
return firstModification;
|
||||
}
|
||||
|
||||
void LexerPython::ProcessLineEnd(StyleContext &sc, int *fstringStateStack, bool &inContinuedString) const {
|
||||
// Restore to to outermost string state if in an f-string expression and
|
||||
// let code below decide what to do
|
||||
while (fstringStateStack[0] != 0) {
|
||||
sc.SetState(PopFromStateStack(fstringStateStack, 4));
|
||||
}
|
||||
|
||||
if ((sc.state == SCE_P_DEFAULT)
|
||||
|| IsPyTripleQuoteStringState(sc.state)) {
|
||||
// Perform colourisation of white space and triple quoted strings at end of each line to allow
|
||||
// tab marking to work inside white space and triple quoted strings
|
||||
sc.SetState(sc.state);
|
||||
}
|
||||
if (IsPySingleQuoteStringState(sc.state)) {
|
||||
if (inContinuedString || options.stringsOverNewline) {
|
||||
inContinuedString = false;
|
||||
} else {
|
||||
sc.ChangeState(SCE_P_STRINGEOL);
|
||||
sc.ForwardSetState(SCE_P_DEFAULT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
|
||||
Accessor styler(pAccess, NULL);
|
||||
|
||||
// Track whether in f-string expression; an array is used for a stack to
|
||||
// handle nested f-strings such as f"""{f'''{f"{f'{1}'}"}'''}"""
|
||||
int fstringStateStack[4] = { 0, };
|
||||
const Sci_Position endPos = startPos + length;
|
||||
|
||||
// Backtrack to previous line in case need to fix its tab whinging
|
||||
@ -383,39 +479,25 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
||||
}
|
||||
|
||||
if (sc.atLineEnd) {
|
||||
if ((sc.state == SCE_P_DEFAULT) ||
|
||||
(sc.state == SCE_P_TRIPLE) ||
|
||||
(sc.state == SCE_P_TRIPLEDOUBLE)) {
|
||||
// Perform colourisation of white space and triple quoted strings at end of each line to allow
|
||||
// tab marking to work inside white space and triple quoted strings
|
||||
sc.SetState(sc.state);
|
||||
}
|
||||
ProcessLineEnd(sc, fstringStateStack, inContinuedString);
|
||||
lineCurrent++;
|
||||
if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) {
|
||||
if (inContinuedString || options.stringsOverNewline) {
|
||||
inContinuedString = false;
|
||||
} else {
|
||||
sc.ChangeState(SCE_P_STRINGEOL);
|
||||
sc.ForwardSetState(SCE_P_DEFAULT);
|
||||
}
|
||||
}
|
||||
if (!sc.More())
|
||||
break;
|
||||
}
|
||||
|
||||
bool needEOLCheck = false;
|
||||
|
||||
// Check for a state end
|
||||
|
||||
if (sc.state == SCE_P_OPERATOR) {
|
||||
kwLast = kwOther;
|
||||
sc.SetState(SCE_P_DEFAULT);
|
||||
} else if (sc.state == SCE_P_NUMBER) {
|
||||
if (!IsAWordChar(sc.ch) &&
|
||||
if (!IsAWordChar(sc.ch, false) &&
|
||||
!(!base_n_number && ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
|
||||
sc.SetState(SCE_P_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_P_IDENTIFIER) {
|
||||
if ((sc.ch == '.') || (!IsAWordChar(sc.ch))) {
|
||||
if ((sc.ch == '.') || (!IsAWordChar(sc.ch, options.unicodeIdentifiers))) {
|
||||
char s[100];
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
int style = SCE_P_IDENTIFIER;
|
||||
@ -487,10 +569,10 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
||||
sc.SetState(SCE_P_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_P_DECORATOR) {
|
||||
if (!IsAWordChar(sc.ch)) {
|
||||
if (!IsAWordStart(sc.ch, options.unicodeIdentifiers)) {
|
||||
sc.SetState(SCE_P_DEFAULT);
|
||||
}
|
||||
} else if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) {
|
||||
} else if (IsPySingleQuoteStringState(sc.state)) {
|
||||
if (sc.ch == '\\') {
|
||||
if ((sc.chNext == '\r') && (sc.GetRelative(2) == '\n')) {
|
||||
sc.Forward();
|
||||
@ -501,14 +583,16 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
||||
// Don't roll over the newline.
|
||||
sc.Forward();
|
||||
}
|
||||
} else if ((sc.state == SCE_P_STRING) && (sc.ch == '\"')) {
|
||||
} else if (((sc.state == SCE_P_STRING || sc.state == SCE_P_FSTRING))
|
||||
&& (sc.ch == '\"')) {
|
||||
sc.ForwardSetState(SCE_P_DEFAULT);
|
||||
needEOLCheck = true;
|
||||
} else if ((sc.state == SCE_P_CHARACTER) && (sc.ch == '\'')) {
|
||||
} else if (((sc.state == SCE_P_CHARACTER) || (sc.state == SCE_P_FCHARACTER))
|
||||
&& (sc.ch == '\'')) {
|
||||
sc.ForwardSetState(SCE_P_DEFAULT);
|
||||
needEOLCheck = true;
|
||||
}
|
||||
} else if (sc.state == SCE_P_TRIPLE) {
|
||||
} else if ((sc.state == SCE_P_TRIPLE) || (sc.state == SCE_P_FTRIPLE)) {
|
||||
if (sc.ch == '\\') {
|
||||
sc.Forward();
|
||||
} else if (sc.Match("\'\'\'")) {
|
||||
@ -517,7 +601,7 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
||||
sc.ForwardSetState(SCE_P_DEFAULT);
|
||||
needEOLCheck = true;
|
||||
}
|
||||
} else if (sc.state == SCE_P_TRIPLEDOUBLE) {
|
||||
} else if ((sc.state == SCE_P_TRIPLEDOUBLE) || (sc.state == SCE_P_FTRIPLEDOUBLE)) {
|
||||
if (sc.ch == '\\') {
|
||||
sc.Forward();
|
||||
} else if (sc.Match("\"\"\"")) {
|
||||
@ -527,6 +611,19 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
||||
needEOLCheck = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Note if used and not if else because string states also match
|
||||
// some of the above clauses
|
||||
if (IsPyFStringState(sc.state) && sc.ch == '{') {
|
||||
if (sc.chNext == '{') {
|
||||
sc.Forward();
|
||||
} else {
|
||||
PushStateToStack(sc.state, fstringStateStack, ELEMENTS(fstringStateStack));
|
||||
sc.ForwardSetState(SCE_P_DEFAULT);
|
||||
}
|
||||
needEOLCheck = true;
|
||||
}
|
||||
// End of code to find the end of a state
|
||||
|
||||
if (!indentGood && !IsASpaceOrTab(sc.ch)) {
|
||||
styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 1);
|
||||
@ -541,12 +638,18 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
||||
|
||||
// State exit code may have moved on to end of line
|
||||
if (needEOLCheck && sc.atLineEnd) {
|
||||
ProcessLineEnd(sc, fstringStateStack, inContinuedString);
|
||||
lineCurrent++;
|
||||
styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
|
||||
if (!sc.More())
|
||||
break;
|
||||
}
|
||||
|
||||
// If in f-string expression, check for } to resume f-string state
|
||||
if (fstringStateStack[0] != 0 && sc.ch == '}') {
|
||||
sc.SetState(PopFromStateStack(fstringStateStack, ELEMENTS(fstringStateStack)));
|
||||
}
|
||||
|
||||
// Check for a new state starting character
|
||||
if (sc.state == SCE_P_DEFAULT) {
|
||||
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
|
||||
@ -581,7 +684,7 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
|
||||
while (nextIndex > (sc.currentPos + 1) && sc.More()) {
|
||||
sc.Forward();
|
||||
}
|
||||
} else if (IsAWordStart(sc.ch)) {
|
||||
} else if (IsAWordStart(sc.ch, options.unicodeIdentifiers)) {
|
||||
sc.SetState(SCE_P_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
|
@ -29,10 +29,7 @@ static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = fa
|
||||
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;
|
||||
}
|
||||
bool wordSeparator[256] = {}; // Initialise all to false.
|
||||
wordSeparator[static_cast<unsigned int>('\r')] = true;
|
||||
wordSeparator[static_cast<unsigned int>('\n')] = true;
|
||||
if (!onlyLineEnds) {
|
||||
@ -118,7 +115,7 @@ static int cmpWords(const void *a, const void *b) {
|
||||
}
|
||||
|
||||
static void SortWordList(char **words, unsigned int len) {
|
||||
qsort(reinterpret_cast<void *>(words), len, sizeof(*words), cmpWords);
|
||||
qsort(static_cast<void *>(words), len, sizeof(*words), cmpWords);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -134,8 +131,7 @@ void WordList::Set(const char *s) {
|
||||
#else
|
||||
SortWordList(words, len);
|
||||
#endif
|
||||
for (unsigned int k = 0; k < ELEMENTS(starts); k++)
|
||||
starts[k] = -1;
|
||||
std::fill(starts, starts + ELEMENTS(starts), -1);
|
||||
for (int l = len - 1; l >= 0; l--) {
|
||||
unsigned char indexChar = words[l][0];
|
||||
starts[indexChar] = l;
|
||||
|
@ -1805,7 +1805,7 @@ bool Document::MatchesWordOptions(bool word, bool wordStart, int pos, int length
|
||||
(wordStart && IsWordStartAt(pos));
|
||||
}
|
||||
|
||||
bool Document::HasCaseFolder(void) const {
|
||||
bool Document::HasCaseFolder() const {
|
||||
return pcf != 0;
|
||||
}
|
||||
|
||||
|
@ -400,7 +400,7 @@ public:
|
||||
bool IsWordAt(int start, int end) const;
|
||||
|
||||
bool MatchesWordOptions(bool word, bool wordStart, int pos, int length) const;
|
||||
bool HasCaseFolder(void) const;
|
||||
bool HasCaseFolder() const;
|
||||
void SetCaseFolder(CaseFolder *pcf_);
|
||||
long FindText(int minPos, int maxPos, const char *search, int flags, int *length);
|
||||
const char *SubstituteByPosition(const char *text, int *length);
|
||||
|
@ -1288,7 +1288,13 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt
|
||||
// For each selection draw
|
||||
for (size_t r = 0; (r<model.sel.Count()) || drawDrag; r++) {
|
||||
const bool mainCaret = r == model.sel.Main();
|
||||
const SelectionPosition posCaret = (drawDrag ? model.posDrag : model.sel.Range(r).caret);
|
||||
SelectionPosition posCaret = (drawDrag ? model.posDrag : model.sel.Range(r).caret);
|
||||
if (vsDraw.caretStyle == CARETSTYLE_BLOCK && !drawDrag && posCaret > model.sel.Range(r).anchor) {
|
||||
if (posCaret.VirtualSpace() > 0)
|
||||
posCaret.SetVirtualSpace(posCaret.VirtualSpace() - 1);
|
||||
else
|
||||
posCaret.SetPosition(model.pdoc->MovePositionOutsideChar(posCaret.Position()-1, -1));
|
||||
}
|
||||
const int offset = posCaret.Position() - posLineStart;
|
||||
const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth;
|
||||
const XYPOSITION virtualOffset = posCaret.VirtualSpace() * spaceWidth;
|
||||
@ -2085,7 +2091,7 @@ void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectan
|
||||
}
|
||||
|
||||
void EditView::FillLineRemainder(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
|
||||
int line, PRectangle rcArea, int subLine) {
|
||||
int line, PRectangle rcArea, int subLine) const {
|
||||
int eolInSelection = 0;
|
||||
int alpha = SC_ALPHA_NOALPHA;
|
||||
if (!hideSelection) {
|
||||
|
@ -143,7 +143,7 @@ public:
|
||||
void PaintText(Surface *surfaceWindow, const EditModel &model, PRectangle rcArea, PRectangle rcClient,
|
||||
const ViewStyle &vsDraw);
|
||||
void FillLineRemainder(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
|
||||
int line, PRectangle rcArea, int subLine);
|
||||
int line, PRectangle rcArea, int subLine) const;
|
||||
long FormatRange(bool draw, Sci_RangeToFormat *pfr, Surface *surface, Surface *surfaceMeasure,
|
||||
const EditModel &model, const ViewStyle &vs);
|
||||
};
|
||||
|
@ -2611,10 +2611,10 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) {
|
||||
if (pdoc->ContainsLineEnd(mh.text, mh.length) && (mh.position != pdoc->LineStart(lineOfPos)))
|
||||
endNeedShown = pdoc->LineStart(lineOfPos+1);
|
||||
} else if (mh.modificationType & SC_MOD_BEFOREDELETE) {
|
||||
// Extend the need shown area over any folded lines
|
||||
// If the deletion includes any EOL then we extend the need shown area.
|
||||
endNeedShown = mh.position + mh.length;
|
||||
int lineLast = pdoc->LineFromPosition(mh.position+mh.length);
|
||||
for (int line = lineOfPos; line <= lineLast; line++) {
|
||||
for (int line = lineOfPos + 1; line <= lineLast; line++) {
|
||||
const int lineMaxSubord = pdoc->GetLastChild(line, -1, -1);
|
||||
if (lineLast < lineMaxSubord) {
|
||||
lineLast = lineMaxSubord;
|
||||
@ -5500,7 +5500,7 @@ void Editor::FoldChanged(int line, int levelNow, int levelPrev) {
|
||||
if (!(levelNow & SC_FOLDLEVELWHITEFLAG) && (LevelNumber(levelPrev) < LevelNumber(levelNow))) {
|
||||
if (cs.HiddenLines()) {
|
||||
const int parentLine = pdoc->GetFoldParent(line);
|
||||
if (!cs.GetExpanded(parentLine) && cs.GetExpanded(line))
|
||||
if (!cs.GetExpanded(parentLine) && cs.GetVisible(line))
|
||||
FoldLine(parentLine, SC_FOLDACTION_EXPAND);
|
||||
}
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ int ScintillaBase::KeyCommand(unsigned int iMessage) {
|
||||
}
|
||||
|
||||
void ScintillaBase::AutoCompleteDoubleClick(void *p) {
|
||||
ScintillaBase *sci = reinterpret_cast<ScintillaBase *>(p);
|
||||
ScintillaBase *sci = static_cast<ScintillaBase *>(p);
|
||||
sci->AutoCompleteCompleted(0, SC_AC_DOUBLECLICK);
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ ColourDesired XPM::ColourFromCode(int ch) const {
|
||||
return colourCodeTable[ch];
|
||||
}
|
||||
|
||||
void XPM::FillRun(Surface *surface, int code, int startX, int y, int x) {
|
||||
void XPM::FillRun(Surface *surface, int code, int startX, int y, int x) const {
|
||||
if ((code != codeTransparent) && (startX != x)) {
|
||||
PRectangle rc = PRectangle::FromInts(startX, y, x, y + 1);
|
||||
surface->FillRectangle(rc, ColourFromCode(code));
|
||||
|
@ -23,7 +23,7 @@ class XPM {
|
||||
ColourDesired colourCodeTable[256];
|
||||
char codeTransparent;
|
||||
ColourDesired ColourFromCode(int ch) const;
|
||||
void FillRun(Surface *surface, int code, int startX, int y, int x);
|
||||
void FillRun(Surface *surface, int code, int startX, int y, int x) const;
|
||||
public:
|
||||
explicit XPM(const char *textForm);
|
||||
explicit XPM(const char *const *linesForm);
|
||||
|
@ -1 +1 @@
|
||||
372
|
||||
373
|
||||
|
@ -1424,6 +1424,10 @@ gboolean highlighting_is_string_style(gint lexer, gint style)
|
||||
style == SCE_P_TRIPLE ||
|
||||
style == SCE_P_TRIPLEDOUBLE ||
|
||||
style == SCE_P_CHARACTER ||
|
||||
style == SCE_P_FSTRING ||
|
||||
style == SCE_P_FCHARACTER ||
|
||||
style == SCE_P_FTRIPLE ||
|
||||
style == SCE_P_FTRIPLEDOUBLE ||
|
||||
style == SCE_P_STRINGEOL);
|
||||
|
||||
case SCLEX_F77:
|
||||
|
@ -1257,6 +1257,10 @@ static const HLStyle highlighting_styles_PYTHON[] =
|
||||
{ SCE_P_COMMENTBLOCK, "commentblock", FALSE },
|
||||
{ SCE_P_STRINGEOL, "stringeol", FALSE },
|
||||
{ SCE_P_WORD2, "word2", FALSE },
|
||||
{ SCE_P_FSTRING, "fstring", FALSE },
|
||||
{ SCE_P_FCHARACTER, "fcharacter", FALSE },
|
||||
{ SCE_P_FTRIPLE, "ftriple", FALSE },
|
||||
{ SCE_P_FTRIPLEDOUBLE, "ftripledouble", FALSE },
|
||||
{ SCE_P_DECORATOR, "decorator", FALSE }
|
||||
};
|
||||
static const HLKeyword highlighting_keywords_PYTHON[] =
|
||||
|
Loading…
x
Reference in New Issue
Block a user