Sfall-ScriptEditor
979 строк · 41.1 Кб
1using System;2using System.Collections.Generic;3using System.IO;4using System.Text.RegularExpressions;5using System.Windows.Forms;6using System.Linq;7
8using ICSharpCode.TextEditor;9using ICSharpCode.TextEditor.Document;10
11using ScriptEditor.CodeTranslation;12using ScriptEditor.TextEditorUI;13
14namespace ScriptEditor.TextEditorUtilities15{
16/// <summary>17/// Class for text editor functions.18/// </summary>19internal sealed class Utilities20{21private const string endKeyWord = "end";22
23internal struct Quote24{25public int Open;26public int Close;27}28
29#region Formating code functions30// for selected code31public static void FormattingCode(TextAreaControl TAC)32{33string textCode;34int offset;35if (TAC.SelectionManager.HasSomethingSelected) {36ISelection select = TAC.SelectionManager.SelectionCollection[0];37textCode = select.SelectedText;38offset = select.Offset;39} else {40textCode = TextUtilities.GetLineAsString(TAC.Document, TAC.Caret.Line);41offset = TAC.Caret.Offset - TAC.Caret.Column;42}43TAC.Document.Replace(offset, textCode.Length, FormattingCode(textCode));44}45
46public static void FormattingCodeSmart(TextAreaControl TAC)47{48string textCode = TextUtilities.GetLineAsString(TAC.Document, TAC.Caret.Line);49
50int col = TAC.Caret.Column;51int offset = TAC.Caret.Offset - col;52
53if (col < textCode.Length)54textCode = textCode.Remove(col);55
56string formatText = FormattingCode(textCode);57
58int diffLen = formatText.Length - textCode.Length;59if (diffLen > 0) {60TAC.Document.Replace(offset, textCode.Length, formatText);61TAC.Caret.Column += diffLen;62}63}64
65public static string FormattingCode(string textCode)66{67string[] pattern = { ":=", "!=", "==", ">=", "<=", "+=", "-=", "*=", "/=", "%=", ",", ">", "<", "+", "-", "*", "/", "%" };68char[] excludeR = { ' ', '=', '+', '-', '*', '/' };69char[] excludeL = { ' ', '=', '>', '<', '+', '-', '!', ':', '*', '/', '%' };70char[] excludeD = { ' ', ',', '(' };71const string space = " ";72
73List<Quote> Quotes = new List<Quote>();74
75string[] linecode = textCode.Split('\n');76for (int i = 0; i < linecode.Length; i++)77{78string tmp = linecode[i].TrimStart();79if (tmp.Length < 3 || (tmp[0] == '/' && (tmp[1] == '/' || tmp[1] == '*'))) continue;80// check Quotes81GetQuotesPosition(linecode[i], Quotes);82foreach (string p in pattern)83{84int n = 0;85do {86n = linecode[i].IndexOf(p, n);87if (n < 0)88break;89
90// skiping quotes "..."91bool inQuotes = false;92foreach (Quote q in Quotes)93{94if (n > q.Open && n < q.Close) {95n = q.Close + 1;96inQuotes = true;97break;98}99}100if (inQuotes) {101if (n >= linecode[i].Length)102break;103continue;104}105
106// insert right space107int cPos = n + p.Length;108if (linecode[i].Length > cPos && !Char.IsWhiteSpace(linecode[i], cPos)) {109if (p.Length == 2)110linecode[i] = linecode[i].Insert(n + 2, space);111else {112if (linecode[i].IndexOfAny(excludeR, n + 1, 1) == -1) {113if ((p == "-" && Char.IsDigit(linecode[i], n + 1)114&& linecode[i].IndexOfAny(excludeD, n - 1, 1) != -1) == false // check NegDigit115&& ((p == "+" || p == "-") && linecode[i][n - 1].ToString() == p) == false) // check '++/--'116linecode[i] = linecode[i].Insert(n + 1, space);117}118}119}120// insert left space121if (n > 0 && p != "," && !Char.IsWhiteSpace(linecode[i], n - 1)) {122if (p.Length == 2)123linecode[i] = linecode[i].Insert(n, space);124else {125if (linecode[i].IndexOfAny(excludeL, n - 1, 1) == -1) {126if ((p == "-" && Char.IsDigit(linecode[i], n + 1)127&& linecode[i][n - 1] == '(') == false // check NegDigit128&& ((p == "+" || p == "-") && linecode[i][n + 1].ToString() == p) == false) // check '++/--'129linecode[i] = linecode[i].Insert(n, space);130}131}132}133
134n += p.Length;135} while (n < linecode[i].Length);136}137Quotes.Clear();138}139return string.Join("\n", linecode);140}141
142public static void DecIndent(TextAreaControl TAC)143{144int indent = -1;145if (TAC.SelectionManager.HasSomethingSelected) {146ISelection position = TAC.SelectionManager.SelectionCollection[0];147
148for (int i = position.StartPosition.Line; i <= position.EndPosition.Line; i++)149{150CheckSpacesIndent(i, ref indent, TAC.Document);151}152
153if (indent <= 0)154return;155TAC.Document.UndoStack.StartUndoGroup();156
157for (int i = position.StartPosition.Line; i <= position.EndPosition.Line; i++)158{159SubDecIndent(i, indent, TAC.Document);160}161
162TAC.Document.UndoStack.EndUndoGroup();163TextLocation srtSel = TAC.SelectionManager.SelectionCollection[0].StartPosition;164TextLocation endSel = TAC.SelectionManager.SelectionCollection[0].EndPosition;165srtSel.Column -= indent;166endSel.Column -= indent;167TAC.SelectionManager.SetSelection(srtSel, endSel);168} else {169int line = TAC.Caret.Line;170CheckSpacesIndent(line, ref indent, TAC.Document);171if (indent <= 0 || SubDecIndent(line, indent, TAC.Document))172return;173}174TAC.Caret.Column -= indent;175//TAC.Refresh();176}177
178private static void CheckSpacesIndent(int line, ref int indent, IDocument document)179{180string LineText = TextUtilities.GetLineAsString(document, line);181int len = LineText.Length;182int trimlen = LineText.TrimStart().Length;183if (len == 0 || trimlen == 0)184return;185
186int spacesLen = (len - trimlen);187if (indent == -1) {188// Adjust indent189int adjust = spacesLen % Settings.tabSize;190indent = (adjust > 0) ? adjust : Settings.tabSize;191}192if (spacesLen < indent)193indent = spacesLen;194}195
196private static bool SubDecIndent(int line, int indent, IDocument document)197{198if (TextUtilities.GetLineAsString(document, line).TrimStart().Length == 0)199return true;200document.Remove(document.LineSegmentCollection[line].Offset, indent);201return false;202}203
204public static void CommentText(TextAreaControl TAC)205{206string commentLine = TAC.Document.HighlightingStrategy.Properties["LineComment"];207
208if (TAC.SelectionManager.HasSomethingSelected) {209TAC.Document.UndoStack.StartUndoGroup();210ISelection position = TAC.SelectionManager.SelectionCollection[0];211for (int i = position.StartPosition.Line; i <= position.EndPosition.Line; i++)212{213string LineText = TextUtilities.GetLineAsString(TAC.Document, i);214string TrimText = LineText.TrimStart();215if (TrimText.StartsWith(commentLine))216continue;217int offset = LineText.Length - TrimText.Length;218offset += TAC.Document.LineSegmentCollection[i].Offset;219TAC.Document.Insert(offset, commentLine);220}221TAC.Document.UndoStack.EndUndoGroup();222TAC.SelectionManager.ClearSelection();223} else {224string LineText = TextUtilities.GetLineAsString(TAC.Document, TAC.Caret.Line);225string TrimText = LineText.TrimStart();226if (TrimText.StartsWith(commentLine))227return;228int offset = LineText.Length - TrimText.Length;229offset += TAC.Document.LineSegmentCollection[TAC.Caret.Line].Offset;230TAC.Document.Insert(offset, commentLine);231}232TAC.Caret.Column += commentLine.Length;233}234
235public static void UnCommentText(TextAreaControl TAC)236{237string commentLine = TAC.Document.HighlightingStrategy.Properties["LineComment"];238int lenComment = commentLine.Length;239
240if (TAC.SelectionManager.HasSomethingSelected) {241TAC.Document.UndoStack.StartUndoGroup();242ISelection position = TAC.SelectionManager.SelectionCollection[0];243for (int i = position.StartPosition.Line; i <= position.EndPosition.Line; i++)244{245string LineText = TextUtilities.GetLineAsString(TAC.Document, i);246if (!LineText.TrimStart().StartsWith(commentLine))247continue;248int n = LineText.IndexOf(commentLine);249int offset_str = TAC.Document.LineSegmentCollection[i].Offset;250TAC.Document.Remove(offset_str + n, lenComment);251}252TAC.Document.UndoStack.EndUndoGroup();253TAC.SelectionManager.ClearSelection();254} else {255string LineText = TextUtilities.GetLineAsString(TAC.Document, TAC.Caret.Line);256if (!LineText.TrimStart().StartsWith(commentLine))257return;258int n = LineText.IndexOf(commentLine);259int offset_str = TAC.Document.LineSegmentCollection[TAC.Caret.Line].Offset;260TAC.Document.Remove(offset_str + n, lenComment);261}262TAC.Caret.Column -= lenComment;263}264
265public static void AlignToLeft(TextAreaControl TAC)266{267if (TAC.SelectionManager.HasSomethingSelected) {268ISelection position = TAC.SelectionManager.SelectionCollection[0];269string LineText = TextUtilities.GetLineAsString(TAC.Document, position.StartPosition.Line);270int Align = LineText.Length - LineText.TrimStart().Length; // узнаем длину отступа271TAC.Document.UndoStack.StartUndoGroup();272for (int i = position.StartPosition.Line + 1; i <= position.EndPosition.Line; i++)273{274LineText = TextUtilities.GetLineAsString(TAC.Document, i);275int len = LineText.Length - LineText.TrimStart().Length;276if (len == 0 || len <= Align) continue;277int offset = TAC.Document.LineSegmentCollection[i].Offset;278TAC.Document.Remove(offset, len-Align);279}280TAC.Document.UndoStack.EndUndoGroup();281}282}283#endregion284
285# region Search Function286public static bool Search(string text, string str, Regex regex, int start, bool restart, bool mcase, out int mstart, out int mlen)287{288if (start >= text.Length) start = 0;289mstart = 0;290mlen = str.Length;291if (regex != null) {292Match m = regex.Match(text, start);293if (m.Success) {294mstart = m.Index;295mlen = m.Length;296return true;297}298if (!restart) return false;299m = regex.Match(text);300if (m.Success) {301mstart = m.Index;302mlen = m.Length;303return true;304}305} else {306int i = text.IndexOf(str, start, (mcase) ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);307if (i != -1) {308mstart = i;309return true;310}311if (!restart) return false;312i = text.IndexOf(str, (mcase) ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);313if (i != -1) {314mstart = i;315return true;316}317}318return false;319}320
321public static bool Search(string text, string str, Regex regex, bool mcase)322{323return (regex == null)324? (text.IndexOf(str, (mcase) ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase) != -1)325: regex.IsMatch(text);326}327
328public static bool SearchAndScroll(TextAreaControl TAC, Regex regex, string searchText, bool mcase, ref ScriptEditor.TextEditor.PositionType type, bool searchContinue = true)329{330int start, len;331if (Search(TAC.Document.TextContent, searchText, regex, (searchContinue) ? TAC.Caret.Offset + 1 : 0, true, mcase, out start, out len)) {332FindSelected(TAC, start, len, ref type);333return true;334}335return false;336}337
338public static void FindSelected(TextAreaControl TAC, int start, int len, ref ScriptEditor.TextEditor.PositionType type, string replace = null)339{340type = ScriptEditor.TextEditor.PositionType.NoStore;341
342TextLocation locstart = TAC.Document.OffsetToPosition(start);343TextLocation locend = TAC.Document.OffsetToPosition(start + len);344TAC.SelectionManager.SetSelection(locstart, locend);345if (replace != null) {346TAC.Document.Replace(start, len, replace);347locend = TAC.Document.OffsetToPosition(start + replace.Length);348TAC.SelectionManager.SetSelection(locstart, locend);349}350TAC.Caret.Position = locstart;351TAC.CenterViewOn(locstart.Line, Math.Max(2, TAC.TextArea.TextView.VisibleLineCount / 4));352}353
354public static void SearchForAll(TabInfo tab, string searchText, Regex regex, bool mcase, DataGridView dgv, List<int> offsets, List<int> lengths)355{356int start, len, line, lastline = -1;357int offset = 0;358while (Search(tab.textEditor.Text, searchText, regex, offset, false, mcase, out start, out len))359{360offset = start + 1;361line = tab.textEditor.Document.OffsetToPosition(start).Line;362if (offsets != null) {363offsets.Add(start);364lengths.Add(len);365}366if (line != lastline) {367lastline = line;368string message = TextUtilities.GetLineAsString(tab.textEditor.Document, line).Trim();369Error error = new Error(message, tab.filepath, line + 1, tab.textEditor.Document.OffsetToPosition(start).Column + 1, len);370dgv.Rows.Add(tab.filename, error.line.ToString(), error);371}372}373}374
375public static void SearchForAll(string[] text, string file, string searchText, Regex regex, bool mcase, DataGridView dgv)376{377bool matched;378for (int i = 0; i < text.Length; i++)379{380if (regex != null)381matched = regex.IsMatch(text[i]);382else383matched = text[i].IndexOf(searchText, (mcase) ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase) != -1;384if (matched) {385Error error = new Error(text[i].Trim(), file, i + 1);386dgv.Rows.Add(Path.GetFileName(file), (i + 1).ToString(), error);387}388}389}390
391public static int SearchPanel(string text, string find, int start, bool icase, bool wholeword, bool back = false)392{393int z;394if (wholeword) {395RegexOptions option = RegexOptions.Multiline;396if (!icase)397option |= RegexOptions.IgnoreCase;398if (back)399option |= RegexOptions.RightToLeft;400z = SearchWholeWord(text, find, start, option);401} else {402StringComparison sc = (!icase) ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;403z = (back) ? text.LastIndexOf(find, start, sc)404: text.IndexOf(find, start, sc);405}406return z;407}408
409public static int SearchWholeWord(string text, string find, int start, RegexOptions option)410{411int z, x;412string search = @"\b" + Regex.Escape(find) + @"\b";413Regex s_regex = new Regex(search, option);414
415if (!Search(text, find, s_regex, start, false, false, out z, out x))416return -1;417
418return z;419}420
421internal static bool IsAnyChar(char ch, char[] chars)422{423bool result = false;424foreach (char c in chars)425{426if (c == ch)427result = true;428}429return result;430}431#endregion432
433#region Create/Delete procedure function434internal static void PrepareDeleteProcedure(Procedure proc, IDocument document)435{436string def_poc;437
438ParserInternal.UpdateParseBuffer(document.TextContent);439ProcedureBlock block = ParserInternal.GetProcedureBlock(proc.name, 0, true);440block.declar = proc.d.declared;441
442document.UndoStack.StartUndoGroup();443DeleteProcedure(document, block, out def_poc);444document.UndoStack.EndUndoGroup();445}446
447// Remove multi procedures448internal static void DeleteProcedure(List<string> procName, IDocument document)449{450document.UndoStack.StartUndoGroup();451foreach (var name in procName)452{453string def_poc;454
455ParserInternal.UpdateParseBuffer(document.TextContent);456ProcedureBlock block = ParserInternal.GetProcedureBlock(name, 0, true);457block.declar = ParserInternal.GetDeclarationProcedureLine(name) + 1;458DeleteProcedure(document, block, out def_poc);459}460document.UndoStack.EndUndoGroup();461}462
463internal static void DeleteProcedure(IDocument document, ProcedureBlock block, out string def_poc)464{465ISegment segmentS = document.GetLineSegment(block.begin);466ISegment segmentE = document.GetLineSegment(block.end);467int len = (segmentE.Offset + segmentE.Length) - segmentS.Offset;468
469int inc_s = 0;470int inc_e = 2;471if (block.end < document.TotalNumberOfLines - 1) {472if (segmentS.Offset + len + 4 <= document.TextLength) {473if (document.GetLineSegment(block.end + 1).Length == 0) {474if (block.begin > 0 && document.GetLineSegment(block.begin - 1).Length == 0) {475len += 2;476inc_s = -2;477}478}479}480else481inc_e = 0;482} else483inc_e = 0;484document.Remove(segmentS.Offset + inc_s, len + inc_e);485
486// declare487int declarLine = block.declar - 1;488if (declarLine > -1 & declarLine != block.begin) {489def_poc = TextUtilities.GetLineAsString(document, declarLine);490int offset = document.PositionToOffset(new TextLocation(0, declarLine));491document.Remove(offset, def_poc.Length + 2);492} else493def_poc = null;494}495
496// Create procedure block497internal static void InsertProcedure(TextAreaControl TAC, string name, string procblock, int declrLine, int procLine, ref int caretline)498{499TAC.Document.UndoStack.StartUndoGroup();500TAC.SelectionManager.ClearSelection();501
502// proc body paste503int len = TextUtilities.GetLineAsString(TAC.Document, procLine).Trim().Length;504if (len > 0) {505procblock = Environment.NewLine + procblock;506caretline++;507}508int offset = TAC.Document.PositionToOffset(new TextLocation(len, procLine));509TAC.Document.Insert(offset, procblock);510
511// declared paste512offset = TAC.Document.PositionToOffset(new TextLocation(0, declrLine));513TAC.Document.Insert(offset, "procedure " + name + ";" + Environment.NewLine);514
515TAC.Document.UndoStack.EndUndoGroup();516}517#endregion518
519#region Misc code function520internal static void HighlightingSelectedText(TextAreaControl TAC)521{522List<TextMarker> marker = TAC.Document.MarkerStrategy.GetMarkers(0, TAC.Document.TextLength);523foreach (TextMarker m in marker)524{525if (m.TextMarkerType == TextMarkerType.SolidBlock)526TAC.Document.MarkerStrategy.RemoveMarker(m);527}528if (!TAC.SelectionManager.HasSomethingSelected) return;529
530string sWord = TAC.SelectionManager.SelectedText.Trim();531int wordLen = sWord.Length;532if (wordLen == 0 || (wordLen <= 2 && !Char.IsLetterOrDigit(sWord[0]) && wordLen == 2 && !Char.IsLetterOrDigit(sWord[1]))) return;533
534string word = TAC.Document.LineSegmentCollection[TAC.Caret.Line].GetWord(TAC.SelectionManager.SelectionCollection[0].StartPosition.Column).Word;535bool isWordHighlighting = (wordLen == word.Length && sWord == word);536
537int seek = 0;538while (seek < TAC.Document.TextLength) {539seek = TAC.Document.TextContent.IndexOf(sWord, seek);540if (seek == -1) break;541char chS = '\0', chE = '\0';542if (isWordHighlighting) {543chS = (seek > 0) ? TAC.Document.GetCharAt(seek - 1) : ' ';544chE = ((seek + wordLen) < TAC.Document.TextLength) ? TAC.Document.GetCharAt(seek + wordLen) : ' ';545}546if (!isWordHighlighting || !(Char.IsLetterOrDigit(chS) || chS == '_') && !(Char.IsLetterOrDigit(chE) || chE == '_'))547TAC.Document.MarkerStrategy.AddMarker(new TextMarker(seek, sWord.Length, TextMarkerType.SolidBlock,548ColorTheme.SelectedHighlight.BackgroundColor, ColorTheme.SelectedHighlight.Color));549seek += wordLen;550}551TAC.SelectionManager.ClearSelection();552}553
554// Auto selected text color region555internal static void SelectedTextColorRegion(TextLocation position, TextAreaControl TAC)556{557if (position.IsEmpty) position = TAC.Caret.Position;558
559HighlightColor hc = TAC.Document.GetLineSegment(position.Line).GetColorForPosition(position.Column);560if (hc != null && hc.BackgroundColor == ColorTheme.CodeFunctions) {561int sEnd = TextUtilities.SearchBracketForward(TAC.Document, TAC.Caret.Offset + 1, '{', '}');562char c = TAC.Document.GetCharAt(TAC.Caret.Offset);563if (sEnd == -1) {564if (c != '}') return;565sEnd = TAC.Caret.Offset;566}567int sStart = TextUtilities.SearchBracketBackward(TAC.Document, TAC.Caret.Offset - 1, '{', '}');568if (sStart == -1) {569if (c != '{') return;570sStart = TAC.Caret.Offset;571}572int len = sEnd - sStart;573if (len < 2) return;574TextLocation sSel = TAC.Document.OffsetToPosition(sStart);575TextLocation eSel = TAC.Document.OffsetToPosition(sEnd + 1);576if (sSel.Line != eSel.Line || TAC.Document.GetText(sStart, len).IndexOfAny(new char[] { ':', ',' }) != -1) return;577TAC.SelectionManager.SetSelection(sSel, eSel);578}579}580
581// Paste autocomplete KeyWord construction code582internal static bool AutoCompleteKeyWord(TextAreaControl TAC)583{584Caret caret = TAC.Caret;585if (ColorTheme.CheckColorPosition(TAC.Document, caret.Position))586return false;587
588int offsetShift = 1;589if (TAC.Document.TextLength == caret.Offset) offsetShift++;590
591string keyword = TextUtilities.GetWordAt(TAC.Document, caret.Offset - offsetShift);592if (keyword.Length < 2)593return false;594
595string lineText = TextUtilities.GetLineAsString(TAC.Document, caret.Line);596int totalWS = 0, totalTab = 0;597for (int i = 0; i < lineText.Length; i++)598{599if (lineText[i] == ' ')600totalWS++;601else if (lineText[i] == '\t')602totalTab++;603else604break;605}606
607int indentationSize = TAC.TextEditorProperties.IndentationSize;608bool convertTab = TAC.TextEditorProperties.ConvertTabsToSpaces;609if (convertTab) {610totalTab *= indentationSize;611} else {612totalWS /= indentationSize;613}614int columnStart = totalWS + totalTab;615
616int keyStart = TextUtilities.FindWordStart(TAC.Document, caret.Offset - offsetShift);617int keyLen = caret.Offset - keyStart;618bool cutKeyWord = keyword.Length > keyLen;619if (cutKeyWord) keyword = keyword.Remove(keyLen);620
621string beginIndent = String.Empty;622if (caret.Column > keyword.Length) beginIndent = new String((convertTab) ? ' ' : '\t', columnStart);623
624string indentation = beginIndent;625if (convertTab)626indentation += new String(' ', indentationSize);627else628indentation += '\t';629
630int lineShift = 2, columnShift = 0;631if (convertTab) {632if (totalTab > 0) {633columnShift -= (totalTab / indentationSize);634columnShift += columnShift;635}636} else if (totalWS > 0) columnShift = (totalWS * indentationSize) - totalWS;637
638bool keyWordMatch = true;639string code = null;640TAC.Document.UndoStack.StartUndoGroup();641switch (keyword)642{643case "for":644code = " ({iterator} := 0; {condition}; {iterator}++) begin\r\n" + indentation + "\r\n";645columnShift += 2;646break;647case "foreach":648code = " ({iterator}: {item} in {array}) begin\r\n" + indentation + "\r\n";649columnShift += 6;650break;651case "while":652code = " ({condition}) do begin\r\n" + indentation + "\r\n";653columnShift += 4;654break;655case "switch":656code = " ({condition}) begin\r\n" + indentation657+ "case {constant} : {code}\r\n" + indentation658+ "default : {code}\r\n";659lineShift++;660columnShift += 5;661break;662case "if":663code = " ({condition}) then begin\r\n" + indentation + "\r\n";664columnShift++;665break;666case "ifel":667code = "({condition}) then begin" + String.Format("{0}{2}{0}{1}else{0}{2}{0}",668"\r\n", beginIndent, indentation);669lineShift = 4;670columnShift += 2;671TAC.Document.Remove(caret.Offset - 2, 2);672break;673case "elif":674code = " if ({condition}) then begin\r\n" + indentation + "\r\n";675columnShift += 6;676TAC.Document.Replace(caret.Offset - 2, 2, "se");677break;678case "else":679code = " begin\r\n" + indentation + "\r\n";680lineShift = 1;681int isize = (convertTab) ? indentationSize : 1;682columnShift = (columnStart + isize) - (columnStart + 3);683break;684case "then":685code = " begin";686lineShift = 0;687columnShift = 0;688break;689case "var":690code = "iable ";691lineShift = 0;692columnShift = 0;693break;694case "proc":695code = "edure ";696lineShift = 0;697columnShift = 0;698break;699default:700keyWordMatch = false;701break;702}703if (keyWordMatch) {704if (lineShift != 0) {705code += beginIndent + endKeyWord + ((cutKeyWord) ? " " : String.Empty);706}707TAC.TextArea.InsertString(code);708TAC.Caret.Position = new TextLocation(caret.Column + columnShift, caret.Line - lineShift); //+ keyword.Length - columnShift709Utilities.SelectedTextColorRegion(caret.Position, TAC);710}711TAC.Document.UndoStack.EndUndoGroup();712
713return keyWordMatch;714}715
716internal static void PasteIncludeFile(string sHeaderfile, TextAreaControl TAC)717{718if (sHeaderfile != null) {719int beginLine = 1, endLine = 1;720foreach (FoldMarker fm in TAC.Document.FoldingManager.FoldMarker) {721if (fm.FoldType == FoldType.Region) {722beginLine = fm.StartLine;723endLine = fm.EndLine;724break;725}726}727
728string includeText = "#include ";729var caret = TAC.Caret.Line;730if (caret >= beginLine && caret <= endLine) {731beginLine = caret;732} else {733for (int line = endLine; line > 0; line--) {734string ln = TextUtilities.GetLineAsString(TAC.Document, line);735if (ln.TrimStart().StartsWith(includeText, StringComparison.OrdinalIgnoreCase)) {736beginLine = line + 1;737break;738}739}740}741
742includeText += "\"" + sHeaderfile + "\"" + Environment.NewLine;743int offset = TAC.Document.PositionToOffset(new TextLocation(0, beginLine));744TAC.Document.Insert(offset, includeText);745TAC.Document.MarkerStrategy.AddMarker(new TextMarker(offset, includeText.Length, TextMarkerType.SolidBlock, ColorTheme.IncludeHighlight));746TAC.ScrollTo(beginLine);747TAC.Refresh();748}749}750
751#endregion752
753#region Script code text functions754public static int ReplaceCommonText(Regex s_regex, ref string document, string newText, int differ)755{756MatchCollection matches = s_regex.Matches(document);757
758int replace_count = 0;759foreach (Match m in matches)760{761int offset = (differ * replace_count) + m.Index;762document = document.Remove(offset, m.Length);763document = document.Insert(offset, newText);764replace_count++;765}766return matches.Count;767}768
769// используется для замены имени процедур770public static int ReplaceSpecialText(Regex s_regex, ref string document, string newText, int differ)771{772MatchCollection matches = s_regex.Matches(document);773
774int replace_count = 0;775foreach (Match m in matches)776{777var shiftOffset = (m.Groups.Count > 1) ? m.Groups[1].Length : 0;778int offset = (differ * replace_count) + (m.Index + shiftOffset);779
780document = document.Remove(offset, (m.Length - shiftOffset));781document = document.Insert(offset, newText);782replace_count++;783}784return matches.Count;785}786
787public static void ReplaceIDocumentText(Regex s_regex, IDocument document, string newText, int differ)788{789MatchCollection matches = s_regex.Matches(document.TextContent);790document.UndoStack.StartUndoGroup();791
792int replace_count = 0;793foreach (Match m in matches)794{795ReplaceMatch(document, newText, differ * replace_count++, m);796}797document.UndoStack.EndUndoGroup();798}799
800public static void ReplaceByReferences(Regex s_regex, IDocument document, IParserInfo pi, string newText, int differ)801{802MatchCollection matches = s_regex.Matches(document.TextContent);803
804bool isVariable = (pi is Variable);805
806bool decl = false, define = isVariable;807int declared = (isVariable) ? (((Variable)pi).IsArgument) ? ((Variable)pi).adeclared : ((Variable)pi).d.declared808: ((Procedure)pi).d.declared;809
810List<Reference> references = pi.References().ToList();811List<Match> renameReferences = new List<Match>();812
813foreach (Match m in matches)814{815int line = document.OffsetToPosition(m.Index).Line + 1;816
817if (!decl && declared == line) {818renameReferences.Add(m);819decl = true;820} else if (!define && ((Procedure)pi).d.defined == line) { // может быть -1 если declared для процедуры не был объявлен821renameReferences.Add(m);822define = true;823} else {824for (int i = 0; i < references.Count; i++)825{826if (references[i].line == line) {827renameReferences.Add(m);828references.RemoveAt(i);829break;830}831}832}833}834document.UndoStack.StartUndoGroup();835
836int replace_count = 0;837foreach (Match refMatch in renameReferences)838{839ReplaceMatch(document, newText, differ * replace_count++, refMatch);840}841document.UndoStack.EndUndoGroup();842
843if (references.Count > 0) MessageBox.Show("Some of the references have not been renamed.", "Warning");844}845
846private static void ReplaceMatch(IDocument document, string newText, int replacedCount, Match m)847{848var shiftOffset = (m.Groups.Count > 1) ? m.Groups[1].Length : 0;849int offset = replacedCount + (m.Index + shiftOffset);850document.Replace(offset, (m.Length - shiftOffset), newText);851}852
853internal static string GetProcedureCode(IDocument document, Procedure curProc)854{855if (curProc.d.start == -1 || curProc.d.end == -1) // for imported or w/o body procedure856return null;857
858LineSegment start = document.GetLineSegment(curProc.d.start);859LineSegment end = document.GetLineSegment(curProc.d.end - 1);860int length = end.Offset - start.Offset - 2; // -2 не захватываем символы CRLF861
862return (length < 0) ? String.Empty : document.GetText(start.Offset, length);863}864
865internal static bool ReplaceProcedureCode(IDocument document, ProgramInfo pi, string name, string code)866{867int index = pi.GetProcedureIndex(name);868if (index == -1)869return true; // procedure not found870
871LineSegment start = document.GetLineSegment(pi.procs[index].d.start);872LineSegment end = document.GetLineSegment(pi.procs[index].d.end - 1);873int length = end.Offset - start.Offset - 2; // -2 не заменяем символы CRLF874
875if (length < 0 && code.Length > 0 && !code[code.Length - 1].Equals('\n'))876code += Environment.NewLine;877
878if (length < 0)879document.Insert(start.Offset, code);880else881document.Replace(start.Offset, length, code);882
883return false;884}885
886internal static void InsertText(string iText, TextAreaControl TAC)887{888TAC.Document.UndoStack.StartUndoGroup();889if (TAC.SelectionManager.HasSomethingSelected) {890TextLocation selStart = TAC.SelectionManager.SelectionCollection[0].StartPosition;891TAC.TextArea.SelectionManager.RemoveSelectedText();892TAC.Caret.Position = selStart;893}894TAC.TextArea.InsertString(iText);895TAC.Document.UndoStack.EndUndoGroup();896}897
898//Get block text899internal static string GetRegionText(IDocument document, int _begin, int _end, int _ecol = 0, int _bcol = 0)900{901ISegment segmentB = document.GetLineSegment(_begin);902ISegment segmentE = document.GetLineSegment(_end);903
904int Offset = segmentB.Offset + _bcol;905int Length;906if (_ecol > 0)907Length = segmentE.Offset + _ecol;908else909Length = segmentE.Offset + segmentE.Length;910Length -= Offset;911
912return document.GetText(Offset, Length);913}914
915//Selected and return block text [NOT USED]916internal static string GetSelectBlockText(TextAreaControl TAC, int _begin, int _end, int _ecol = -1, int _bcol = 0)917{918if (_ecol < 0)919_ecol = TAC.Document.GetLineSegment(_end).Length;920TAC.SelectionManager.SetSelection(new TextLocation(_bcol, _begin), new TextLocation(_ecol, _end));921return TAC.SelectionManager.SelectedText;922}923
924internal static string NormalizeNewLine(string text)925{926char[] delimetr = new char[] {'\r', '\n'};927
928int offset = 0;929while (offset < text.Length) {930offset = text.IndexOfAny(delimetr, offset);931if (offset == -1)932break;933switch (text[offset]) {934case '\r':935if (offset + 1 < text.Length) {936if (text[++offset] != delimetr[1])937text = text.Insert(offset, delimetr[1].ToString());938}939break;940case '\n':941if (offset > 0 && text[offset - 1] != delimetr[0])942text = text.Insert(offset, delimetr[0].ToString());943break;944}945offset++;946};947return text;948}949
950internal static void ConvertToUnixPlatform(ref string text)951{952if (Environment.OSVersion.Platform != PlatformID.Unix) return;953int offset = 0;954while (offset < text.Length)955{956offset = text.IndexOf('\r', offset);957if (offset == -1) break;958text = text.Remove(offset, 1);959offset++;960};961}962
963internal static void GetQuotesPosition(string textCode, List<Quote> quotes)964{965int openQuotes = textCode.IndexOf('"');966while (openQuotes > -1)967{968Quote position;969position.Open = openQuotes++;970position.Close = textCode.IndexOf('"', openQuotes);971if (position.Close == -1)972break;973quotes.Add(position);974openQuotes = textCode.IndexOf('"', position.Close + 1);975};976}977#endregion978}979}
980