PythonSyntax.diff

Bettter string handling - Zbigniew Rebacz, 12/16/2015 09:11 PM

Download (9.26 KB)

View differences:

CInit.cpp (kopia robocza)
344 344

  
345 345
int CSyntax::LoadSyntax(const char *keywords[], const char *names[])	// Changed
346 346
{
347
	Index<String>& key = keyword.Add()	;
347
	Index<String>& key = keyword.Add();
348 348
	while(*keywords)
349 349
		key.Add(*keywords++);
350 350
	Index <String>& nam = name.Add();
CRegister.icpp (kopia robocza)
13 13
	EditorSyntax::Register(id, callback1(CreateCSyntax, kind), exts, description);
14 14
}
15 15

  
16
void CreateTagSyntax(One<EditorSyntax>& e, bool html, bool witz)
16
void CreateDiffSyntax(One<EditorSyntax>& e)
17 17
{
18
	e.Create<TagSyntax>().Html(html).Witz(witz);
18
	e.Create<DiffSyntax>();
19 19
}
20 20

  
21
void CreateDiffSyntax(One<EditorSyntax>& e)
21
void CreatePythonSyntax(One<EditorSyntax>& e)
22 22
{
23
	e.Create<DiffSyntax>();
23
	e.Create<PythonSyntax>();
24 24
}
25 25

  
26
void CreateTagSyntax(One<EditorSyntax>& e, bool html, bool witz)
27
{
28
	e.Create<TagSyntax>().Html(html).Witz(witz);
29
}
30

  
26 31
void CreateLogSyntax(One<EditorSyntax>& e)
27 32
{
28 33
	e.Create<LogSyntax>();
......
46 51
	RegisterCSyntax("calc", CSyntax::HIGHLIGHT_CALC, "", "");
47 52
	RegisterCSyntax("php", CSyntax::HIGHLIGHT_PHP, "*.php", "PHP");
48 53
	
54
	EditorSyntax::Register("diff", callback(CreateDiffSyntax), "*.diff *.patch", "Diff");
55
	
56
	EditorSyntax::Register("python", callback(CreatePythonSyntax), "*.py, *.pyc, *.pyd, *.pyo, *.pyw, *.pyz", "Python");
57
	
49 58
	EditorSyntax::Register("xml", callback2(CreateTagSyntax, false, false), "*.xml *.xsd", "XML (.xml)");
50 59
	EditorSyntax::Register("html", callback2(CreateTagSyntax, true, false), "*.html *.htm", "HTML (.html)");
51 60
	EditorSyntax::Register("witz", callback2(CreateTagSyntax, true, true), "*.witz", "Skylark templates (.witz)");
52 61
	
53
	EditorSyntax::Register("diff", callback(CreateDiffSyntax), "*.diff *.patch", "Diff");
54

  
55 62
	EditorSyntax::Register("log", callback(CreateLogSyntax), "*.log", "Log (*.log)");
56 63
}
57 64

  
CodeEditor.h (kopia robocza)
175 175
#include "DiffSyntax.h"
176 176
#include "TagSyntax.h"
177 177
#include "LogSyntax.h"
178
#include "PythonSyntax.h"
178 179

  
179 180
class CodeEditor : public LineEdit,
180 181
public HighlightSetup
CodeEditor.upp (kopia robocza)
28 28
	TagSyntax readonly separator,
29 29
	TagSyntax.h,
30 30
	TagSyntax.cpp,
31
	PythonSyntax readonly separator,
32
	PythonSyntax.cpp,
33
	PythonSyntax.h,
31 34
	LogSyntax readonly separator,
32 35
	LogSyntax.h,
33 36
	LogSyntax.cpp,
