Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cherry Pick: Fix console errors (#457) #469

Merged
merged 1 commit into from
Jan 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/Microsoft.Repl/Commanding/DefaultCommandDispatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public IReadOnlyList<string> CollectSuggestions(IShellState shellState)
shellState = shellState ?? throw new ArgumentNullException(nameof(shellState));

string line = shellState.InputManager.GetCurrentBuffer();
TParseResult parseResult = _parser.Parse(line, shellState.ConsoleManager.CaretPosition);
TParseResult parseResult = _parser.Parse(line, shellState.InputManager.CaretPosition);
HashSet<string> suggestions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

foreach (ICommand<TProgramState, TParseResult> command in _commands)
Expand Down Expand Up @@ -139,7 +139,7 @@ public async Task ExecuteCommandAsync(IShellState shellState, CancellationToken
private async Task ExecuteCommandInternalAsync(IShellState shellState, CancellationToken cancellationToken)
{
string line = shellState.InputManager.GetCurrentBuffer();
TParseResult parseResult = _parser.Parse(line, shellState.ConsoleManager.CaretPosition);
TParseResult parseResult = _parser.Parse(line, shellState.InputManager.CaretPosition);

if (!string.IsNullOrWhiteSpace(parseResult.CommandText))
{
Expand Down Expand Up @@ -171,7 +171,7 @@ public void OnReady(IShellState shellState)
if (!_isReady && !shellState.IsExiting)
{
_onReady(shellState);
shellState.ConsoleManager.ResetCommandStart();
shellState.InputManager.ResetInput();
_isReady = true;
}
}
Expand Down
159 changes: 56 additions & 103 deletions src/Microsoft.Repl/ConsoleHandling/ConsoleManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,6 @@ public class ConsoleManager : IConsoleManager

public Point Caret => new Point(Console.CursorLeft, Console.CursorTop);

public Point CommandStart
{
get
{
Point c = Caret;
return new Point(c.X - CaretPosition % Console.BufferWidth, c.Y - CaretPosition / Console.BufferWidth);
}
}

public int CaretPosition { get; private set; }

public bool IsKeyAvailable => Console.KeyAvailable;

public bool IsCaretVisible
Expand All @@ -35,95 +24,88 @@ public bool IsCaretVisible

public ConsoleManager()
{
Error = new Writable(CaretUpdateScope, Reporter.Error);
Error = new Writable(Reporter.Error);
Console.CancelKeyPress += OnCancelKeyPress;
}

public void Clear()
{
using (CaretUpdateScope())
{
Console.Clear();
ResetCommandStart();
}
Console.Clear();
}

public void MoveCaret(int positions)
{
using (CaretUpdateScope())
if (positions == 0)
{
if (positions == 0)
{
return;
}
return;
}

int bufferWidth = Console.BufferWidth;
int cursorTop = Console.CursorTop;
int cursorLeft = Console.CursorLeft;
int bufferWidth = Console.BufferWidth;
int cursorTop = Console.CursorTop;
int cursorLeft = Console.CursorLeft;

while (positions < 0 && CaretPosition > 0)
while (positions < 0)
{
if (-positions > bufferWidth)
{
if (-positions > bufferWidth)
if (cursorTop == 0)
{
if (cursorTop == 0)
{
cursorLeft = 0;
positions = 0;
}
else
{
positions += bufferWidth;
--cursorTop;
}
cursorLeft = 0;
positions = 0;
}
else
{
int remaining = cursorLeft + positions;

if (remaining >= 0)
{
cursorLeft = remaining;
}
else if (cursorTop == 0)
{
cursorLeft = 0;
}
else
{
--cursorTop;
cursorLeft = bufferWidth + remaining;
}
positions += bufferWidth;
--cursorTop;
}
}
else
{
int remaining = cursorLeft + positions;

positions = 0;
if (remaining >= 0)
{
cursorLeft = remaining;
}
else if (cursorTop == 0)
{
cursorLeft = 0;
}
else
{
--cursorTop;
cursorLeft = bufferWidth + remaining;
}

positions = 0;
}
}

while (positions > 0)
while (positions > 0)
{
if (positions > bufferWidth)
{
positions -= bufferWidth;
++cursorTop;
}
else
{
if (positions > bufferWidth)
int spaceLeftOnLine = bufferWidth - cursorLeft - 1;
if (positions > spaceLeftOnLine)
{
positions -= bufferWidth;
++cursorTop;
cursorLeft = positions - spaceLeftOnLine - 1;
}
else
{
int spaceLeftOnLine = bufferWidth - cursorLeft - 1;
if (positions > spaceLeftOnLine)
{
++cursorTop;
cursorLeft = positions - spaceLeftOnLine - 1;
}
else
{
cursorLeft += positions;
}

positions = 0;
cursorLeft += positions;
}
}

Console.SetCursorPosition(cursorLeft, cursorTop);
positions = 0;
}
}

Console.SetCursorPosition(cursorLeft, cursorTop);
}

public ConsoleKeyInfo ReadKey(CancellationToken cancellationToken)
Expand All @@ -143,33 +125,19 @@ public ConsoleKeyInfo ReadKey(CancellationToken cancellationToken)
}
}

