Beispiel #1
0
        /// <summary>
        /// Find a list of items in the completion and return it
        /// Uses the position to filter the list the same way the autocompletion form would
        /// </summary>
        /// <returns></returns>
        public static List <CompletionItem> FindInCompletionData(string keyword, int position, bool dontCheckLine = false)
        {
            var filteredList = AutoCompletionForm.ExternalFilterItems(SavedAllItems.ToList(), Npp.LineFromPosition(position), dontCheckLine);

            if (filteredList == null || filteredList.Count <= 0)
            {
                return(null);
            }
            var found = filteredList.Where(data => data.DisplayText.EqualsCi(keyword)).ToList();

            if (found.Count > 0)
            {
                return(found);
            }

            // search in tables fields
            var tableFound = ParserHandler.FindAnyTableOrBufferByName(Npp.GetFirstWordRightAfterPoint(position));

            if (tableFound == null)
            {
                return(null);
            }

            var listOfFields = DataBase.GetFieldsList(tableFound).ToList();

            return(listOfFields.Where(data => data.DisplayText.EqualsCi(keyword)).ToList());
        }
Beispiel #2
0
        /// <summary>
        /// Returns a keyword from the autocompletion list with the correct case
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="lastWordPos"></param>
        /// <returns></returns>
        public static string CorrectKeywordCase(string keyword, int lastWordPos)
        {
            string output = null;

            if (!Config.Instance.DisableAutoCaseCompletly)
            {
                var found = FindInSavedItems(keyword, Npp.Line.CurrentLine);
                if (found != null)
                {
                    RememberUseOf(found);
                    int caseMode;
                    if (found.FromParser)
                    {
                        caseMode = 4; // use displayText case
                    }
                    else if (found.Type == CompletionType.Database || found.Type == CompletionType.Field || found.Type == CompletionType.FieldPk || found.Type == CompletionType.Sequence || found.Type == CompletionType.Table)
                    {
                        caseMode = Config.Instance.DatabaseChangeCaseMode;
                    }
                    else
                    {
                        caseMode = Config.Instance.KeywordChangeCaseMode;
                    }
                    output = keyword.ConvertCase(caseMode, found.DisplayText);
                }
                else
                {
                    // search in tables fields
                    var tableFound = ParserHandler.FindAnyTableOrBufferByName(Npp.GetFirstWordRightAfterPoint(lastWordPos));
                    if (tableFound != null)
                    {
                        var fieldFound = DataBase.FindFieldByName(keyword, tableFound);
                        if (fieldFound != null)
                        {
                            RememberUseOf(new CompletionItem {
                                FromParser  = false,
                                DisplayText = fieldFound.Name,
                                Type        = CompletionType.Field,
                                Ranking     = 0
                            });
                            RememberUseOfDatabaseItem(fieldFound.Name);
                            output = keyword.ConvertCase(tableFound.IsTempTable ? 4 : Config.Instance.DatabaseChangeCaseMode, fieldFound.Name);
                        }
                    }
                }
            }
            return(output);
        }
