Beispiel #1
0
    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);
                }
            }
        }
    }
Beispiel #2
0
        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 => ");
                    }
Beispiel #3
0
    /// <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);
    }