/// <summary> /// Tries to re-indent the code of the whole document /// </summary> public static void CorrectCodeIndentation() { // handle spam (1s min between 2 indent) if (Utils.IsSpamming("CorrectCodeIndentation", 1000)) { return; } var parser = new Parser.Parser(Sci.Text, Npp.CurrentFile.Path, null, false); // in case of an incorrect document, warn the user var parserErrors = parser.ParseErrorsInHtml; if (!string.IsNullOrEmpty(parserErrors)) { if (UserCommunication.Message("The internal parser of 3P has found inconsistencies in your document :<br>" + parserErrors + "<br>You can still try to format your code but the result is not guaranteed (worst case scenario you can press CTRL+Z).<br>Please confirm that you want to proceed", MessageImg.MsgQuestion, "Correct indentation", "Problems spotted", new List <string> { "Continue", "Abort" }) != 0) { return; } } var linesLogFile = Path.Combine(Config.FolderTemp, "lines.log"); var canIndentSafely = string.IsNullOrEmpty(parserErrors); // start indenting Sci.BeginUndoAction(); StringBuilder x = new StringBuilder(); var indentWidth = Sci.TabWidth; var i = 0; var dic = parser.LineInfo; while (dic.ContainsKey(i)) { Sci.GetLine(i).Indentation = dic[i].BlockDepth * indentWidth; if (!canIndentSafely) { x.AppendLine(i + 1 + " > " + dic[i].BlockDepth + " , " + dic[i].Scope.ScopeType + " , " + dic[i].Scope.Name); } i++; } Sci.EndUndoAction(); // if we didn't parse the code correctly or if there are grammar errors if (!canIndentSafely) { Utils.FileWriteAllText(linesLogFile, x.ToString()); UserCommunication.Notify("If the code compiles successfully and the document is incorrectly formatted, please make sure to create an issue on the project's github and (if possible) include the incriminating code so i can fix this problem : <br>" + Config.IssueUrl.ToHtmlLink() + (Config.IsDevelopper ? "<br><br>Lines report log :<br>" + linesLogFile.ToHtmlLink() : ""), MessageImg.MsgRip, "Correct indentation", "Incorrect grammar", null, 10); } }
private static void CommonTagAction(Action <FileTagObject> performAction) { var filename = Npp.CurrentFile.FileName; if (Contains(filename)) { var fileInfo = GetLastFileTag(filename); Sci.BeginUndoAction(); performAction(fileInfo); Sci.EndUndoAction(); } else { UserCommunication.Notify("No info available for this file, please fill the file info form first!", MessageImg.MsgToolTip, "Insert modification tags", "No info available", 4); Appli.Appli.GoToPage(PageNames.FileInfo); } }
/// <summary> /// Tries to re-indent the code of the whole document /// </summary> public static void CorrectCodeIndentation() { // handle spam (1s min between 2 indent) if (Utils.IsSpamming("CorrectCodeIndentation", 1000)) { return; } var parser = new Parser.Pro.Parse.Parser(Sci.Text, Npp.CurrentFileInfo.Path, null, false); // in case of an incorrect document, warn the user var parserErrors = parser.ParseErrorsInHtml; if (!string.IsNullOrEmpty(parserErrors)) { if (UserCommunication.Message("The internal parser of 3P has found inconsistencies in your document :<br>" + parserErrors + "<br>You can still try to format your code but the result is not guaranteed (worst case scenario you can press CTRL+Z).<br>If the code compiles successfully and the document is incorrectly formatted, please make sure to create an issue on the project's github and (if possible) include the incriminating code so i can fix this problem : <br>" + Config.UrlIssues.ToHtmlLink() + "<br><br>Please confirm that you want to proceed", MessageImg.MsgQuestion, "Correct indentation", "Problems spotted", new List <string> { "Continue", "Abort" }) != 0) { return; } } // start indenting Sci.BeginUndoAction(); var indentStartLine = Sci.LineFromPosition(Sci.SelectionStart); var indentEndLine = Sci.LineFromPosition(Sci.SelectionEnd); var indentWidth = Sci.TabWidth; var i = 0; var dic = GetIndentation(parser.LineInfo); while (dic.ContainsKey(i)) { if (indentStartLine == indentEndLine || (i >= indentStartLine && i <= indentEndLine)) { var line = Sci.GetLine(i); line.Indentation = (dic[i].BlockDepth + dic[i].ExtraStatementDepth) * indentWidth; } i++; } Sci.EndUndoAction(); }
/// <summary> /// If no selection, comment the line of the caret /// If selection, comment the selection as a block /// </summary> public static void ToggleComment() { Sci.BeginUndoAction(); // for each selection (limit selection number) for (var i = 0; i < Sci.Selection.Count; i++) { var selection = Sci.GetSelection(i); int startPos; int endPos; bool singleLineComm = false; if (selection.Caret == selection.Anchor) { // comment line var thisLine = new Sci.Line(Sci.LineFromPosition(selection.Caret)); startPos = thisLine.IndentationPosition; endPos = thisLine.EndPosition; singleLineComm = true; } else { startPos = selection.Start; endPos = selection.End; } var toggleMode = ToggleCommentOnRange(startPos, endPos); if (toggleMode == 3) { selection.SetPosition(startPos + 3); } // correct selection... if (!singleLineComm && toggleMode == 2) { selection.End += 2; } } Sci.EndUndoAction(); }
/// <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> private void UpdateFunctionPrototypes(bool silent) { try { 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) { Sci.BeginUndoAction(); // Add proto if (listOfSoloImplementation.Count > 0 && string.IsNullOrEmpty(_parser.ParseErrorsInHtml)) { 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++; } ParseNow(); 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++; } ParseNow(); GetPrototypesLists(out listOfOutDatedProto, out listOfSoloImplementation, out listOfUselessProto); nbLoop++; } outputMessage.Append("<br><br>"); } // update proto if (listOfOutDatedProto.Count > 0) { outputMessage.Append("The following functions have had their prototype synchronized :"); while (listOfOutDatedProto.Count > 0 && nbLoop < nbToDo) { if (UpdatePrototypes(ref outputMessage, listOfOutDatedProto[0])) { nbThingsDone++; } ParseNow(); GetPrototypesLists(out listOfOutDatedProto, out listOfSoloImplementation, out listOfUselessProto); nbLoop++; } outputMessage.Append("<br><br>"); } Sci.EndUndoAction(); } if (nbThingsDone == 0) { if (!silent) { if (nbToDo == 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" + _parser.ParseErrorsInHtml, MessageImg.MsgHighImportance, "Function prototypes", "Failed to create prototypes"); } } } else { outputMessage.Append("<i>"); outputMessage.Append("CTRL + Z will cancel the above-mentioned modifications<br>"); outputMessage.Append(Npp.CurrentFileInfo.Path.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], int.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>" + Npp.CurrentFileInfo.Path + "<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); args.Handled = true; } } }, 5); } } catch (Exception e) { ErrorHandler.ShowErrors(e, "Error updating prototypes"); } }