public override void OnDidCloseTextDocument(DidCloseTextDocumentParams parameters) { Uri objUri = new Uri(parameters.textDocument.uri); if (objUri.IsFile) { typeCobolWorkspace.CloseSourceFile(objUri); // DEBUG information RemoteConsole.Log("Closed source file : " + objUri.LocalPath); } }
// -- Files synchronization : maintain a list of opened files, apply all updates to their content -- public override void OnDidOpenTextDocument(DidOpenTextDocumentParams parameters) { Uri objUri = new Uri(parameters.uri); if (objUri.IsFile) { string fileName = Path.GetFileName(objUri.LocalPath); typeCobolWorkspace.OpenSourceFile(fileName, parameters.text); // DEBUG information RemoteConsole.Log("Opened source file : " + fileName); } }
public override void OnDidCloseTextDocument(TextDocumentIdentifier parameters) { Uri objUri = new Uri(parameters.uri); if (objUri.IsFile) { string fileName = Path.GetFileName(objUri.LocalPath); typeCobolWorkspace.CloseSourceFile(fileName); // DEBUG information RemoteConsole.Log("Closed source file : " + fileName); } }
public override void OnDidOpenTextDocument(DidOpenTextDocumentParams parameters) { Uri objUri = new Uri(parameters.textDocument.uri); if (objUri.IsFile) { //Subscribe to diagnostics event typeCobolWorkspace.MissingCopiesEvent += MissingCopiesDetected; typeCobolWorkspace.DiagnosticsEvent += DiagnosticsDetected; typeCobolWorkspace.OpenSourceFile(objUri, parameters.text != null ? parameters.text : parameters.textDocument.text, Workspace.LsrTestOptions); // DEBUG information RemoteConsole.Log("Opened source file : " + objUri.LocalPath); } }
public override void OnDidChangeTextDocument(DidChangeTextDocumentParams parameters) { Uri objUri = new Uri(parameters.uri); if (objUri.IsFile) { string fileName = Path.GetFileName(objUri.LocalPath); var fileCompiler = typeCobolWorkspace.OpenedFileCompilers[fileName]; #region Convert text changes format from multiline range replacement to single line updates // THIS CONVERSION STILL NEEDS MORE WORK : much more complicated than you would think TextChangedEvent textChangedEvent = new TextChangedEvent(); foreach (var contentChange in parameters.contentChanges) { // Split the text updated into distinct lines string[] lineUpdates = null; bool replacementTextStartsWithNewLine = false; if (contentChange.text != null && contentChange.text.Length > 0) { replacementTextStartsWithNewLine = contentChange.text[0] == '\r' || contentChange.text[0] == '\n'; lineUpdates = contentChange.text.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); } // Document cleared if (contentChange.range == null) { var textChange = new TextChange(TextChangeType.DocumentCleared, 0, null); textChangedEvent.TextChanges.Add(textChange); if (lineUpdates != null) { for (int i = 0; i < lineUpdates.Length; i++) { textChange = new TextChange(TextChangeType.LineInserted, i, new TextLineSnapshot(i, lineUpdates[i], null)); textChangedEvent.TextChanges.Add(textChange); } } } // Document updated else { // Check if the first line was inserted int firstLineIndex = contentChange.range.start.line; int firstLineChar = contentChange.range.start.character; if (replacementTextStartsWithNewLine) { firstLineIndex++; firstLineChar = 0; } // Check if the last line was deleted int lastLineIndex = contentChange.range.end.line; bool lastLineDeleted = false; if (contentChange.range.end.line > contentChange.range.start.line && contentChange.range.end.character == 0) { lastLineIndex--; lastLineDeleted = true; } if (!lastLineDeleted && contentChange.text.Length == 0) { lineUpdates = new string[0]; } // Get original lines text before change string originalFirstLineText = fileCompiler.CompilationResultsForProgram.CobolTextLines[contentChange.range.start.line].Text; string originalLastLineText = originalFirstLineText; if (lastLineIndex > firstLineIndex) { originalLastLineText = fileCompiler.CompilationResultsForProgram.CobolTextLines[lastLineIndex].Text; } // Text not modified at the beginning of the first replaced line string startOfFirstLine = null; if (firstLineChar > 0) { startOfFirstLine = originalFirstLineText.Substring(0, contentChange.range.start.character); } // Text not modified at the end of the last replaced line string endOfLastLine = null; if (!lastLineDeleted && contentChange.range.end.character < originalLastLineText.Length) { endOfLastLine = originalLastLineText.Substring(contentChange.range.end.character); } // Remove all the old lines for (int i = firstLineIndex; i <= lastLineIndex; i++) { var textChange = new TextChange(TextChangeType.LineRemoved, firstLineIndex, null); textChangedEvent.TextChanges.Add(textChange); } // Insert the updated lines if (!(startOfFirstLine == null && lineUpdates == null && endOfLastLine == null)) { int lineUpdatesCount = (lineUpdates != null && lineUpdates.Length > 0) ? lineUpdates.Length : 1; for (int i = 0; i < lineUpdatesCount; i++) { string newLine = (lineUpdates != null && lineUpdates.Length > 0) ? lineUpdates[i] : String.Empty; if (i == 0) { newLine = startOfFirstLine + newLine; } if (i == lineUpdatesCount - 1) { newLine = newLine + endOfLastLine; if (lastLineDeleted) { break; } } var textChange = new TextChange(TextChangeType.LineInserted, firstLineIndex + i, new TextLineSnapshot(firstLineIndex + i, newLine, null)); textChangedEvent.TextChanges.Add(textChange); } } } } #endregion // Update the source file with the computed text changes typeCobolWorkspace.UpdateSourceFile(fileName, textChangedEvent); // DEBUG information RemoteConsole.Log("Udpated source file : " + fileName); foreach (var textChange in textChangedEvent.TextChanges) { RemoteConsole.Log(" - " + textChange.ToString()); } } }
public override void OnDidChangeTextDocument(DidChangeTextDocumentParams parameters) { var fileCompiler = GetFileCompilerFromStringUri(parameters.uri, false); //Text Change do not have to trigger node phase, it's only a another event that will do it if (fileCompiler == null) { return; } Uri objUri = new Uri(parameters.uri); #region Convert text changes format from multiline range replacement to single line updates TextChangedEvent textChangedEvent = new TextChangedEvent(); foreach (var contentChange in parameters.contentChanges) { // Split the text updated into distinct lines List <string> lineUpdates = null; bool replacementTextStartsWithNewLine = false; if (!string.IsNullOrEmpty(contentChange.text)) { replacementTextStartsWithNewLine = contentChange.text[0] == '\r' || contentChange.text[0] == '\n'; //Allow to know if a new line was added //Split on \r \n to know the number of lines added lineUpdates = contentChange.text.Replace("\r", "").Split('\n').ToList(); if (string.IsNullOrEmpty(lineUpdates.FirstOrDefault()) && replacementTextStartsWithNewLine) { lineUpdates.RemoveAt(0); } } // Document cleared if (contentChange.range == null) { //JCM: I have noticed that if the entire text has changed, is better to reload the entire file //To avoid crashes. try { typeCobolWorkspace.OpenSourceFile(objUri, contentChange.text, this.Workspace.LsrTestOptions); return; } catch (Exception e) { //Don't rethow an exception on save. RemoteConsole.Error(string.Format("Error while handling notification {0} : {1}", "textDocument/didChange", e.Message)); return; } } // Document updated else { // Get original lines text before change string originalFirstLineText = fileCompiler.CompilationResultsForProgram.CobolTextLines[contentChange.range.start.line] .Text; string originalLastLineText = originalFirstLineText; // Check if the first line was inserted int firstLineIndex = contentChange.range.start.line; int firstLineChar = contentChange.range.start.character; if (replacementTextStartsWithNewLine && !(contentChange.range.start.character < originalLastLineText.Length)) { firstLineIndex++; firstLineChar = 0; } else if (replacementTextStartsWithNewLine) //Detected that the add line appeared inside an existing line { lineUpdates.Add(lineUpdates.First()); //Add the default 7 spaces + add lineUpdates in order to update the current line and add the new one. } // Check if the last line was deleted int lastLineIndex = contentChange.range.end.line; if (contentChange.range.end.line > contentChange.range.start.line && contentChange.range.end.character == 0) { //Allows to detect if the next line was suppressed } if (contentChange.text?.Length == 0) { lineUpdates = new List <string>(); } if (lastLineIndex > firstLineIndex) { originalLastLineText = fileCompiler.CompilationResultsForProgram.CobolTextLines[ Math.Min(lastLineIndex, fileCompiler.CompilationResultsForProgram.CobolTextLines.Count - 1)].Text; } // Text not modified at the beginning of the first replaced line string startOfFirstLine = null; if (firstLineChar > 0) { if (originalFirstLineText.Length >= contentChange.range.start.character) { startOfFirstLine = originalFirstLineText.Substring(0, contentChange.range.start.character); } else { startOfFirstLine = originalFirstLineText.Substring(0, originalFirstLineText.Length) + new string(' ', contentChange.range.start.character - originalFirstLineText.Length); } } // Text not modified at the end of the last replaced line string endOfLastLine = null; if (contentChange.range.end.character < originalLastLineText.Length) { endOfLastLine = originalLastLineText.Substring(contentChange.range.end.character); } // Remove all the old lines for (int i = firstLineIndex; i <= lastLineIndex; i++) { var textChange = new TextChange(TextChangeType.LineRemoved, firstLineIndex, null); textChangedEvent.TextChanges.Add(textChange); //Mark the index line to be removed. The index will remains the same for each line delete, because text change are apply one after another } // Insert the updated lines if (!(startOfFirstLine == null && lineUpdates == null && endOfLastLine == null)) { int lineUpdatesCount = (lineUpdates != null && lineUpdates.Count > 0) ? lineUpdates.Count : 1; for (int i = 0; i < lineUpdatesCount; i++) { string newLine = (lineUpdates != null && lineUpdates.Count > 0) ? lineUpdates[i] : string.Empty; if (i == 0) { newLine = startOfFirstLine + newLine; } if (i == lineUpdatesCount - 1) { newLine = newLine + endOfLastLine; } var textChange = new TextChange(TextChangeType.LineInserted, firstLineIndex + i, new TextLineSnapshot(firstLineIndex + i, newLine, null)); textChangedEvent.TextChanges.Add(textChange); } } } } #endregion // Update the source file with the computed text changes typeCobolWorkspace.UpdateSourceFile(objUri, textChangedEvent); // DEBUG information RemoteConsole.Log("Udpated source file : " + objUri.LocalPath); foreach (var textChange in textChangedEvent.TextChanges) { RemoteConsole.Log(" - " + textChange.ToString()); } }