示例#1
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 => ");
                    }
示例#2
0
文件: CiSnippets.cs 项目: qmgindi/Au
    //static int s_test;
    public static void AddSnippets(List <CiComplItem> items, TextSpan span, CompilationUnitSyntax root, string code, CSharpSyntaxContext syncon)
    {
        //CSharpSyntaxContext was discovered later and therefore almost not used here.
        if (syncon.IsObjectCreationTypeContext)
        {
            return;
        }
        //CiUtil.GetContextType(syncon);

        //print.clear(); print.it(++s_test);

        //print.clear();
        //foreach (var v in root.ChildNodes()) {
        //	CiUtil.PrintNode(v);
        //}
        //print.it("---");

        _Context context = _Context.Unknown;
        int      pos     = span.Start;

        //get node from start
        var token = root.FindToken(pos);
        var node  = token.Parent;

        //CiUtil.PrintNode(node); //print.it("--");
        //return;

        //find ancestor/self that contains pos inside
        while (node != null && !node.Span.ContainsInside(pos))
        {
            node = node.Parent;
        }
        //CiUtil.PrintNode(node);
        //for(var v = node; v != null; v = v.Parent) print.it(v.GetType().Name, v is ExpressionSyntax, v is ExpressionStatementSyntax);

        //print.it(SyntaxFacts.IsTopLevelStatement);
        //print.it(SyntaxFacts.IsInNamespaceOrTypeContext); //not tested

        switch (node)
        {
        case BlockSyntax:
        case SwitchSectionSyntax:         //between case: and break;
        case ElseClauseSyntax:
        case LabeledStatementSyntax:
        case IfStatementSyntax s1 when pos > s1.CloseParenToken.SpanStart:
        case WhileStatementSyntax s2 when pos > s2.CloseParenToken.SpanStart:
        case DoStatementSyntax s3 when pos <s3.WhileKeyword.SpanStart:
                                        case ForStatementSyntax s4 when pos> s4.CloseParenToken.SpanStart:
        case CommonForEachStatementSyntax s5 when pos > s5.CloseParenToken.SpanStart:
        case LockStatementSyntax s6 when pos > s6.CloseParenToken.SpanStart:
        case FixedStatementSyntax s7 when pos > s7.CloseParenToken.SpanStart:
        case UsingStatementSyntax s8 when pos > s8.CloseParenToken.SpanStart:
            context = _Context.Function;
            break;

        case TypeDeclarationSyntax td when pos > td.OpenBraceToken.Span.Start:         //{ } of class, struct, interface
            context = _Context.Type;
            break;

        case NamespaceDeclarationSyntax ns when pos > ns.OpenBraceToken.Span.Start:
        case CompilationUnitSyntax:
        case null:
            context = _Context.Namespace | _Context.Function;             //Function for C# 9 top-level statements. //FUTURE: only if in correct place.
            break;

        case LambdaExpressionSyntax:
        case ArrowExpressionClauseSyntax:         //like void F() =>here
            context = _Context.Arrow;
            break;

        case AttributeListSyntax:
            context = _Context.Attributes;
            break;

        default:
            if (span.IsEmpty)               //if '=> here;' or '=> here)' etc, use =>
            {
                var t2 = token.GetPreviousToken();
                if (t2.IsKind(SyntaxKind.EqualsGreaterThanToken) && t2.Parent is LambdaExpressionSyntax)
                {
                    context = _Context.Arrow;
                }
            }
            break;
        }
        //print.it(context);
        s_context = context;

        if (s_items == null)
        {
            var a = new List <_CiComplItemSnippet>();
            if (!filesystem.exists(CustomFile).File)
            {
                try { filesystem.copy(folders.ThisAppBS + @"Default\Snippets2.xml", CustomFile); }
                catch { goto g1; }
            }
            _LoadFile(CustomFile, true);
            g1 : _LoadFile(DefaultFile, false);
            if (a.Count == 0)
            {
                return;
            }
            s_items = a;

            void _LoadFile(string file, bool custom)
            {
                try {
                    var xroot = XmlUtil.LoadElem(file);
                    foreach (var xg in xroot.Elements("group"))
                    {
                        if (!xg.Attr(out string sc, "context"))
                        {
                            continue;
                        }
                        _Context con = default;
                        if (sc == "Function")
                        {
                            con = _Context.Function;   //many
                        }
                        else                           //few, eg Type or Namespace|Type
                        {
                            foreach (var seg in sc.Segments("|"))
                            {
                                switch (sc[seg.Range])
                                {
                                case "Function": con |= _Context.Function; break;

                                case "Type": con |= _Context.Type; break;

                                case "Namespace": con |= _Context.Namespace; break;

                                case "Arrow": con |= _Context.Arrow; break;

                                case "Attributes": con |= _Context.Attributes; break;

                                case "Any": con |= _Context.Any; break;

                                case "Line": con |= _Context.Line; break;
                                }
                            }
                        }
                        if (con == default)
                        {
                            continue;
                        }
                        foreach (var xs in xg.Elements("snippet"))
                        {
                            a.Add(new _CiComplItemSnippet(xs.Attr("name"), xs, con, custom));
                        }
                    }
                }
                catch (Exception ex) { print.it("Failed to load snippets from " + file + "\r\n\t" + ex.ToStringWithoutStack()); }
            }

            //FUTURE: support $selection$. Add menu Edit -> Surround -> Snippet1|Snippet2|....
            //FUTURE: snippet editor, maybe like in Eclipse.
        }

        bool isLineStart = InsertCodeUtil.IsLineStart(code, pos);

        foreach (var v in s_items)
        {
            if (!v.context.HasAny(context))
            {
                continue;
            }
            if (v.context.Has(_Context.Line) && !isLineStart)
            {
                continue;
            }
            v.group   = 0; v.hidden = 0; v.hilite = 0; v.moveDown = 0;
            v.ci.Span = span;
            items.Add(v);
        }
    }