예제 #1
0
        /// <summary>
        /// This method checks if the current document contains function prototypes that are not updated
        /// and correct them if needed
        /// </summary>
        /// <remarks>This method is costly because we parse everything potentially X times, but it's much simpler this way...</remarks>
        public static void UpdateFunctionPrototypesIfNeeded(bool silent = false)
        {
            if (_ignoredFiles.Contains(Plug.CurrentFilePath) || Config.Instance.DisablePrototypeAutoUpdate)
            {
                if (silent)
                {
                    return;
                }
                _ignoredFiles.Remove(Plug.CurrentFilePath);
            }

            List <ParsedImplementation> listOfOutDatedProto;
            List <ParsedImplementation> listOfSoloImplementation;
            List <ParsedPrototype>      listOfUselessProto;

            StringBuilder outputMessage = new StringBuilder();

            var nbLoop       = 0;
            var nbNotCreated = 0;
            var nbThingsDone = 0;
            var nbToDo       = GetPrototypesLists(out listOfOutDatedProto, out listOfSoloImplementation, out listOfUselessProto);

            // if there is at least 1 thing to do
            if (nbToDo > 0)
            {
                Npp.BeginUndoAction();

                // Add proto
                if (listOfSoloImplementation.Count > 0)
                {
                    var tempMes = new StringBuilder("The following function prototypes have been created :");

                    while (listOfSoloImplementation.Count > nbNotCreated && nbLoop <= nbToDo)
                    {
                        if (AddPrototypes(ref tempMes, listOfSoloImplementation[nbNotCreated]))
                        {
                            nbThingsDone++;
                        }
                        else
                        {
                            nbNotCreated++;
                        }

                        GetPrototypesLists(out listOfOutDatedProto, out listOfSoloImplementation, out listOfUselessProto);
                        nbLoop++;
                    }
                    tempMes.Append("<br><br>");
                    if (nbThingsDone > 0)
                    {
                        outputMessage.Append(tempMes);
                    }
                }

                // delete proto
                if (listOfUselessProto.Count > 0)
                {
                    outputMessage.Append("The following prototypes have been deleted :");
                    while (listOfUselessProto.Count > 0 && nbLoop <= nbToDo)
                    {
                        if (DeletePrototypes(ref outputMessage, listOfUselessProto[0]))
                        {
                            nbThingsDone++;
                        }

                        GetPrototypesLists(out listOfOutDatedProto, out listOfSoloImplementation, out listOfUselessProto);
                        nbLoop++;
                    }
                    outputMessage.Append("<br><br>");
                }

                // update proto
                if (listOfOutDatedProto.Count > 0 && nbLoop <= nbToDo)
                {
                    outputMessage.Append("The following functions have had their prototype synchronized :");
                    while (listOfOutDatedProto.Count > 0)
                    {
                        if (UpdatePrototypes(ref outputMessage, listOfOutDatedProto[0]))
                        {
                            nbThingsDone++;
                        }

                        GetPrototypesLists(out listOfOutDatedProto, out listOfSoloImplementation, out listOfUselessProto);
                        nbLoop++;
                    }
                    outputMessage.Append("<br><br>");
                }

                Npp.EndUndoAction();
            }

            if (nbThingsDone == 0)
            {
                if (!silent)
                {
                    if (nbNotCreated == 0)
                    {
                        UserCommunication.Notify("There was nothing to be done :<br>All the prototypes match their implementation", MessageImg.MsgInfo, "Function prototypes", "Everything is synchronized", 5);
                    }
                    else
                    {
                        UserCommunication.Notify("Failed to find the prototype for " + nbNotCreated + " function implementations<br>Your document is not correctly formatted for 3P to automatically create them :<br><i>The block _UIB-PREPROCESSOR-BLOCK is missing or the procedure can't be opened in the appbuilder!</i><br><br>Please correct your document manually, then they will all be updated correctly" + ProCodeFormat.GetParserErrorDescription(), MessageImg.MsgHighImportance, "Function prototypes", "Failed to create prototypes");
                    }
                }
            }
            else
            {
                outputMessage.Append("<i>");
                outputMessage.Append("CTRL + Z will cancel the above-mentionned modifications<br>");
                outputMessage.Append(Plug.CurrentFilePath.ToHtmlLink("Click here to stop auto-updating the prototypes for this file"));
                outputMessage.Append("</i>");
                UserCommunication.NotifyUnique("Prototype_synchro", outputMessage.ToString(), MessageImg.MsgOk, "Function prototypes", "Synchronization done", args => {
                    var split = args.Link.Split('#');
                    if (split.Length == 2)
                    {
                        Npp.GotoPos(split[0], Int32.Parse(split[1]));
                        args.Handled = true;
                    }
                    else
                    {
                        if (!_ignoredFiles.Contains(args.Link))
                        {
                            _ignoredFiles.Add(args.Link);
                            UserCommunication.NotifyUnique("Prototype_synchro", "Automatic prototype updates stopped for the file :<br>" + Plug.CurrentFilePath + "<br><br><i>This is effective until you restart Notepad++<br>You can also trigger an update manually to restart the auto-update</i>", MessageImg.MsgInfo, "Function prototypes", "Synchronization stopped", null, 5);
                        }
                    }
                }, 5);
            }
        }