public void ResetCommandStart()
{
CaretPosition = 0;
}

public void Write(char c)
{
using (CaretUpdateScope())
{
Reporter.Output.Write(c);
}
Reporter.Output.Write(c);
}

public void Write(string s)
{
using (CaretUpdateScope())
{
Reporter.Output.Write(s);
}
Reporter.Output.Write(s);
}

public void WriteLine()
{
using (CaretUpdateScope())
{
Reporter.Output.WriteLine();
}
Reporter.Output.WriteLine();
}

public void WriteLine(string s)
Expand All @@ -179,10 +147,7 @@ public void WriteLine(string s)
return;
}

using (CaretUpdateScope())
{
Reporter.Output.WriteLine(s);
}
Reporter.Output.WriteLine(s);
}

public IDisposable AddBreakHandler(Action onBreak)
Expand All @@ -192,18 +157,6 @@ public IDisposable AddBreakHandler(Action onBreak)
return result;
}

private IDisposable CaretUpdateScope()
{
Point currentCaret = Caret;
return new Disposable(() =>
{
Point c = Caret;
int y = c.Y - currentCaret.Y;
int x = c.X - currentCaret.X;
CaretPosition += y * Console.BufferWidth + x;
});
}

private void OnCancelKeyPress(object sender, ConsoleCancelEventArgs e)
{
e.Cancel = true;
Expand Down
6 changes: 0 additions & 6 deletions src/Microsoft.Repl/ConsoleHandling/IConsoleManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ public interface IConsoleManager : IWritable
{
Point Caret { get; }

Point CommandStart { get; }

int CaretPosition { get; }

#pragma warning disable CA1716 // Identifiers should not match keywords
IWritable Error { get; }
#pragma warning restore CA1716 // Identifiers should not match keywords
Expand All @@ -26,8 +22,6 @@ public interface IConsoleManager : IWritable

ConsoleKeyInfo ReadKey(CancellationToken cancellationToken);

void ResetCommandStart();

IDisposable AddBreakHandler(Action onBreak);

bool AllowOutputRedirection { get; }
Expand Down
26 changes: 5 additions & 21 deletions src/Microsoft.Repl/ConsoleHandling/Writable.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;

namespace Microsoft.Repl.ConsoleHandling
{
internal class Writable : IWritable
{
private readonly Func<IDisposable> _caretUpdater;
private readonly Reporter _reporter;

public Writable(Func<IDisposable> caretUpdater, Reporter reporter)
public Writable(Reporter reporter)
{
_caretUpdater = caretUpdater;
_reporter = reporter;
}

Expand All @@ -24,34 +20,22 @@ public bool IsCaretVisible

public void Write(char c)
{
using (_caretUpdater())
{
_reporter.Write(c);
}
_reporter.Write(c);
}

public void Write(string s)
{
using (_caretUpdater())
{
_reporter.Write(s);
}
_reporter.Write(s);
}

public void WriteLine()
{
using (_caretUpdater())
{
_reporter.WriteLine();
}
_reporter.WriteLine();
}

public void WriteLine(string s)
{
using (_caretUpdater())
{
_reporter.WriteLine(s);
}
_reporter.WriteLine(s);
}
}
}
2 changes: 2 additions & 0 deletions src/Microsoft.Repl/IShellState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,7 @@ public interface IShellState
ISuggestionManager SuggestionManager { get; }

bool IsExiting { get; set; }

void MoveCarets(int positions);
}
}
4 changes: 4 additions & 0 deletions src/Microsoft.Repl/Input/IInputManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public interface IInputManager
{
bool IsOverwriteMode { get; set; }

int CaretPosition { get; }

IInputManager RegisterKeyHandler(ConsoleKey key, AsyncKeyPressHandler handler);

IInputManager RegisterKeyHandler(ConsoleKey key, ConsoleModifiers modifiers, AsyncKeyPressHandler handler);
Expand All @@ -28,5 +30,7 @@ public interface IInputManager
void RemoveCurrentCharacter(IShellState state);

void Clear(IShellState state);

void MoveCaret(int positions);
}
}
Loading