pascalabcnet/VisualPascalABCNET/AutoInsertCode/AutoInsertCode.cs
Mikhalkovich Stanislav 549af34263 AutoInsertCode.cs
2019-07-08 21:58:12 +03:00

168 lines
7.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.TextEditor.Document;
using ICSharpCode.TextEditor;
namespace VisualPascalABC
{
public partial class Form1
{
string Spaces(int n) => new string(' ', n);
string GetLine(int lineNum)
{
var ta = CurrentCodeFileDocument.TextEditor.ActiveTextAreaControl.TextArea;
var doc = ta.Document;
if (lineNum < doc.TotalNumberOfLines)
return TextUtilities.GetLineAsString(doc, lineNum);
else return null;
}
void GetCurNextLines(out string Current, out string Next, out string Prev) // Next - следующая непустая строка
{
var ta = CurrentCodeFileDocument.TextEditor.ActiveTextAreaControl.TextArea;
var doc = ta.Document;
var tl_beg = new TextLocation(ta.Caret.Column, ta.Caret.Line);
var cls = doc.GetLineSegment(ta.Caret.Line);
LineSegment nls = null;
if (ta.Caret.Line + 1 < doc.TotalNumberOfLines)
nls = doc.GetLineSegment(ta.Caret.Line + 1);
Current = GetLine(ta.Caret.Line);
var i = ta.Caret.Line + 1;
do
{
Next = GetLine(i);
i++;
} while (Next != null && Next.Trim() == "");
Prev = null;
if (ta.Caret.Line > 0)
Prev = GetLine(ta.Caret.Line - 1);
}
int Indent(string s)
{
return Array.FindIndex(s.ToCharArray(), c => c != ' ');
}
private bool TextArea_KeyEventHandler(char ch)
{
if (!tsAutoInsertCode.Checked)
return false;
try
{
var editor = VisualPascalABCProgram.MainForm.CurrentCodeFileDocument.TextEditor;
var ta = editor.ActiveTextAreaControl.TextArea;
var doc = ta.Document;
/*if (ch == '(')
{
var tl_beg = new TextLocation(ta.Caret.Column, ta.Caret.Line);
int offset = doc.PositionToOffset(tl_beg);
doc.Insert(offset, ")");
return false;
}
if (ch == '[')
{
var tl_beg = new TextLocation(ta.Caret.Column, ta.Caret.Line);
int offset = doc.PositionToOffset(tl_beg);
doc.Insert(offset, "]");
return false;
}
if (ch == '{')
{
var tl_beg = new TextLocation(ta.Caret.Column, ta.Caret.Line);
int offset = doc.PositionToOffset(tl_beg);
doc.Insert(offset, "}");
return false;
}*/
if (ch != '\n')
return false;
var caret = editor.ActiveTextAreaControl.Caret;
int start = TextUtilities.FindPrevWordStart(editor.Document, caret.Offset);
var Text = editor.Document.GetText(start, caret.Offset - start).TrimEnd();
if (Text.ToLower() == "begin")
{
string cur, next, prev;
GetCurNextLines(out cur, out next, out prev);
// анализ предыдущей
var icur = Indent(cur);
if (cur.Trim().ToLower() == "begin" && (next == null || Indent(next) < icur || Indent(next) == icur && !next.TrimStart().ToLower().StartsWith("end"))) // значит, это единственное слово begin в строке
{
// Проанализируем предыдущий оператор по первому слову
var pst = prev?.TrimStart().ToLower();
if (pst != null)
if (pst.StartsWith("if") || pst.StartsWith("for") || pst.StartsWith("loop") || pst.StartsWith("with") || pst.StartsWith("on")) // потом улучшу - для нескольких выборов
{
// Надо удалить в текущей строке пробелы чтобы выровнять begin по if
var iprev = Indent(prev);
var tl_beg = new TextLocation(ta.Caret.Column, ta.Caret.Line);
int offset = doc.PositionToOffset(tl_beg);
doc.Remove(offset - 7, 2);
icur -= 2;
}
}
ta.InsertString("\n" + Spaces(icur + 2));
if (next == null || Indent(next) < icur || Indent(next) == icur && !next.TrimStart().ToLower().StartsWith("end"))
{
var tl_beg = new TextLocation(ta.Caret.Column, ta.Caret.Line);
int offset = doc.PositionToOffset(tl_beg);
var send = "\n" + Spaces(icur) + "end";
if (next == null)
send += ".";
else send += ";";
doc.Insert(offset, send);
}
return true;
}
if (Text.ToLower() == "repeat")
{
string cur, next, prev;
GetCurNextLines(out cur, out next, out prev);
var icur = Indent(cur);
ta.InsertString("\n" + Spaces(icur + 2));
if (next == null || Indent(next) < icur || Indent(next) == icur && !next.TrimStart().ToLower().StartsWith("until"))
{
var tl_beg = new TextLocation(ta.Caret.Column, ta.Caret.Line);
int offset = doc.PositionToOffset(tl_beg);
var send = "\n" + Spaces(icur) + "until ;";
doc.Insert(offset, send);
}
return true;
}
if (Text.ToLower() == "then" || Text.ToLower() == "else" || Text.ToLower() == "do")
{
string cur, next, prev;
GetCurNextLines(out cur, out next, out prev);
var icur = Indent(cur);
ta.InsertString("\n" + Spaces(icur + 2));
return true;
}
/*if (Text.ToLower() == "do")
{
var pos = doc.OffsetToPosition(start);
var ls = doc.GetLineSegment(pos.Line);
//var beglineoffset = ls.Offset;
var tttt = doc.GetText(ls);
var n = Array.FindIndex(tttt.ToCharArray(), c => c != ' ');
ta.InsertString("\n" + Spaces(n) + "begin\n" + Spaces(n + 2));
var tl_beg = new TextLocation(ta.Caret.Column, ta.Caret.Line);
int offset = doc.PositionToOffset(tl_beg);
doc.Insert(offset, "\n" + Spaces(n) + "end;");
return true;
}*/
return false;
}
catch (Exception e)
{
}
return false;
}
}
}