bool _Update() { //print.it("update"); //using var p1 = perf.local(); if (!CodeInfo.GetContextAndDocument(out var cd, 0, metaToo: true)) { return(false); } var cu = cd.syntaxRoot; var root = new _Item(); //at first get regions if (cu.ContainsDirectives) { _Item regions = null; for (var d = cu.GetFirstDirective(); d != null; d = d.GetNextDirective()) { if (!d.IsKind(SyntaxKind.RegionDirectiveTrivia) || !d.IsActive) { continue; } var s = d.EndOfDirectiveToken.LeadingTrivia.ToString(); if (s.NE()) { continue; } if (regions == null) { root.AddChild(regions = new("#region", CiItemKind.Region, 0)); } regions.AddChild(new(s, CiItemKind.Region, d.SpanStart)); } } //then get member declarations var members = cu.Members; while (members.Count == 1) { var f = members.First(); if (f is BaseNamespaceDeclarationSyntax nd) { members = nd.Members; } else if (f is TypeDeclarationSyntax td) { members = td.Members; } else { break; } } //p1.Next('d'); _Members(root, members, 0); //p1.Next('m'); void _Members(_Item parent, SyntaxList <MemberDeclarationSyntax> members, int level) { int sort = App.Settings.outline_flags & 3; List <_Item> a = sort != 0 ? new() : null; _Item locals = null; foreach (var m in members) { if (level == 0 && m is GlobalStatementSyntax g) { if (g.Statement is not LocalFunctionStatementSyntax d) { continue; } if (locals == null) { parent.AddChild(locals = new("Local functions", CiItemKind.LocalMethod, 0)); } var k = new _Item(d); locals.AddChild(k); } else { var k = new _Item(m); if (a != null) { a.Add(k); } else { parent.AddChild(k); } switch (m) { case BaseNamespaceDeclarationSyntax d: _Members(k, d.Members, level + 1); break; case TypeDeclarationSyntax d: _Members(k, d.Members, level + 1); break; } } } if (a != null) { a.Sort((i1, i2) => { if (sort >= 2) { int k1 = (int)i1._kind, k2 = (int)i2._kind; if (k1 != k2) { return(k1 - k2); } //if (sort == 2) return i1._pos - i2._pos; } string s1 = i1._text, s2 = i2._text; bool a1 = s1[0].IsAsciiAlpha(), a2 = s2[0].IsAsciiAlpha(); if (a1 != a2) { return(a1 ? -1 : 1); } return(string.CompareOrdinal(s1, s2)); }); foreach (var v in a) { parent.AddChild(v); } } } _modified = false; _activeDoc = cd.sci; //_oldDocument = cd.document; int changed = 4; if (_oldTree != null) { changed = _TreeChanged(_oldTree, root); //print.it(changed); if (changed == 0) { _UpdatePos(_oldTree, root); return(true); } } _oldTree = root; //p1.Next('c'); if (!_once) { _once = true; _tv.ItemActivated += (_, e) => { _activeDoc.Focus(); var v = e.Item as _Item; _activeDoc.zGoToPos(true, v._pos); }; Panels.Editor.ZActiveDocChanged += () => Clear(); } _tv.SetItems(root.Children(), modified: changed != 4); return(true); //0 same, 1 changed int _TreeChanged(_Item old, _Item now) { int R = 0; if (old.HasChildren || now.HasChildren) { for (_Item o = old.FirstChild, n = now.FirstChild; ; o = o.Next, n = n.Next) { if ((o == null) != (n == null)) { return(1); //added or removed at the end } if (o == null) { break; } if (!n.Eq(o)) { //is just changed text of this, or something added or removed in the moddle? If added/removed, need to update _isExpanded. R |= 1; _Item o1 = o.Next, n1 = n.Next; if (o1 != null && n1 != null) //else added or removed at the end { if (!n1.Eq(o1)) //else just changed text { for (; n1 != null; n1 = n1.Next) { if (n1.Eq(o)) { n = n1; goto g1; } //inserted 1 or more } for (; o1 != null; o1 = o1.Next) { if (o1.Eq(n)) { o = o1; goto g1; } //removed 1 or more } return(1); g1 :; } } } if (o.HasChildren || n.HasChildren) { R |= _TreeChanged(o, n); } } now._isExpanded = old._isExpanded; } return(R); } void _UpdatePos(_Item old, _Item now) { for (_Item o = old.FirstChild, n = now.FirstChild; o != null; o = o.Next, n = n.Next) { o._pos = n._pos; if (o.HasChildren) { _UpdatePos(o, n); } } } }
unsafe void _Drop(POINT xy, int effect) { _GetDropPos(ref xy, out int pos8); var z = new Sci_DragDropData { x = xy.x, y = xy.y }; string s = null; var b = new StringBuilder(); int what = 0, index = 0; if (_justText) { s = _data.text; } else { _sci.Call(SCI_DRAGDROP, 2, &z); //just hides the drag indicator and sets caret position if (_sci._fn.IsCodeFile) { string mi = _data.scripts ? "1 string s = name;|2 string s = path;|3 script.run(path);|4 t[name] = o => script.run(path);" : "11 string s = path;|12 run.it(path);|13 t[name] = o => run.it(path);"; what = popupMenu.showSimple(mi); if (what == 0) { return; } } if (_data.scripts) { var a = Panels.Files.TreeControl.DragDropFiles; if (a != null) { foreach (var f in a) { _AppendScriptOrLink(f.ItemPath, f.Name, f); } } } else if (_data.files != null) { foreach (var path in _data.files) { _AppendFileOrShell(path); } } else if (_data.shell != null) { _GetShell(_data.shell, out var shells, out var names); if (shells != null) { for (int i = 0; i < shells.Length; i++) { _AppendFileOrShell(shells[i], names[i]); } } } else if (_data.linkName != null) { _AppendScriptOrLink(_data.text, _GetLinkName(_data.linkName)); } s = b.ToString(); } if (!s.NE()) { if (_justText) //a simple drag-drop inside scintilla or text-only from outside { var s8 = Encoding.UTF8.GetBytes(s); fixed(byte *p8 = s8) { z.text = p8; z.len = s8.Length; if (0 == ((DragDropEffects)effect & DragDropEffects.Move)) { z.copy = 1; } CodeInfo.Pasting(_sci); _sci.Call(SCI_DRAGDROP, 2, &z); } } else //file, script or URL { InsertCode.Statements(s, ICSFlags.NoFocus); } if (!_sci.IsFocused && _sci.Hwnd.Window.IsActive) //note: don't activate window; let the drag source do it, eg Explorer activates on drag-enter. { _sci._noModelEnsureCurrentSelected = true; //don't scroll treeview to currentfile _sci.Focus(); _sci._noModelEnsureCurrentSelected = false; } } else { _sci.Call(SCI_DRAGDROP, 3); } void _AppendFileOrShell(string path, string name = null) { if (b.Length > 0) { b.AppendLine(); } var pi = new TUtil.PathInfo(path, name); b.Append(pi.FormatCode(what - 11, ++index)); } void _AppendScriptOrLink(string path, string name, FileNode fn = null) { if (b.Length > 0) { b.AppendLine(); } if (what == 0) { b.Append(path); } else { if (what == 4) { name = name.RemoveSuffix(".cs"); } name = name.Escape(); if (what is 4 or 13) { var t = InsertCodeUtil.GetNearestLocalVariableOfType("Au.toolbar", "Au.popupMenu"); b.Append($"{t?.Name ?? "t"}[\"{name}\"] = o => "); }
/// <summary> /// If f is already open, unhides its control. /// Else loads f text and creates control. If fails, does not change anything. /// Hides current file's control. /// Returns false if failed to read file. /// Does not save text of previously active document. /// </summary> /// <param name="f"></param> /// <param name="newFile">Should be true if opening the file first time after creating.</param> public bool ZOpen(FileNode f, bool newFile) { Debug.Assert(!Program.Model.IsAlien(f)); if (f == _activeDoc?.ZFile) { return(true); } bool focus = _activeDoc?.Focused ?? false; var doc = ZGetOpenDocOf(f); if (doc != null) { if (_activeDoc != null) { _activeDoc.Visible = false; } _activeDoc = doc; _activeDoc.Visible = true; _UpdateUI_EditEnabled(); ZActiveDocChanged?.Invoke(); } else { var path = f.FilePath; byte[] text = null; SciText.FileLoaderSaver fls = default; try { text = fls.Load(path); } catch (Exception ex) { AOutput.Write("Failed to open file. " + ex.Message); } if (text == null) { return(false); } if (_activeDoc != null) { _activeDoc.Visible = false; } doc = new SciCode(f, fls); doc.AccessibleName = f.Name; doc.AccessibleDescription = path; _docs.Add(doc); _activeDoc = doc; this.Controls.Add(doc); doc._Init(text, newFile); _UpdateUI_EditEnabled(); ZActiveDocChanged?.Invoke(); //CodeInfo.FileOpened(doc); } if (focus && !newFile) { _activeDoc.Focus(); } else //don't focus now, or then cannot select treeview items with keyboard etc. Focus on mouse move in editor control. { _openFocus.onMM ??= (object sender, MouseEventArgs e) => { var c = sender as Control; if (!c.FindForm().Hwnd().IsActive) { return; } if (_openFocus.dist >= 0) //if new file, don't focus until mouse moved away from tree { int dist = (int)AMath.Distance(Program.Model.TreeControl.Hwnd().Rect, AMouse.XY); if (dist < _openFocus.dist + 10) { if (dist < _openFocus.dist) { _openFocus.dist = dist; } return; } } c.MouseMove -= _openFocus.onMM; c.Focus(); }; _activeDoc.MouseMove += _openFocus.onMM; _openFocus.dist = newFile ? int.MaxValue - 10 : -1; } _activeDoc.Call(SCI_SETWRAPMODE, Program.Settings.edit_wrap); //fast and does nothing if already is in that wrap state _activeDoc.ZImages.Visible = Program.Settings.edit_noImages ? AnnotationsVisible.ANNOTATION_HIDDEN : AnnotationsVisible.ANNOTATION_STANDARD; _UpdateUI_IsOpen(); Panels.Find.ZUpdateQuickResults(true); return(true); }