From d9ac6d640165a2c86d7eedca49d6988ee61b617d Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Tue, 19 Jul 2016 21:07:06 -0700 Subject: [PATCH 1/2] Implementing Write-Progress using SetBufferContents --- .../host/msh/ConsoleHostRawUserInterface.cs | 88 ++++++++++++++++++- .../host/msh/ProgressPane.cs | 31 +++++-- 2 files changed, 111 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostRawUserInterface.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostRawUserInterface.cs index 2c260fb47..b68523f3b 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostRawUserInterface.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostRawUserInterface.cs @@ -1711,7 +1711,44 @@ namespace Microsoft.PowerShell } } - /// + public void ScrollBuffer(int lines) + { + for (int i=0; i /// This API returns a rectangular region of the screen buffer. In /// this example this functionality is not needed so the method throws /// a NotImplementException exception. @@ -1760,7 +1797,54 @@ namespace Microsoft.PowerShell public override void SetBufferContents(Coordinates origin, BufferCell[,] contents) { - throw new NotImplementedException("The method or operation is not implemented."); + //if there are no contents, there is nothing to set the buffer to + if (contents == null) + { + PSTraceSource.NewArgumentNullException("contents"); + } + + //variables to traverse through the buffer + int cursorX = origin.X; + int cursorY = origin.Y; + + //if the cursor is on the last line, we need to make more space to print the specified buffer + if (cursorY == Console.BufferHeight -1 && cursorX >= Console.BufferWidth) + { + //for each row in the buffer, create a new line + int rows = contents.GetLength(0); + for (int i=0; i < rows; i++) + { + ScrollBuffer(1); + } + + //for each row in the buffer, move the cursor y up to the beginning of the created blank space + cursorY -= rows; + } + + //iterate through the buffer to set + foreach (var charitem in contents) + { + //set the cursor to false to prevent cursor flicker + Console.CursorVisible = false; + + //if x is exceeding buffer width, reset to the next line + if (cursorX >= Console.BufferWidth) + { + cursorX = 1; + } + + //write the character from contents + Console.Out.Write(charitem.Character); + + //advance the character one position + cursorX++; + } + + //reset the cursor to the original position + Console.SetCursorPosition(cursorX, cursorY); + //reset the cursor to visible + Console.CursorVisible = true; + } /// diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ProgressPane.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ProgressPane.cs index d213381d1..9d457a1a6 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ProgressPane.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ProgressPane.cs @@ -102,14 +102,33 @@ namespace Microsoft.PowerShell location.X = 0; location.Y = Math.Min(location.Y + 2, bufSize.Height); - // Save off the current contents of the screen buffer in the region that we will occupy - - savedRegion = - rawui.GetBufferContents( - new Rectangle(location.X, location.Y, location.X + cols - 1, location.Y + rows - 1)); + if (System.Management.Automation.Platform.IsWindows) + { + // Save off the current contents of the screen buffer in the region that we will occupy + savedRegion = + rawui.GetBufferContents( + new Rectangle(location.X, location.Y, location.X + cols - 1, location.Y + rows - 1)); + } + //Platform is either OSX or Linux + else + { + // replace the saved region in the screen buffer with our progress display + location.X = rawui.CursorPosition.X; + location.Y = rawui.CursorPosition.Y; + + //set the cursor position back to the beginning of the region to overwrite write-progress + //if the cursor is at the bottom, back it up to overwrite the previous write progress + if (location.Y >= Console.BufferHeight - rows) + { + Console.Out.Write('\n'); + location.Y -= rows; + } + + Console.SetCursorPosition(location.X, location.Y); + } + // replace the saved region in the screen buffer with our progress display - rawui.SetBufferContents(location, tempProgressRegion); } } From 17b4bb354c761284a514941dd74b1c5005bf8452 Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Tue, 19 Jul 2016 21:09:54 -0700 Subject: [PATCH 2/2] Changing description of SetBufferContents function --- .../host/msh/ConsoleHostRawUserInterface.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostRawUserInterface.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostRawUserInterface.cs index b68523f3b..24307ce22 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostRawUserInterface.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostRawUserInterface.cs @@ -1789,11 +1789,10 @@ namespace Microsoft.PowerShell /// /// This method copies an array of buffer cells into the screen buffer - /// at a specified location. In this example this functionality is - /// not needed so the method throws a NotImplementedException exception. + /// at a specified location. /// - /// The parameter is not used. - /// The parameter is not used. + /// The parameter used to set the origin where the buffer where begin writing to. + /// The parameter used to contain the contents to be written to the buffer. public override void SetBufferContents(Coordinates origin, BufferCell[,] contents) {