ide: Raw (multiline) literals support in CodeEditor highlighting

git-svn-id: svn://ultimatepp.org/upp/trunk@11845 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2018-03-19 14:54:46 +00:00
parent d57058081c
commit 9d3ddc1c48
10 changed files with 132 additions and 11 deletions

View file

@ -113,6 +113,29 @@ const wchar *CSyntax::DoComment(HighlightOutput& hls, const wchar *p, const wcha
return p + n;
}
bool CSyntax::RawString(const wchar *p, int& n) {
if(highlight != HIGHLIGHT_CPP)
return false;
const wchar *s = p;
if(*s++ != 'R')
return false;
while(*s == ' ' || *s == '\t')
s++;
if(*s++ != '\"')
return false;
WString rs;
while(*s != '(') {
if(*s == '\0')
return false;
rs.Cat(*s++);
}
raw_string = ")";
raw_string.Cat(rs);
raw_string.Cat('\"');
n = s + 1 - p;
return true;
};
void CSyntax::Highlight(const wchar *ltext, const wchar *e, HighlightOutput& hls, CodeEditor *editor, int line, int64 pos)
{
ONCELOCK {
@ -200,6 +223,7 @@ void CSyntax::Highlight(const wchar *ltext, const wchar *e, HighlightOutput& hls
Color lbcolor = Null;
bool is_comment = false;
while(p < e) {
int raw_n = 0;
int pair = MAKELONG(p[0], p[1]);
if(pair == MAKELONG('/', '*') && highlight != HIGHLIGHT_JSON || comment) {
if(!comment) {
@ -222,6 +246,28 @@ void CSyntax::Highlight(const wchar *ltext, const wchar *e, HighlightOutput& hls
comment_ended:;
}
else
if(raw_string.GetCount() || RawString(p, raw_n)) {
const wchar *b = p;
p += raw_n;
while(p < e) {
const wchar *s = p;
const wchar *r = raw_string;
while(*s && *r) {
if(*s != *r)
break;
s++;
r++;
}
if(*r == '\0') {
p = s;
raw_string.Clear();
break;
}
p++;
}
hls.Put(int(p - b), hl_style[INK_RAW_STRING]);
}
else
if(linecomment && linecont || pair == MAKELONG('/', '/') &&
highlight != HIGHLIGHT_CSS && highlight != HIGHLIGHT_JSON ||
highlight == HIGHLIGHT_PHP && *p == '#') {

View file

@ -39,6 +39,7 @@ void CSyntax::Clear() {
macro = MACRO_OFF;
stmtline = endstmtline = seline = -1;
was_namespace = false;
raw_string = false;
ifstack.Clear();
}
@ -204,9 +205,28 @@ void CSyntax::ScanSyntax(const wchar *ln, const wchar *e, int line, int tab_size
p++;
}
}
else
if(raw_string.GetCount()) {
const wchar *s = p;
const wchar *r = raw_string;
while(*s && *r) {
if(*s != *r)
break;
s++;
r++;
}
if(*r == '\0') {
p = s;
raw_string.Clear();
}
else
p++;
if(p >= e) return;
}
else {
int pc = 0;
for(;;) {
int raw_n;
if(p >= e) return;
const wchar *pp;
if(!iscidl(pc) && (pp = isstmt(p)) != NULL) {
@ -216,6 +236,9 @@ void CSyntax::ScanSyntax(const wchar *ln, const wchar *e, int line, int tab_size
p = pp;
}
else
if(RawString(p, raw_n))
p += raw_n;
else
if(!iscidl(pc) && p[0] == 'n' && p[1] == 'a' && p[2] == 'm' && p[3] == 'e' &&
p[4] == 's' && p[5] == 'p' && p[6] == 'a' && p[7] == 'c' && p[8] == 'e' &&
!iscidl(p[9])) {
@ -330,6 +353,7 @@ void CSyntax::Serialize(Stream& s)
s % linecont;
s % was_namespace;
s % macro;
s % raw_string;
s % cl % bl % pl;

View file

@ -18,6 +18,7 @@ protected:
bool string; // we are in string (becase it can be continued by '\')
bool linecont; // line ended with '\'
bool was_namespace; // true if there was 'namespace', until '{' or ';' (not in ( [ brackets)
WString raw_string; // we are in C++11 raw string literal, this is end delimiter, e.g. )"
char macro; // can be one of:
enum {
MACRO_OFF = 0, // last line was not #define
@ -65,6 +66,8 @@ protected:
bool CheckBracket(CodeEditor& e, int li, int64 pos, int64 ppos, int64 pos0, WString ln, int d, int limit, int64& bpos0, int64& bpos);
bool CheckLeftBracket(CodeEditor& e, int64 pos, int64& bpos0, int64& bpos);
bool CheckRightBracket(CodeEditor& e, int64 pos, int64& bpos0, int64& bpos);
bool RawString(const wchar *p, int& n);
public:
static int LoadSyntax(const char *keywords[], const char *names[]);

View file

@ -84,24 +84,31 @@ inline bool IsComment(int a, int b) {
return a == '/' && b == '*' || a == '*' && b == '/' || a == '/' && b == '/';
}
void CodeEditor::PreInsert(int pos, const WString& text)
{
}
inline bool RBR(int c) {
return isbrkt(c);
}
String CodeEditor::GetRefreshInfo(int pos)
{
int ii = GetLine(pos) + 1;
return ii < GetLineCount() ? GetSyntax(ii)->Get() : String();
}
void CodeEditor::CheckSyntaxRefresh(int64 pos, const WString& text)
{
GetSyntax(GetLine(pos))->CheckSyntaxRefresh(*this, pos, text);
}
void CodeEditor::PreInsert(int pos, const WString& text)
{
refresh_info = GetRefreshInfo(pos);
}
void CodeEditor::PostInsert(int pos, const WString& text) {
if(check_edited)
bar.SetEdited(GetLine(pos));
if(!IsFullRefresh()) {
if(text.GetCount() > 200 || text.Find('\n') >= 0)
if(text.GetCount() > 200 || GetRefreshInfo(pos) != refresh_info || text.Find('\n') >= 0)
Refresh();
else
CheckSyntaxRefresh(pos, text);
@ -118,8 +125,10 @@ void CodeEditor::PreRemove(int pos, int size) {
WString text = GetW(pos, size);
if(text.Find('\n') >= 0)
Refresh();
else
else {
CheckSyntaxRefresh(pos, text);
refresh_info = GetRefreshInfo(pos);
}
}
}
@ -128,6 +137,8 @@ void CodeEditor::PostRemove(int pos, int size) {
bar.SetEdited(GetLine(pos));
WhenUpdate();
EditorBarLayout();
if(GetRefreshInfo(pos) != refresh_info)
Refresh();
}
void CodeEditor::ClearLines() {

View file

@ -296,6 +296,8 @@ protected:
bool search_canceled;
int search_time0;
One<Progress> search_progress;
String refresh_info; // serialized next line syntax context to detect the need of full Refresh
struct HlSt;
@ -347,6 +349,8 @@ protected:
bool SearchCanceled();
void EndSearchProgress();
String GetRefreshInfo(int pos);
public:
struct MouseTip {
int pos;

View file

@ -117,6 +117,8 @@ void HighlightSetup::DarkTheme()
SetHlStyle(INK_COMMENT_WORD, Blue, true, true);
SetHlStyle(PAPER_COMMENT_WORD, Yellow);
SetHlStyle(INK_CONST_STRING, Color(255, 255, 150));
SetHlStyle(INK_RAW_STRING,Color(134, 25, 70));
SetHlStyle(INK_CONST_STRINGOP, LtBlue);
SetHlStyle(INK_OPERATOR, White, true);
SetHlStyle(INK_KEYWORD, Color(255, 42, 150), true, true);
SetHlStyle(INK_UPP, Cyan, true);
@ -130,7 +132,6 @@ void HighlightSetup::DarkTheme()
SetHlStyle(INK_CONST_FLOAT, Magenta);
SetHlStyle(INK_CONST_HEX, Blue);
SetHlStyle(INK_CONST_OCT, Blue);
SetHlStyle(INK_CONST_STRINGOP, LtBlue);
SetHlStyle(PAPER_BRACKET0, Color(226, 42, 0), true);
SetHlStyle(PAPER_BRACKET, Color(226, 42, 0), true);
SetHlStyle(PAPER_BLOCK1, Color(38, 38, 38));

View file

@ -10,7 +10,9 @@ HL_COLOR(PAPER_READONLY, t_("Read only background"), 0)
HL_COLOR(INK_COMMENT, t_("Comment text"), 1)
HL_COLOR(INK_COMMENT_WORD, t_("FIXME/TODO text in comment"), 0)
HL_COLOR(PAPER_COMMENT_WORD, t_("FIXME/TODO paper in comment"), 0)
HL_COLOR(INK_CONST_STRING, t_("String constant text"), 1)
HL_COLOR(INK_CONST_STRING, t_("String literal"), 1)
HL_COLOR(INK_CONST_STRINGOP, t_("Format field"), 1)
HL_COLOR(INK_RAW_STRING, t_("Raw string literal"), 1)
HL_COLOR(INK_OPERATOR, t_("Operator text"), 1)
HL_COLOR(INK_KEYWORD, t_("Keyword text"), 1)
HL_COLOR(INK_UPP, t_("U++ identifier text"), 1)
@ -26,7 +28,6 @@ HL_COLOR(INK_CONST_FLOAT, t_("FP constant"), 1)
//HL_COLOR(INK_CONST_FLOAT_3, t_("FP constant thousands"), 1)
HL_COLOR(INK_CONST_HEX, t_("Hexadecimal constant"), 1)
HL_COLOR(INK_CONST_OCT, t_("Octal constant"), 1)
HL_COLOR(INK_CONST_STRINGOP, t_("Format field"), 1)
HL_COLOR(PAPER_BRACKET0, t_("Cursor bracket"), 0)
HL_COLOR(PAPER_BRACKET, t_("Matching bracket"), 0)

View file

@ -23,6 +23,34 @@ void initializeGL()
{
glewInit();
gl_image.Create(R"(
attribute vec4 a_position;
attribute vec2 a_texCoord;
uniform mat4 u_projection;
varying vec2 v_texCoord;
void main()
{
gl_Position = u_projection * a_position;
v_texCoord = a_texCoord;
}
)", R"(
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
varying vec2 v_texCoord;
uniform sampler2D s_texture;
void main()
{
gl_FragColor = texture2D(s_texture, v_texCoord);
}
)",
ATTRIB_VERTEX, "a_position",
ATTRIB_TEXPOS, "a_texCoord"
);
/*
gl_image.Create(
"attribute vec4 a_position; \n"
"attribute vec2 a_texCoord; \n"
@ -47,7 +75,7 @@ void initializeGL()
ATTRIB_VERTEX, "a_position",
ATTRIB_TEXPOS, "a_texCoord"
);
*/
glUniform1i(gl_image.GetUniform("s_texture"), 0);
gl_image_colored.Create(

View file

@ -39,6 +39,9 @@ void GLProgram::Create(const char *vertex_shader_, const char *fragment_shader_,
program = glCreateProgram();
DDUMP(vertex_shader_);
DDUMP(fragment_shader_);
vertex_shader = LoadShader(vertex_shader_, GL_VERTEX_SHADER);
fragment_shader = LoadShader(fragment_shader_, GL_FRAGMENT_SHADER);

View file

@ -146,7 +146,7 @@ void AppMain___()
#endif
#ifdef _DEBUG
// Ctrl::ShowRepaint(20); _DBG_
// Ctrl::ShowRepaint(20);
#endif
// _DBG_ InstantSetup(); return;