Beispiel #1
0
        /// <summary>
        /// Applies the provided FileChange to the file's contents
        /// </summary>
        /// <param name="fileChange">The FileChange to apply to the file's contents.</param>
        public void ApplyChange(FileChange fileChange)
        {
            // TODO: Verify offsets are in range

            // Break up the change lines
            string[] changeLines = fileChange.InsertString.Split('\n');

            // Get the first fragment of the first line
            string firstLineFragment =
                this.FileLines[fileChange.Line - 1]
                .Substring(0, fileChange.Offset - 1);

            // Get the last fragment of the last line
            string endLine          = this.FileLines[fileChange.EndLine - 1];
            string lastLineFragment =
                endLine.Substring(
                    fileChange.EndOffset - 1,
                    (this.FileLines[fileChange.EndLine - 1].Length - fileChange.EndOffset) + 1);

            // Remove the old lines
            for (int i = 0; i <= fileChange.EndLine - fileChange.Line; i++)
            {
                this.FileLines.RemoveAt(fileChange.Line - 1);
            }

            // Build and insert the new lines
            int currentLineNumber = fileChange.Line;

            for (int changeIndex = 0; changeIndex < changeLines.Length; changeIndex++)
            {
                // Since we split the lines above using \n, make sure to
                // trim the ending \r's off as well.
                string finalLine = changeLines[changeIndex].TrimEnd('\r');

                // Should we add first or last line fragments?
                if (changeIndex == 0)
                {
                    // Append the first line fragment
                    finalLine = firstLineFragment + finalLine;
                }
                if (changeIndex == changeLines.Length - 1)
                {
                    // Append the last line fragment
                    finalLine = finalLine + lastLineFragment;
                }

                this.FileLines.Insert(currentLineNumber - 1, finalLine);
                currentLineNumber++;
            }

            // Parse the script again to be up-to-date
            this.ParseFileContents();
        }
Beispiel #2
0
        /// <summary>
        /// Applies the provided FileChange to the file's contents
        /// </summary>
        /// <param name="fileChange">The FileChange to apply to the file's contents.</param>
        public void ApplyChange(FileChange fileChange)
        {
            // Break up the change lines
            string[] changeLines = fileChange.InsertString.Split('\n');

            if (fileChange.IsReload)
            {
                this.FileLines.Clear();
                foreach (var changeLine in changeLines)
                {
                    this.FileLines.Add(changeLine);
                }
            }
            else
            {
                // VSCode sometimes likes to give the change start line as (FileLines.Count + 1).
                // This used to crash EditorServices, but we now treat it as an append.
                // See https://github.com/PowerShell/vscode-powershell/issues/1283
                if (fileChange.Line == this.FileLines.Count + 1)
                {
                    foreach (string addedLine in changeLines)
                    {
                        string finalLine = addedLine.TrimEnd('\r');
                        this.FileLines.Add(finalLine);
                    }
                }
                // Similarly, when lines are deleted from the end of the file,
                // VSCode likes to give the end line as (FileLines.Count + 1).
                else if (fileChange.EndLine == this.FileLines.Count + 1 && String.Empty.Equals(fileChange.InsertString))
                {
                    int lineIndex = fileChange.Line - 1;
                    this.FileLines.RemoveRange(lineIndex, this.FileLines.Count - lineIndex);
                }
                // Otherwise, the change needs to go between existing content
                else
                {
                    this.ValidatePosition(fileChange.Line, fileChange.Offset);
                    this.ValidatePosition(fileChange.EndLine, fileChange.EndOffset);

                    // Get the first fragment of the first line
                    string firstLineFragment =
                        this.FileLines[fileChange.Line - 1]
                        .Substring(0, fileChange.Offset - 1);

                    // Get the last fragment of the last line
                    string endLine          = this.FileLines[fileChange.EndLine - 1];
                    string lastLineFragment =
                        endLine.Substring(
                            fileChange.EndOffset - 1,
                            (this.FileLines[fileChange.EndLine - 1].Length - fileChange.EndOffset) + 1);

                    // Remove the old lines
                    for (int i = 0; i <= fileChange.EndLine - fileChange.Line; i++)
                    {
                        this.FileLines.RemoveAt(fileChange.Line - 1);
                    }

                    // Build and insert the new lines
                    int currentLineNumber = fileChange.Line;
                    for (int changeIndex = 0; changeIndex < changeLines.Length; changeIndex++)
                    {
                        // Since we split the lines above using \n, make sure to
                        // trim the ending \r's off as well.
                        string finalLine = changeLines[changeIndex].TrimEnd('\r');

                        // Should we add first or last line fragments?
                        if (changeIndex == 0)
                        {
                            // Append the first line fragment
                            finalLine = firstLineFragment + finalLine;
                        }
                        if (changeIndex == changeLines.Length - 1)
                        {
                            // Append the last line fragment
                            finalLine = finalLine + lastLineFragment;
                        }

                        this.FileLines.Insert(currentLineNumber - 1, finalLine);
                        currentLineNumber++;
                    }
                }
            }

            // Parse the script again to be up-to-date
            this.ParseFileContents();
        }
        private void AssertFileChange(
            string initialString,
            string expectedString,
            FileChange fileChange)
        {
            using (StringReader stringReader = new StringReader(initialString))
            {
                // Create an in-memory file from the StringReader
                ScriptFile fileToChange = new ScriptFile("TestFile.ps1", "TestFile.ps1", stringReader);

                // Apply the FileChange and assert the resulting contents
                fileToChange.ApplyChange(fileChange);
                Assert.Equal(expectedString, fileToChange.Contents);
            }
        }
        /// <summary>
        /// Applies the provided FileChange to the file's contents
        /// </summary>
        /// <param name="fileChange">The FileChange to apply to the file's contents.</param>
        public void ApplyChange(FileChange fileChange)
        {
            // TODO: Verify offsets are in range

            // Break up the change lines
            string[] changeLines = fileChange.InsertString.Split('\n');

            // Get the first fragment of the first line
            string firstLineFragment = 
                this.FileLines[fileChange.Line - 1]
                    .Substring(0, fileChange.Offset - 1);

            // Get the last fragment of the last line
            string endLine = this.FileLines[fileChange.EndLine - 1];
            string lastLineFragment = 
                endLine.Substring(
                    fileChange.EndOffset - 1, 
                    (this.FileLines[fileChange.EndLine - 1].Length - fileChange.EndOffset) + 1);

            // Remove the old lines
            for (int i = 0; i <= fileChange.EndLine - fileChange.Line; i++)
            {
                this.FileLines.RemoveAt(fileChange.Line - 1); 
            }

            // Build and insert the new lines
            int currentLineNumber = fileChange.Line;
            for (int changeIndex = 0; changeIndex < changeLines.Length; changeIndex++)
            {
                // Since we split the lines above using \n, make sure to
                // trim the ending \r's off as well.
                string finalLine = changeLines[changeIndex].TrimEnd('\r');

                // Should we add first or last line fragments?
                if (changeIndex == 0)
                {
                    // Append the first line fragment
                    finalLine = firstLineFragment + finalLine;
                }
                if (changeIndex == changeLines.Length - 1)
                {
                    // Append the last line fragment
                    finalLine = finalLine + lastLineFragment;
                }

                this.FileLines.Insert(currentLineNumber - 1, finalLine);
                currentLineNumber++;
            }

            // Parse the script again to be up-to-date
            this.ParseFileContents();
        }