Beispiel #3
0
        /// <summary>
        /// Sets the content of the tooltip (when we want to descibe something present in the completionData list)
        /// </summary>
        private static void SetToolTip()
        {
            var popupMinWidth = 250;
            var toDisplay     = new StringBuilder();

            GoToDefinitionFile = null;

            // only select one item from the list
            var data = GetCurrentlyDisplayedCompletionData();

            if (data == null)
            {
                return;
            }

            CurrentWord = data.DisplayText;

            // general stuff
            toDisplay.Append("<div class='InfoToolTip' id='ToolTip'>");
            toDisplay.Append(@"
                <table width='100%' class='ToolTipName'>
                    <tr style='vertical-align: top;'>
                    <td>
                        <table width='100%' style='margin: 0; padding: 0;'>
                            <tr>
                                <td rowspan='2' style='width: 25px;'>
                                    <img src='" + data.Type + @"'>
                                </td>
                                <td>
                                    " + data.DisplayText + @"
                                </td>
                            </tr>
                            <tr>
                                <td>
                                    <span class='ToolTipSubString'>" + data.Type + @"</span>
                                </td>
                            </tr>
                        </table>
                    </td>");
            if (_currentCompletionList.Count > 1)
            {
                toDisplay.Append(@"
                        <td class='ToolTipCount'>" +
                                 (IndexToShow + 1) + "/" + _currentCompletionList.Count + @"
                        </td>");
            }
            toDisplay.Append(@"
                    </tr>
                </table>");

            // the rest depends on the item type
            try {
                switch (data.Type)
                {
                case CompletionType.TempTable:
                case CompletionType.Table:
                    popupMinWidth = Math.Min(500, Npp.NppScreen.WorkingArea.Width / 2);
                    // buffer
                    if (data.FromParser)
                    {
                        if (data.ParsedItem is ParsedDefine)
                        {
                            toDisplay.Append(FormatRowWithImg(ParseFlag.Buffer.ToString(), "BUFFER FOR " + FormatSubString(data.SubString)));
                        }
                        if (data.ParsedItem is ParsedTable && !string.IsNullOrEmpty(data.SubString))
                        {
                            toDisplay.Append(FormatRow("Is like", (data.SubString.Contains("?")) ? "Unknow table [" + ((ParsedTable)data.ParsedItem).LcLikeTable + "]" : data.SubString.Replace("Like ", "")));
                        }
                    }

                    var tbItem = ParserHandler.FindAnyTableOrBufferByName(data.DisplayText);
                    if (tbItem != null)
                    {
                        if (!string.IsNullOrEmpty(tbItem.Description))
                        {
                            toDisplay.Append(FormatRow("Description", tbItem.Description));
                        }

                        if (tbItem.Fields.Count > 0)
                        {
                            toDisplay.Append(FormatSubtitle("FIELDS [x" + tbItem.Fields.Count + "]"));
                            toDisplay.Append("<table width='100%;'>");
                            foreach (var parsedField in tbItem.Fields)
                            {
                                toDisplay.Append("<tr><td><img src='" + (parsedField.Flag.HasFlag(ParsedFieldFlag.Primary) ? CompletionType.FieldPk.ToString() : CompletionType.Field.ToString()) + "'></td><td style='padding-right: 4px'>" + (parsedField.Flag.HasFlag(ParsedFieldFlag.Mandatory) ? "<img src='Mandatory'>" : "") + "</td><td style='padding-right: 8px'>" + parsedField.Name + "</td><td style='padding-right: 8px'>" + parsedField.Type + "</td><td style='padding-right: 8px'> = " + (parsedField.Type == ParsedPrimitiveType.Character ? parsedField.InitialValue.ProQuoter() : parsedField.InitialValue) + "</td><td style='padding-right: 8px'>" + parsedField.Description + "</td></tr>");
                            }
                            toDisplay.Append("</table>");
                        }

                        if (tbItem.Triggers.Count > 0)
                        {
                            toDisplay.Append(FormatSubtitle("TRIGGERS [x" + tbItem.Triggers.Count + "]"));
                            foreach (var parsedTrigger in tbItem.Triggers)
                            {
                                toDisplay.Append(FormatRow(parsedTrigger.Event, "<a class='ToolGotoDefinition' href='trigger#" + parsedTrigger.ProcName + "'>" + parsedTrigger.ProcName + "</a>"));
                            }
                        }

                        if (tbItem.Indexes.Count > 0)
                        {
                            toDisplay.Append(FormatSubtitle("INDEXES [x" + tbItem.Indexes.Count + "]"));
                            foreach (var parsedIndex in tbItem.Indexes)
                            {
                                toDisplay.Append(FormatRow(parsedIndex.Name, ((parsedIndex.Flag != ParsedIndexFlag.None) ? parsedIndex.Flag + " - " : "") + parsedIndex.FieldsList.Aggregate((i, j) => i + ", " + j)));
                            }
                        }
                    }
                    break;

                case CompletionType.Sequence:
                    toDisplay.Append(FormatRow("Database logical name", data.SubString));
                    break;

                case CompletionType.Database:
                    var dbItem = DataBase.GetDb(data.DisplayText);

                    toDisplay.Append(FormatRow("Logical name", dbItem.LogicalName));
                    toDisplay.Append(FormatRow("Physical name", dbItem.PhysicalName));
                    toDisplay.Append(FormatRow("Progress version", dbItem.ProgressVersion));
                    toDisplay.Append(FormatRow("Number of Tables", dbItem.Tables.Count.ToString()));
                    break;

                case CompletionType.Field:
                case CompletionType.FieldPk:
                    // find field
                    var fieldFound = DataBase.FindFieldByName(data.DisplayText, (ParsedTable)data.ParsedItem);
                    if (fieldFound != null)
                    {
                        if (fieldFound.AsLike == ParsedAsLike.Like)
                        {
                            toDisplay.Append(FormatRow("Is LIKE", fieldFound.TempType));
                        }
                        toDisplay.Append(FormatRow("Type", FormatSubString(data.SubString)));
                        toDisplay.Append(FormatRow("Owner table", ((ParsedTable)data.ParsedItem).Name));
                        if (!string.IsNullOrEmpty(fieldFound.Description))
                        {
                            toDisplay.Append(FormatRow("Description", fieldFound.Description));
                        }
                        if (!string.IsNullOrEmpty(fieldFound.Format))
                        {
                            toDisplay.Append(FormatRow("Format", fieldFound.Format));
                        }
                        if (!string.IsNullOrEmpty(fieldFound.InitialValue))
                        {
                            toDisplay.Append(FormatRow("Initial value", fieldFound.InitialValue));
                        }
                        toDisplay.Append(FormatRow("Order", fieldFound.Order.ToString()));
                    }

                    break;

                case CompletionType.Procedure:
                    // find its parameters
                    toDisplay.Append(FormatSubtitle("PARAMETERS"));
                    var paramList = ParserHandler.FindProcedureParameters(data);
                    if (paramList.Count > 0)
                    {
                        foreach (var parameter in paramList)
                        {
                            var defItem = (ParsedDefine)parameter.ParsedItem;
                            toDisplay.Append(FormatRowParam(defItem.LcFlagString, parameter.DisplayText + " as <span class='ToolTipSubString'>" + defItem.PrimitiveType + "</span>"));
                        }
                    }
                    else
                    {
                        toDisplay.Append("None");
                    }
                    break;

                case CompletionType.Function:
                    var funcItem = (ParsedFunction)data.ParsedItem;
                    toDisplay.Append(FormatSubtitle("RETURN TYPE"));
                    toDisplay.Append(FormatRowParam("output", "Returns " + FormatSubString(funcItem.ReturnType.ToString())));

                    toDisplay.Append(FormatSubtitle("PARAMETERS"));
                    var param2List = ParserHandler.FindProcedureParameters(data);
                    if (param2List.Count > 0)
                    {
                        foreach (var parameter in param2List)
                        {
                            var defItem = (ParsedDefine)parameter.ParsedItem;
                            toDisplay.Append(FormatRowParam(defItem.LcFlagString, parameter.DisplayText + " as " + FormatSubString(defItem.PrimitiveType.ToString())));
                        }
                    }
                    else
                    {
                        toDisplay.Append("None");
                    }

                    var funcImplem = data.ParsedItem as ParsedImplementation;
                    if (funcImplem != null)
                    {
                        toDisplay.Append(FormatSubtitle("PROTOTYPE"));
                        if (funcImplem.HasPrototype)
                        {
                            toDisplay.Append(FormatRowWithImg("Prototype", "<a class='ToolGotoDefinition' href='proto#" + funcItem.FilePath + "#" + funcImplem.PrototypeLine + "#" + funcImplem.PrototypeColumn + "'>Go to prototype</a>"));
                        }
                        else
                        {
                            toDisplay.Append("Has none");
                        }
                    }
                    else
                    {
                        toDisplay.Append(FormatSubtitle("DEFINED IN"));
                        toDisplay.Append("Function defined in an external procedure or is a web service operation");
                    }
                    break;

                case CompletionType.Keyword:
                case CompletionType.KeywordObject:
                    toDisplay.Append(FormatRow("Type of keyword", FormatSubString(data.SubString)));
                    // for abbreviations, find the complete keyword first
                    string keyword = data.DisplayText;
                    if (data.KeywordType == KeywordType.Abbreviation)
                    {
                        keyword = Keywords.GetFullKeyword(keyword);
                        var associatedKeyword = AutoComplete.FindInCompletionData(keyword, 0);
                        if (associatedKeyword != null && associatedKeyword.Count > 0)
                        {
                            data = associatedKeyword.First();
                        }
                    }
                    string keyToFind = null;
                    // for the keywords define and create, we try to match the second keyword that goes with it
                    if (data.KeywordType == KeywordType.Statement &&
                        (keyword.EqualsCi("define") || keyword.EqualsCi("create")))
                    {
                        var lineStr        = Npp.GetLine(Npp.LineFromPosition(Npp.GetPositionFromMouseLocation())).Text;
                        var listOfSecWords = new List <string> {
                            "ALIAS", "BROWSE", "BUFFER", "BUTTON", "CALL", "CLIENT-PRINCIPAL", "DATA-SOURCE", "DATABASE", "DATASET", "EVENT", "FRAME", "IMAGE", "MENU", "PARAMETER", "PROPERTY", "QUERY", "RECTANGLE", "SAX-ATTRIBUTES", "SAX-READER", "SAX-WRITER", "SERVER", "SERVER-SOCKET", "SOAP-HEADER", "SOAP-HEADER-ENTRYREF", "SOCKET", "STREAM", "SUB-MENU", "TEMP-TABLE", "VARIABLE", "WIDGET-POOL", "WORK-TABLE", "WORKFILE", "X-DOCUMENT", "X-NODEREF"
                        };
                        foreach (var word in listOfSecWords)
                        {
                            if (lineStr.ContainsFast(word))
                            {
                                keyToFind = string.Join(" ", keyword, word, data.SubString);
                                break;
                            }
                        }
                    }
                    if (keyToFind == null)
                    {
                        keyToFind = string.Join(" ", keyword, data.SubString);
                    }

                    var dataHelp = Keywords.GetKeywordHelp(keyToFind);
                    if (dataHelp != null)
                    {
                        toDisplay.Append(FormatSubtitle("DESCRIPTION"));
                        toDisplay.Append(dataHelp.Description);

                        // synthax
                        if (dataHelp.Synthax.Count >= 1 && !string.IsNullOrEmpty(dataHelp.Synthax[0]))
                        {
                            toDisplay.Append(FormatSubtitle("SYNTAX"));
                            toDisplay.Append(@"<div class='ToolTipcodeSnippet'>");
                            var i = 0;
                            foreach (var synthax in dataHelp.Synthax)
                            {
                                if (i > 0)
                                {
                                    toDisplay.Append(@"<br>");
                                }
                                toDisplay.Append(synthax);
                                i++;
                            }
                            toDisplay.Append(@"</div>");
                        }
                    }
                    else
                    {
                        toDisplay.Append(FormatSubtitle("404 NOT FOUND"));
                        if (data.KeywordType == KeywordType.Option)
                        {
                            toDisplay.Append("<i><b>Sorry, this keyword doesn't have any help associated</b><br>Since this keyword is an option, try to hover the first keyword of the statement or refer to the 4GL help</i>");
                        }
                        else
                        {
                            toDisplay.Append("<i><b>Sorry, this keyword doesn't have any help associated</b><br>Please refer to the 4GL help</i>");
                        }
                    }

                    CurrentWord = keyToFind;
                    break;

                case CompletionType.Label:
                    break;

                case CompletionType.Preprocessed:
                    var preprocItem = (ParsedPreProc)data.ParsedItem;
                    if (preprocItem.UndefinedLine > 0)
                    {
                        toDisplay.Append(FormatRow("Undefined line", preprocItem.UndefinedLine.ToString()));
                    }
                    toDisplay.Append(FormatSubtitle("VALUE"));
                    toDisplay.Append(@"<div class='ToolTipcodeSnippet'>");
                    toDisplay.Append(preprocItem.Value);
                    toDisplay.Append(@"</div>");
                    break;

                case CompletionType.Snippet:
                    // TODO
                    break;

                case CompletionType.VariableComplex:
                case CompletionType.VariablePrimitive:
                case CompletionType.Widget:
                    var varItem = (ParsedDefine)data.ParsedItem;
                    toDisplay.Append(FormatRow("Define type", FormatSubString(varItem.Type.ToString())));
                    if (!string.IsNullOrEmpty(varItem.TempPrimitiveType))
                    {
                        toDisplay.Append(FormatRow("Variable type", FormatSubString(varItem.PrimitiveType.ToString())));
                    }
                    if (varItem.AsLike == ParsedAsLike.Like)
                    {
                        toDisplay.Append(FormatRow("Is LIKE", varItem.TempPrimitiveType));
                    }
                    if (!string.IsNullOrEmpty(varItem.ViewAs))
                    {
                        toDisplay.Append(FormatRow("Screen representation", varItem.ViewAs));
                    }
                    if (!string.IsNullOrEmpty(varItem.LcFlagString))
                    {
                        toDisplay.Append(FormatRow("Define flags", varItem.LcFlagString));
                    }
                    if (!string.IsNullOrEmpty(varItem.Left))
                    {
                        toDisplay.Append(FormatSubtitle("END OF DECLARATION"));
                        toDisplay.Append(@"<div class='ToolTipcodeSnippet'>");
                        toDisplay.Append(varItem.Left);
                        toDisplay.Append(@"</div>");
                    }
                    break;
                }
            } catch (Exception e) {
                toDisplay.Append("Error when appending info :<br>" + e + "<br>");
            }

            // parsed item?
            if (data.FromParser)
            {
                toDisplay.Append(FormatSubtitle("ORIGINS"));
                toDisplay.Append(FormatRow("Scope name", data.ParsedItem.Scope.Name));
                if (!Plug.CurrentFilePath.Equals(data.ParsedItem.FilePath))
                {
                    toDisplay.Append(FormatRow("Owner file", "<a class='ToolGotoDefinition' href='gotoownerfile#" + data.ParsedItem.FilePath + "'>" + data.ParsedItem.FilePath + "</a>"));
                }
            }

            // Flags
            var flagStrBuilder = new StringBuilder();

            data.DoForEachFlag((name, flag) => {
                flagStrBuilder.Append(FormatRowWithImg(name, "<b>" + name + "</b>"));
            });
            if (flagStrBuilder.Length > 0)
            {
                toDisplay.Append(FormatSubtitle("FLAGS"));
                toDisplay.Append(flagStrBuilder);
            }


            toDisplay.Append(@"<div class='ToolTipBottomGoTo'>
                [HIT CTRL ONCE] Prevent auto-close");
            // parsed item?
            if (data.FromParser)
            {
                toDisplay.Append(@"<br>[" + Config.Instance.GetShortcutSpecFromName("Go_To_Definition").ToUpper() + "] <a class='ToolGotoDefinition' href='gotodefinition'>Go to definition</a>");
                GoToDefinitionPoint = new Point(data.ParsedItem.Line, data.ParsedItem.Column);
                GoToDefinitionFile  = data.ParsedItem.FilePath;
            }
            if (_currentCompletionList.Count > 1)
            {
                toDisplay.Append("<br>[CTRL + <span class='ToolTipDownArrow'>" + (char)242 + "</span>] <a class='ToolGotoDefinition' href='nexttooltip'>Read next tooltip</a>");
            }
            toDisplay.Append("</div>");

            toDisplay.Append("</div>");

            _form.SetText(toDisplay.ToString(), popupMinWidth);
        }
Beispiel #4
0
        /// <summary>
        /// Updates the CURRENT ITEMS LIST,
        /// handles the opening or the closing of the autocompletion form on key input,
        /// it is only called when the user adds or delete a char
        /// </summary>
        public static void UpdateAutocompletion()
        {
            if (!Config.Instance.AutoCompleteOnKeyInputShowSuggestions && !_openedFromShortCut)
            {
                return;
            }

            // dont show in string/comments..?
            if (!_openedFromShortCut && !IsVisible && !Config.Instance.AutoCompleteShowInCommentsAndStrings && !Style.IsCarretInNormalContext(Npp.CurrentPosition))
            {
                return;
            }

            // get current word, current previous word (table or database name)
            int    nbPoints;
            string previousWord       = "";
            var    strOnLeft          = Npp.GetTextOnLeftOfPos(Npp.CurrentPosition);
            var    keyword            = Abl.ReadAblWord(strOnLeft, false, out nbPoints);
            var    splitted           = keyword.Split('.');
            string lastCharBeforeWord = "";

            switch (nbPoints)
            {
            case 0:
                int startPos = strOnLeft.Length - 1 - keyword.Length;
                lastCharBeforeWord = startPos >= 0 ? strOnLeft.Substring(startPos, 1) : String.Empty;
                break;

            case 1:
                previousWord = splitted[0];
                keyword      = splitted[1];
                break;

            case 2:
                previousWord = splitted[1];
                keyword      = splitted[2];
                break;

            default:
                keyword = splitted[nbPoints];
                break;
            }

            // list of fields or tables
            if (!string.IsNullOrEmpty(previousWord))
            {
                // are we entering a field from a known table?
                var foundTable = ParserHandler.FindAnyTableOrBufferByName(previousWord);
                if (foundTable != null)
                {
                    if (CurrentTypeOfList != TypeOfList.Fields)
                    {
                        CurrentTypeOfList = TypeOfList.Fields;
                        SetCurrentItems(DataBase.GetFieldsList(foundTable).ToList());
                    }
                    ShowSuggestionList(keyword);
                    return;
                }

                // are we entering a table from a connected database?
                var foundDatabase = DataBase.FindDatabaseByName(previousWord);
                if (foundDatabase != null)
                {
                    if (CurrentTypeOfList != TypeOfList.Tables)
                    {
                        CurrentTypeOfList = TypeOfList.Tables;
                        SetCurrentItems(DataBase.GetTablesList(foundDatabase).ToList());
                    }
                    ShowSuggestionList(keyword);
                    return;
                }
            }

            // close if there is nothing to suggest
            if ((!_openedFromShortCut || _openedFromShortCutPosition != Npp.CurrentPosition) && (String.IsNullOrEmpty(keyword) || keyword != null && keyword.Length < Config.Instance.AutoCompleteStartShowingListAfterXChar))
            {
                Close();
                return;
            }

            // if the current is directly preceded by a :, we are entering an object field/method
            if (lastCharBeforeWord.Equals(":"))
            {
                if (CurrentTypeOfList != TypeOfList.KeywordObject)
                {
                    CurrentTypeOfList = TypeOfList.KeywordObject;
                    SetCurrentItems(SavedAllItems);
                }
                ShowSuggestionList(keyword);
                return;
            }

            // show normal complete list
            if (CurrentTypeOfList != TypeOfList.Complete)
            {
                CurrentTypeOfList = TypeOfList.Complete;
                SetCurrentItems(SavedAllItems);
            }
            ShowSuggestionList(keyword);
        }