mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
196 lines
4.9 KiB
C++
196 lines
4.9 KiB
C++
#include "CodeEditor.h"
|
|
|
|
NAMESPACE_UPP
|
|
|
|
void CSyntax::IndentInsert(CodeEditor& e, int chr, int count)
|
|
{
|
|
if(chr == '\n') {
|
|
while(count--) {
|
|
int pp = e.GetCursor();
|
|
int cl = e.GetLinePos(pp);
|
|
WString pl = e.GetWLine(cl);
|
|
e.InsertChar('\n', 1);
|
|
int p = e.GetCursor();
|
|
int l = e.GetLinePos(p);
|
|
One<EditorSyntax> esyntax;
|
|
CSyntax *syntax = NULL;
|
|
if(e.GetLineLength(l) == p) { // At the last char of line
|
|
esyntax = e.GetSyntax(e.GetCursorLine());
|
|
syntax = dynamic_cast<CSyntax *>(~esyntax);
|
|
}
|
|
if(syntax && syntax->par.GetCount() && syntax->par.Top().line == cl && no_parenthesis_indent) {
|
|
for(int i = 0; i < syntax->par.Top().pos && i < pl.GetLength(); i++) // Indent e.g. next line of if(
|
|
e.InsertChar(pl[i] == '\t' ? '\t' : ' ', 1);
|
|
return;
|
|
}
|
|
if(syntax && syntax->endstmtline == cl && syntax->seline >= 0 && syntax->seline < e.GetLineCount())
|
|
pl = e.GetWLine(syntax->seline);
|
|
else {
|
|
int i;
|
|
for(i = 0; i < pl.GetLength(); i++) {
|
|
if(pl[i] != ' ' && pl[i] != '\t')
|
|
break;
|
|
}
|
|
if(pp < i)
|
|
return;
|
|
}
|
|
const wchar *s = pl;
|
|
while(*s == '\t' || *s == ' ')
|
|
e.InsertChar(*s++, 1);
|
|
if(!syntax)
|
|
return;
|
|
if(syntax->stmtline == cl || syntax->blk.GetCount() && syntax->blk.Top() == cl) {
|
|
if(indent_spaces || (s > pl && s[-1] == ' '))
|
|
e.InsertChar(' ', indent_amount);
|
|
else
|
|
e.InsertChar('\t', 1);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
// {, } inserted on line alone should be moved left sometimes:
|
|
int cl = e.GetCursorLine();
|
|
WString l = e.GetWLine(cl);
|
|
if(chr != '{' && chr != '}' || count > 1) {
|
|
e.InsertChar(chr, 1, true);
|
|
return;
|
|
}
|
|
const wchar *s;
|
|
for(s = l; s < l.End(); s++)
|
|
if(*s != ' ' && *s != '\t') {
|
|
e.InsertChar(chr, 1);
|
|
return;
|
|
}
|
|
int len = l.GetLength();
|
|
WString tl;
|
|
int pos = e.GetPos(cl);
|
|
if(chr == '{' && cl > 0 && stmtline == cl - 1)
|
|
tl = e.GetWLine(cl - 1);
|
|
else
|
|
if(chr == '}' && blk.GetCount())
|
|
tl = e.GetWLine(blk.Top());
|
|
else {
|
|
e.InsertChar(chr, 1);
|
|
return;
|
|
}
|
|
e.SetCursor(pos);
|
|
e.Remove(pos, len);
|
|
s = tl;
|
|
while(*s == '\t' || *s == ' ')
|
|
e.InsertChar(*s++, 1);
|
|
e.InsertChar(chr, 1);
|
|
}
|
|
|
|
bool NotEscape(int pos, const WString& s)
|
|
{
|
|
return pos == 0 || s[pos - 1] != '\\' ? true : !NotEscape(pos - 1, s);
|
|
}
|
|
|
|
bool CSyntax::CheckBracket(CodeEditor& e, int li, int pos, int ppos, int pos0, WString ln, int d, int limit,
|
|
int& bpos0, int& bpos)
|
|
{
|
|
int li0 = li;
|
|
int lvl = 1;
|
|
pos += d;
|
|
ppos += d;
|
|
for(;;) {
|
|
int c;
|
|
for(;;) {
|
|
while(pos < 0 || pos >= ln.GetLength()) {
|
|
li += d;
|
|
if(d * li >= d * limit)
|
|
return false;
|
|
ln = e.GetWLine(li);
|
|
int q = ln.Find("//");
|
|
if(q >= 0)
|
|
ln = ln.Mid(0, q) + WString(' ', ln.GetCount() - q);
|
|
pos = d < 0 ? ln.GetLength() - 1 : 0;
|
|
ppos += d;
|
|
}
|
|
c = ln[pos];
|
|
if((c == '\"' || c == '\'') && (pos > 0 && NotEscape(pos, ln) && ln[pos - 1] != '\'')) {
|
|
pos += d;
|
|
ppos += d;
|
|
int lc = c;
|
|
while(pos < ln.GetLength() && pos > 0) {
|
|
if(ln[pos] == lc && NotEscape(pos, ln)) {
|
|
pos += d;
|
|
ppos += d;
|
|
break;
|
|
}
|
|
pos += d;
|
|
ppos += d;
|
|
}
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
if(islbrkt(c))
|
|
lvl += d;
|
|
if(isrbrkt(c))
|
|
lvl -= d;
|
|
if(lvl <= 0) {
|
|
bpos0 = pos0;
|
|
bpos = ppos;
|
|
return true;
|
|
}
|
|
pos += d;
|
|
ppos += d;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CSyntax::CheckLeftBracket(CodeEditor& e, int pos, int& bpos0, int& bpos)
|
|
{
|
|
if(pos < 0 || pos >= e.GetLength())
|
|
return false;
|
|
int ppos = pos;
|
|
int li = e.GetLinePos(pos);
|
|
WString ln = e.GetWLine(li);
|
|
return islbrkt(ln[pos]) &&
|
|
CheckBracket(e, li, pos, ppos, ppos, ln, 1, min(li + 3000, e.GetLineCount()), bpos0, bpos);
|
|
}
|
|
|
|
bool CSyntax::CheckRightBracket(CodeEditor& e, int pos, int& bpos0, int& bpos)
|
|
{
|
|
if(pos < 0 || pos >= e.GetLength())
|
|
return false;
|
|
int ppos = pos;
|
|
int li = e.GetLinePos(pos);
|
|
WString ln = e.GetWLine(li);
|
|
int c = ln[pos];
|
|
return isrbrkt(ln[pos]) &&
|
|
CheckBracket(e, li, pos, ppos, ppos, ln, -1, max(li - 3000, 0), bpos0, bpos);
|
|
}
|
|
|
|
bool CSyntax::CheckBrackets(CodeEditor& e, int& bpos0, int& bpos)
|
|
{
|
|
int c = e.GetCursor();
|
|
return CheckLeftBracket(e, c, bpos0, bpos) ||
|
|
CheckRightBracket(e, c, bpos0, bpos) ||
|
|
CheckLeftBracket(e, c - 1, bpos0, bpos) ||
|
|
CheckRightBracket(e, c - 1, bpos0, bpos);
|
|
}
|
|
|
|
bool CSyntax::CanAssist() const
|
|
{
|
|
return !comment && !string && !linecomment;
|
|
}
|
|
|
|
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
|