예제 #2
0
        /// <summary>
        /// Call this method to insert a new piece of code
        /// </summary>
        public static void InsertCode <T>() where T : ParsedScopeItem
        {
            IProCode codeCode;
            string   insertText;
            string   blockDescription;

            // in case of an incorrect document, warn the user
            if (ParserHandler.AblParser.ParserErrors.Count > 0)
            {
                if (UserCommunication.Message("The internal parser of 3P has found inconsistencies in your document :<br>" + ProCodeFormat.GetParserErrorDescription() + "<br>You can still insert a new piece of code but the insertion position might not be calculated correctly; take caution of what is generated if you decide to go through with it.", MessageImg.MsgQuestion, "Generate code", "Problems spotted", new List <string> {
                    "Continue", "Abort"
                }) != 0)
                {
                    return;
                }
            }

            if (typeof(ParsedImplementation) == typeof(T))
            {
                object input = new ProCodeFunction();
                if (UserCommunication.Input(ref input, "Please provide information about the procedure that will be created", MessageImg.MsgQuestion, "Generate code", "Insert a new function") != 0)
                {
                    return;
                }
                codeCode = (IProCode)input;

                blockDescription = @"_FUNCTION " + codeCode.Name + " Procedure";
                insertText       = Encoding.Default.GetString(DataResources.FunctionImplementation).Trim();
                insertText       = insertText.Replace("{&type}", ((ProCodeFunction)codeCode).Type);
                insertText       = insertText.Replace("{&private}", ((ProCodeFunction)codeCode).IsPrivate ? " PRIVATE" : "");
            }
            else if (typeof(ParsedProcedure) == typeof(T))
            {
                object input = new ProCodeProcedure();
                if (UserCommunication.Input(ref input, "Please provide information about the procedure that will be created", MessageImg.MsgQuestion, "Generate code", "Insert a new procedure") != 0)
                {
                    return;
                }
                codeCode = (IProCode)input;

                blockDescription = @"_PROCEDURE " + codeCode.Name + " Procedure";
                insertText       = Encoding.Default.GetString(DataResources.InternalProcedure).Trim();
                insertText       = insertText.Replace("{&private}", ((ProCodeProcedure)codeCode).IsPrivate ? " PRIVATE" : "");
            }
            else
            {
                return;
            }

            if (string.IsNullOrEmpty(codeCode.Name))
            {
                return;
            }

            // make sure to parse the current document before checking anything
            ParserHandler.ParseCurrentDocument(true, true);

            // check if the code already exists
            if (ParserHandler.AblParser.ParsedItemsList.Exists(item => item.GetType() == typeof(T) && item.Name.EqualsCi(codeCode.Name)))
            {
                UserCommunication.Notify("Sorry, this name is already taken by another existing instance", MessageImg.MsgHighImportance, "Invalid name", "Existing name", 5);
                return;
            }

            insertText = insertText.Replace("{&name}", codeCode.Name);

            // reposition caret and insert
            bool insertBefore;
            int  insertPos = GetCaretPositionForInsertion <T>(codeCode.Name, codeCode.InsertPosition, out insertBefore);

            if (insertPos < 0)
            {
                insertPos = Npp.GetPosFromLineColumn(Npp.Line.CurrentLine, 0);
            }

            insertText = FormatInsertion(insertText, blockDescription, insertBefore);
            int internalCaretPos = insertText.IndexOf("|||", StringComparison.Ordinal);

            insertText = insertText.Replace("|||", "");

            Npp.SetSelection(insertPos);
            Npp.ModifyTextAroundCaret(0, 0, insertText);

            Npp.GoToLine(Npp.LineFromPosition(insertPos));
            Npp.GotoPosition(insertPos + (internalCaretPos > 0 ? internalCaretPos : 0));

            // in the case of a new function, create the prototype if needed
            if (typeof(ParsedImplementation) == typeof(T))
            {
                UpdateFunctionPrototypesIfNeeded(true);
            }
        }