PythonSyntax.cpp (kopia robocza)
1
#include "CodeEditor.h"
2

  
3
NAMESPACE_UPP
4

  
5
PythonSyntax::PythonSyntax() {}
6

  
7
void PythonSyntax::Highlight(const wchar *start, const wchar *end, HighlightOutput& hls, CodeEditor *editor, int line, int pos)
8
{
9
	InitKeywords();
10
	
11
	bool isComment = false;
12
	bool isStr = false;
13
	char strOpening;
14
	
15
	const wchar* p = start;
16
	while(p < end) {
17
		if((*p == '#' || isComment) && !isStr) {
18
			isComment = true;
19
			hls.Put(hl_style[INK_COMMENT]);
20
		}
21
		else
22
		if(*p == '\'' || *p == '\"' || isStr) {
23
			hls.Put(hl_style[INK_CONST_STRING]);
24
			if((*p == '\'' || *p == '\"') && p - 1 != start && *(p - 1) != '\\')
25
				if (!isStr || strOpening == *p) {
26
					isStr = !isStr;
27
					strOpening = *p;
28
				}
29
		}
30
		else
31
		if(IsSeparator(p) || p == start) {
32
			WString w;
33
			bool isW = false;
34
			const wchar* bp = (p == start && !IsSeparator(p)) ? p : p + 1;
35
			while (bp != end && !IsSeparator(bp))
36
				w += *bp++;
37
			
38
			bool isPutted = false;
39
			if(IsSeparator(p)) {
40
				hls.Put(hl_style[INK_NORMAL]);
41
				isPutted = true;
42
			}
43
			if(IsKeyword(w)) {
44
				hls.Put(w.GetLength(), hl_style[INK_KEYWORD]);
45
				isW = true;
46
			}
47
			else
48
			if(IsSpecialVar(w)) {
49
				hls.Put(w.GetLength(), hl_style[INK_UPP]);
50
				isW = true;
51
			}
52
			else
53
			if(IsNumber(w)) {
54
				hls.Put(w.GetLength(), hl_style[INK_CONST_INT]);
55
				isW = true;
56
			}
57
			
58
			if(isW) {
59
				p += w.GetLength() - (isPutted ? 0 : 1);
60
			}
61
		}
62
		else
63
			hls.Put(hl_style[INK_NORMAL]);
64
		
65
		p++;
66
	}
67
}
68

  
69
void PythonSyntax::IndentInsert(CodeEditor& editor, int chr, int count)
70
{
71
	if(chr == '\n') {
72
		while(count--) {
73
			WString cursorLine = editor.GetWLine(editor.GetCursorLine());
74
			editor.InsertChar('\n', 1);
75
			
76
			Identation::Type idType = FindIdentationType(editor, cursorLine);
77
			char idChar = GetIdentationByType(idType);
78
			int mult = 1;
79
			if(idType == Identation::Space)
80
				mult = CalculateSpaceIndetationSize(editor);
81
			if(LineHasColon(cursorLine))
82
				editor.InsertChar(idChar, mult);
83
			editor.InsertChar(idChar, CalculateLineIndetations(cursorLine, idType));
84
		}
85
	}
86
	if(count > 0)
87
		editor.InsertChar(chr, count);
88
}
89

  
90
bool PythonSyntax::IsSeparator(const wchar* c)
91
{
92
	return    *c == ' ' || *c == ':' || *c == ',' || *c == '.' || *c == '('
93
	       || *c == ')' || *c == '[' || *c == ']' || *c == '{' || *c == '}'
94
	       || *c == '\t';
95
}
96

  
97
bool PythonSyntax::IsKeyword(const WString& w)
98
{
99
	return keywords.Find(w.ToString()) > -1;
100
}
101

  
102
bool PythonSyntax::IsSpecialVar(const WString& w)
103
{
104
	return specialVars.Find(w.ToString()) > -1;
105
}
106

  
107
bool PythonSyntax::IsNumber(const WString& w)
108
{
109
	RegExp exp("^-?[0-9]+$");
110
	return exp.Match(w.ToString());
111
}
112

  
113
void PythonSyntax::InitKeywords()
114
{
115
	static const char* pythonKeywords[] = {
116
		"and", "as", "assert", "break", "class", "continue", "def",
117
		"del", "elif", "else", "except", "finally", "for",
118
		"from", "global", "if", "import", "in", "is", "lambda",
119
		"not", "or", "pass", "raise", "return", "try",
120
		"while", "with", "yield",
121
		"None", "True", "False",
122
		NULL
123
	};
124
	static const char* pythonSpecialVars[] = {
125
		"self", "NotImplemented", "Ellipsis", "__debug__", "__file__", "__name__",
126
		NULL
127
	};
128
	
129
	LoadSyntax(pythonKeywords, pythonSpecialVars);
130
}
131

  
132
void PythonSyntax::LoadSyntax(const char* keywordsArray[], const char* specialVarsArray[])
133
{
134
	keywords.Clear();
135
	while(*keywordsArray)
136
		keywords.Add(*keywordsArray++);
137
	
138
	specialVars.Clear();
139
	while(*specialVarsArray)
140
		specialVars.Add(*specialVarsArray++);
141
}
142

  
143
bool PythonSyntax::LineHasColon(const WString& line)
144
{
145
	for(int i = line.GetLength() - 1; i >= 0; i--) {
146
		if(line[i] == ':')
147
			return true;
148
	}
149
	return false;
150
}
151

  
152
int PythonSyntax::CalculateLineIndetations(const WString& line, Identation::Type type)
153
{
154
	int count = 0;
155
	for(int i = 0; i < line.GetLength(); i++) {
156
		if(type == Identation::Tab && line[i] == '\t')
157
			count++;
158
		else
159
		if(type == Identation::Space && line[i] == ' ')
160
			count++;
161
		else
162
			break;
163
	}
164
	return count;
165
}
166

  
167
PythonSyntax::Identation::Type PythonSyntax::FindIdentationType(CodeEditor& editor, const WString& line)
168
{
169
	Identation::Type type = Identation::None;
170
	if(line.StartsWith("\t"))
171
		type = Identation::Tab;
172
	else
173
	if(line.StartsWith(" "))
174
		type = Identation::Space;
175
	else {
176
		for(int i = 0; i < editor.GetLineCount(); i++) {
177
			WString cLine = editor.GetWLine(i);
178
			if(cLine.StartsWith("\t")) {
179
				type = Identation::Tab;
180
				break;
181
			}
182
			else
183
			if(cLine.StartsWith(" ")) {
184
				type = Identation::Space;
185
				break;
186
			}
187
		}
188
	}
189
	return type;
190
}
191

  
192
int PythonSyntax::CalculateSpaceIndetationSize(CodeEditor& editor)
193
{
194
	int current = 0;
195
	for(int i = 0; i < editor.GetLineCount(); i++) {
196
		WString line = editor.GetWLine(i);
197
		for(int j = 0; j < line.GetLength(); j++) {
198
			if(line[j] == ' ')
199
				current++;
200
			else
201
				break;
202
		}
203
		
204
		if(current > 0)
205
			break;
206
	}
207
	
208
	// TODO: 4 is magic numer - try to find the way to get this number from ide constants
209
	return current > 0 ? current : 4;
210
}
211

  
212
char PythonSyntax::GetIdentationByType(Identation::Type type)
213
{
214
	if(type == Identation::Space)
215
		return ' ';
216
	return '\t';
217
}
218

  
219
END_UPP_NAMESPACE
PythonSyntax.h (kopia robocza)
1
class PythonSyntax : public EditorSyntax {
2
private:
3
	struct Identation {
4
		enum Type {
5
			Tab = 0,
6
			Space,
7
			None
8
		};
9
	};
10

  
11
public:
12
	PythonSyntax();
13

  
14
	virtual void Highlight(const wchar *start, const wchar *end, HighlightOutput& hls,
15
	                       CodeEditor *editor, int line, int pos);
16
	virtual void IndentInsert(CodeEditor& e, int chr, int count);
17
	
18
private:
19
	bool IsSeparator(const wchar* c);
20

  
21
	bool IsKeyword(const WString& w);
22
	bool IsSpecialVar(const WString& w);
23
	bool IsNumber(const WString& w);
24
	
25
	void InitKeywords();
26
	void LoadSyntax(const char* keywordsArray[], const char* specialVarsArray[]);
27
	
28
	bool             LineHasColon(const WString& line);
29
	int              CalculateLineIndetations(const WString& line, Identation::Type type);
30
	int              CalculateSpaceIndetationSize(CodeEditor& editor);
31
	Identation::Type FindIdentationType(CodeEditor& editor, const WString& line);
32
	char             GetIdentationByType(Identation::Type type);
33
	
34
private:
35
	Index<String> keywords;
36
	Index<String> specialVars;
37
};