mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
ide: HTML/XML highlightitinh finalized
git-svn-id: svn://ultimatepp.org/upp/trunk@7390 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
1674d6812d
commit
b813e3ce92
10 changed files with 157 additions and 56 deletions
|
|
@ -182,4 +182,15 @@ Vector<IfState> CSyntax::PickIfStack()
|
|||
return pick(ifstack);
|
||||
}
|
||||
|
||||
void CSyntax::CheckSyntaxRefresh(CodeEditor& e, int pos, const WString& text)
|
||||
{
|
||||
for(const wchar *s = text; *s; s++) {
|
||||
if(*s == '{' || *s == '(' || *s == '[' || *s == '/' || *s == '*' ||
|
||||
*s == '}' || *s == ')' || *s == ']' || *s == '\\') {
|
||||
e.Refresh();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ void RegisterCSyntax(const char *id, int kind,
|
|||
EditorSyntax::Register(id, callback1(CreateCSyntax, kind), exts, description);
|
||||
}
|
||||
|
||||
void CreateTagSyntax(One<EditorSyntax>& e)
|
||||
void CreateTagSyntax(One<EditorSyntax>& e, bool html)
|
||||
{
|
||||
e.Create<XmlSyntax>();
|
||||
e.Create<TagSyntax>().Html(html);
|
||||
}
|
||||
|
||||
INITBLOCK {
|
||||
|
|
@ -34,8 +34,8 @@ INITBLOCK {
|
|||
RegisterCSyntax("usc", CSyntax::HIGHLIGHT_USC, "*.usc", "U++ widget definitions (.usc)");
|
||||
RegisterCSyntax("calc", CSyntax::HIGHLIGHT_CALC, "", "");
|
||||
|
||||
EditorSyntax::Register("xml", callback(CreateTagSyntax), "*.xml", "XML (.xml)");
|
||||
EditorSyntax::Register("html", callback(CreateTagSyntax), "*.html *.htm", "HTML (.html)");
|
||||
EditorSyntax::Register("xml", callback1(CreateTagSyntax, false), "*.xml", "XML (.xml)");
|
||||
EditorSyntax::Register("html", callback1(CreateTagSyntax, true), "*.html *.htm", "HTML (.html)");
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ public:
|
|||
virtual bool CanAssist() const;
|
||||
virtual void Highlight(const wchar *s, const wchar *end, HighlightOutput& hls,
|
||||
CodeEditor *editor, int line, int pos);
|
||||
virtual void CheckSyntaxRefresh(CodeEditor& e, int pos, const WString& text);
|
||||
virtual Vector<IfState> PickIfStack(); // TODO: Refactor?
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -75,32 +75,32 @@ inline bool RBR(int c) {
|
|||
return isbrkt(c);
|
||||
}
|
||||
|
||||
void CodeEditor::CheckBraces(const WString& text)
|
||||
void CodeEditor::CheckSyntaxRefresh(int pos, const WString& text)
|
||||
{
|
||||
for(const wchar *s = text; *s; s++)
|
||||
if(*s == '{' || *s == '(' || *s == '[' || *s == '/' || *s == '*' ||
|
||||
*s == '}' || *s == ')' || *s == ']' || *s == '\\') {
|
||||
Refresh();
|
||||
break;
|
||||
}
|
||||
GetSyntax(GetLine(pos))->CheckSyntaxRefresh(*this, pos, text);
|
||||
}
|
||||
|
||||
void CodeEditor::PostInsert(int pos, const WString& text) {
|
||||
if(check_edited)
|
||||
bar.SetEdited(GetLine(pos));
|
||||
if(IsFullRefresh()) return;
|
||||
if(text.GetCount() > 200)
|
||||
if(text.GetCount() > 200 || text.Find('\n') >= 0)
|
||||
Refresh();
|
||||
else
|
||||
CheckBraces(text);
|
||||
CheckSyntaxRefresh(pos, text);
|
||||
}
|
||||
|
||||
void CodeEditor::PreRemove(int pos, int size) {
|
||||
if(IsFullRefresh()) return;
|
||||
if(size > 200)
|
||||
Refresh();
|
||||
else
|
||||
CheckBraces(GetW(pos, size));
|
||||
else {
|
||||
WString text = GetW(pos, size);
|
||||
if(text.Find('\n') >= 0)
|
||||
Refresh();
|
||||
else
|
||||
CheckSyntaxRefresh(pos, text);
|
||||
}
|
||||
}
|
||||
|
||||
void CodeEditor::PostRemove(int pos, int size) {
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ struct FindReplaceDlg : WithIDEFindReplaceLayout<TopWindow> {
|
|||
|
||||
#include "Syntax.h"
|
||||
#include "CSyntax.h"
|
||||
#include "XmlSyntax.h"
|
||||
#include "TagSyntax.h"
|
||||
|
||||
class CodeEditor : public LineEdit,
|
||||
public HighlightSetup //TODO:SYNTAX
|
||||
|
|
@ -280,7 +280,7 @@ protected:
|
|||
void FindWildcard();
|
||||
void ReplaceWildcard();
|
||||
void InsertWildcard(int c);
|
||||
void CheckBraces(const WString& text);
|
||||
void CheckSyntaxRefresh(int pos, const WString& text);
|
||||
|
||||
void SetFound(int fi, int type, const WString& text);
|
||||
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ file
|
|||
CHighlight.cpp,
|
||||
CLogic.cpp,
|
||||
CRegister.icpp,
|
||||
Xml readonly separator,
|
||||
XmlSyntax.h,
|
||||
XmlSyntax.cpp,
|
||||
TagSyntax readonly separator,
|
||||
TagSyntax.h,
|
||||
TagSyntax.cpp,
|
||||
Editor readonly separator,
|
||||
EditorBar.cpp,
|
||||
FindReplace.cpp,
|
||||
|
|
|
|||
|
|
@ -50,6 +50,10 @@ Color EditorSyntax::IfColor(char c)
|
|||
}
|
||||
}
|
||||
|
||||
void EditorSyntax::CheckSyntaxRefresh(CodeEditor& e, int pos, const WString& text)
|
||||
{
|
||||
}
|
||||
|
||||
EditorSyntax::~EditorSyntax() {}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ public:
|
|||
virtual void Serialize(Stream& s);
|
||||
virtual void IndentInsert(CodeEditor& editor, int chr, int count);
|
||||
virtual bool CheckBrackets(CodeEditor& e, int& bpos0, int& bpos); // TODO: Replace with generic mechanism
|
||||
virtual void CheckSyntaxRefresh(CodeEditor& e, int pos, const WString& text);
|
||||
virtual bool CanAssist() const;
|
||||
virtual void Highlight(const wchar *s, const wchar *end, HighlightOutput& hls,
|
||||
CodeEditor *editor, int line, int pos);
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void XmlSyntax::Clear()
|
||||
void TagSyntax::Clear()
|
||||
{
|
||||
hl_ink = INK_NORMAL;
|
||||
hl_paper = PAPER_NORMAL;
|
||||
}
|
||||
|
||||
void XmlSyntax::Put0(int ink, int n, int paper)
|
||||
void TagSyntax::Put0(int ink, int n, int paper)
|
||||
{
|
||||
if(hout)
|
||||
hout->Put(n, hl_style[ink], hl_style[paper]);
|
||||
|
|
@ -19,7 +19,7 @@ inline static bool IsXmlNameChar(int c)
|
|||
return IsAlNum(c) || c == '.' || c == '-' || c == '_' || c == ':';
|
||||
}
|
||||
|
||||
const wchar *XmlSyntax::Spaces(const wchar *s, const wchar *e)
|
||||
const wchar *TagSyntax::Spaces(const wchar *s, const wchar *e)
|
||||
{
|
||||
while(s < e && IsSpace(*s)) {
|
||||
s++;
|
||||
|
|
@ -28,7 +28,7 @@ const wchar *XmlSyntax::Spaces(const wchar *s, const wchar *e)
|
|||
return s;
|
||||
}
|
||||
|
||||
void XmlSyntax::DoScript(const wchar *s, const wchar *e)
|
||||
void TagSyntax::DoScript(const wchar *s, const wchar *e)
|
||||
{
|
||||
if(hout)
|
||||
script.Highlight(s, e, *hout, NULL, 0, 0);
|
||||
|
|
@ -36,25 +36,75 @@ void XmlSyntax::DoScript(const wchar *s, const wchar *e)
|
|||
script.ScanSyntax(s, e, 0, 0);
|
||||
}
|
||||
|
||||
void XmlSyntax::Do(const wchar *s, const wchar *e)
|
||||
inline
|
||||
static const wchar *sSkipSpaces(const wchar *s, const wchar *e)
|
||||
{
|
||||
while(s < e && IsSpace(*s))
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
|
||||
inline bool cmp_wi(const wchar *s, const wchar *t, int len)
|
||||
{
|
||||
while(len--) {
|
||||
if(ToUpper(*s++) != ToUpper(*t++))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline
|
||||
bool IsEndTag(const wchar *s, const wchar *e, const wchar *tag, int len)
|
||||
{
|
||||
if(*s != '<' || s >= e)
|
||||
return false;
|
||||
s = sSkipSpaces(s + 1, e);
|
||||
if(*s != '/' || s >= e)
|
||||
return false;
|
||||
s = sSkipSpaces(s + 1, e);
|
||||
return s < e && e - s >= len && cmp_wi(s, tag, len);
|
||||
}
|
||||
|
||||
const wchar *IsScriptEnd(const wchar *s, const wchar *e, bool script)
|
||||
{
|
||||
while(s < e) {
|
||||
int c = *s;
|
||||
if(c == '\"' || c == '\'') {
|
||||
s++;
|
||||
while(s < e && *s != c) {
|
||||
if(*s == '\\' && s + 1 < e)
|
||||
s += 2;
|
||||
else
|
||||
s++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
static WString s_script("script");
|
||||
static WString s_style("style");
|
||||
const WString& tag = script ? s_script : s_style;
|
||||
if(IsEndTag(s, e, ~tag, tag.GetLength()))
|
||||
return s;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void TagSyntax::Do(const wchar *s, const wchar *e)
|
||||
{
|
||||
doscript:
|
||||
if(status == SCRIPT) { // TODO: Improve ending detection...
|
||||
static WString h1 = "</script>";
|
||||
static WString h2 = "</style>";
|
||||
int q = find(s, e - s, ~h1, h1.GetLength(), 0);
|
||||
if(q < 0)
|
||||
q = find(s, e - s, ~h2, h2.GetLength(), 0);
|
||||
if(q < 0) {
|
||||
DoScript(s, e);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
DoScript(s, s + q);
|
||||
s += q;
|
||||
const wchar *q = IsScriptEnd(s, e, script_type == JS);
|
||||
if(q) {
|
||||
DoScript(s, q);
|
||||
s = q;
|
||||
status = TEXT;
|
||||
Set(INK_NORMAL);
|
||||
}
|
||||
else {
|
||||
DoScript(s, e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
while(s < e) {
|
||||
s = Spaces(s, e);
|
||||
|
|
@ -113,15 +163,20 @@ doscript:
|
|||
Put();
|
||||
Set(INK_NORMAL);
|
||||
status = TEXT;
|
||||
if(tagname == "script") {
|
||||
script.SetHighlight(CSyntax::HIGHLIGHT_JAVASCRIPT);
|
||||
status = SCRIPT;
|
||||
goto doscript;
|
||||
}
|
||||
if(tagname == "style") {
|
||||
script.SetHighlight(CSyntax::HIGHLIGHT_CSS);
|
||||
status = SCRIPT;
|
||||
goto doscript;
|
||||
if(html) {
|
||||
if(tagname == "script") {
|
||||
script.SetHighlight(CSyntax::HIGHLIGHT_JAVASCRIPT);
|
||||
status = SCRIPT;
|
||||
script_type = JS;
|
||||
goto doscript;
|
||||
}
|
||||
else
|
||||
if(tagname == "style") {
|
||||
script.SetHighlight(CSyntax::HIGHLIGHT_CSS);
|
||||
status = SCRIPT;
|
||||
script_type = CSS;
|
||||
goto doscript;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -131,7 +186,9 @@ doscript:
|
|||
tagname.Cat(*s++);
|
||||
Put();
|
||||
}
|
||||
if(*tagname != '/')
|
||||
if(*tagname == '/')
|
||||
status = ENDTAG;
|
||||
else
|
||||
status = TAG;
|
||||
}
|
||||
else
|
||||
|
|
@ -179,25 +236,46 @@ doscript:
|
|||
}
|
||||
}
|
||||
|
||||
void XmlSyntax::ScanSyntax(const wchar *s, const wchar *e, int, int)
|
||||
void TagSyntax::CheckSyntaxRefresh(CodeEditor& e, int pos, const WString& text)
|
||||
{
|
||||
script.CheckSyntaxRefresh(e, pos, text);
|
||||
for(const wchar *s = text; *s; s++)
|
||||
if(*s == '<' || *s == '>' || *s == '/') {
|
||||
e.Refresh();
|
||||
return;
|
||||
}
|
||||
int l = max(pos - 6, 0);
|
||||
int h = min(pos + text.GetLength() + 6, e.GetLength());
|
||||
if(h - l > 200) {
|
||||
e.Refresh();
|
||||
return;
|
||||
}
|
||||
WString w = ToLower(e.GetW(l, h - l));
|
||||
if(w.Find("style") >= 0 || w.Find("script") >= 0)
|
||||
e.Refresh();
|
||||
}
|
||||
|
||||
void TagSyntax::ScanSyntax(const wchar *s, const wchar *e, int, int)
|
||||
{
|
||||
Do(s, e);
|
||||
}
|
||||
|
||||
void XmlSyntax::Highlight(const wchar *s, const wchar *end, HighlightOutput& hls, CodeEditor *editor, int line, int pos)
|
||||
void TagSyntax::Highlight(const wchar *s, const wchar *end, HighlightOutput& hls, CodeEditor *editor, int line, int pos)
|
||||
{
|
||||
hout = &hls;
|
||||
Do(s, end);
|
||||
hout = NULL;
|
||||
}
|
||||
|
||||
void XmlSyntax::Serialize(Stream& s)
|
||||
void TagSyntax::Serialize(Stream& s)
|
||||
{
|
||||
s % hl_ink
|
||||
% hl_paper
|
||||
% status
|
||||
% tagname
|
||||
% script;
|
||||
% script
|
||||
% script_type
|
||||
% html;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
@ -1,21 +1,25 @@
|
|||
class XmlSyntax : public EditorSyntax { // Tag based languages (XML, HTML)
|
||||
class TagSyntax : public EditorSyntax { // Tag based languages (XML, HTML)
|
||||
public:
|
||||
virtual void Clear();
|
||||
virtual void ScanSyntax(const wchar *ln, const wchar *e, int line, int tab_size);
|
||||
virtual void Serialize(Stream& s);
|
||||
virtual void Highlight(const wchar *s, const wchar *end, HighlightOutput& hls,
|
||||
CodeEditor *editor, int line, int pos);
|
||||
virtual void CheckSyntaxRefresh(CodeEditor& e, int pos, const WString& text);
|
||||
|
||||
private:
|
||||
|
||||
enum { TEXT, TAG0, TAG, ATTR, COMMENT, DECL, PI, SCRIPT };
|
||||
enum { TEXT, TAG0, TAG, ENDTAG, ATTR, COMMENT, DECL, PI, SCRIPT };
|
||||
|
||||
bool html;
|
||||
int status;
|
||||
int hl_ink;
|
||||
int hl_paper;
|
||||
String tagname;
|
||||
|
||||
CSyntax script;
|
||||
|
||||
CSyntax script; // for <style> or <script>
|
||||
enum { CSS, JS };
|
||||
int script_type;
|
||||
|
||||
HighlightOutput *hout;
|
||||
|
||||
|
|
@ -29,5 +33,7 @@ private:
|
|||
void SetPut(int ink, int n = 1, int paper = PAPER_NORMAL) { Set(ink, paper); Put(n); }
|
||||
|
||||
public:
|
||||
XmlSyntax() { Clear(); hout = NULL; }
|
||||
void Html(bool b) { html = b; }
|
||||
|
||||
TagSyntax() { Clear(); hout = NULL; html = true; }
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue