mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-01 08:50:25 +01:00
Merge pull request #1364 from BDisp/textview-load-file
Fixes #1314. TextView now exposes file exceptions from callers.
This commit is contained in:
@@ -38,15 +38,10 @@ namespace Terminal.Gui {
|
||||
|
||||
public bool LoadFile (string file)
|
||||
{
|
||||
if (file == null)
|
||||
throw new ArgumentNullException (nameof (file));
|
||||
try {
|
||||
FilePath = file;
|
||||
var stream = File.OpenRead (file);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
LoadStream (File.OpenRead (file));
|
||||
FilePath = file ?? throw new ArgumentNullException (nameof (file));
|
||||
|
||||
var stream = File.OpenRead (file);
|
||||
LoadStream (stream);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -54,12 +49,9 @@ namespace Terminal.Gui {
|
||||
{
|
||||
if (FilePath == null)
|
||||
throw new ArgumentNullException (nameof (FilePath));
|
||||
try {
|
||||
FilePath = null;
|
||||
lines = new List<List<Rune>> ();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
FilePath = null;
|
||||
lines = new List<List<Rune>> ();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -79,14 +71,21 @@ namespace Terminal.Gui {
|
||||
{
|
||||
var lines = new List<List<Rune>> ();
|
||||
int start = 0, i = 0;
|
||||
var hasCR = false;
|
||||
// ASCII code 13 = Carriage Return.
|
||||
// ASCII code 10 = Line Feed.
|
||||
for (; i < content.Length; i++) {
|
||||
if (content [i] == 13) {
|
||||
hasCR = true;
|
||||
continue;
|
||||
}
|
||||
if (content [i] == 10) {
|
||||
if (i - start > 0)
|
||||
lines.Add (ToRunes (content [start, i]));
|
||||
lines.Add (ToRunes (content [start, hasCR ? i - 1 : i]));
|
||||
else
|
||||
lines.Add (ToRunes (ustring.Empty));
|
||||
start = i + 1;
|
||||
hasCR = false;
|
||||
}
|
||||
}
|
||||
if (i - start >= 0)
|
||||
@@ -109,16 +108,23 @@ namespace Terminal.Gui {
|
||||
var buff = new BufferedStream (input);
|
||||
int v;
|
||||
var line = new List<byte> ();
|
||||
var wasNewLine = false;
|
||||
while ((v = buff.ReadByte ()) != -1) {
|
||||
if (v == 13) {
|
||||
continue;
|
||||
}
|
||||
if (v == 10) {
|
||||
Append (line);
|
||||
line.Clear ();
|
||||
wasNewLine = true;
|
||||
continue;
|
||||
}
|
||||
line.Add ((byte)v);
|
||||
wasNewLine = false;
|
||||
}
|
||||
if (line.Count > 0)
|
||||
if (line.Count > 0 || wasNewLine)
|
||||
Append (line);
|
||||
buff.Dispose ();
|
||||
}
|
||||
|
||||
public void LoadString (ustring content)
|
||||
@@ -200,7 +206,7 @@ namespace Terminal.Gui {
|
||||
last = last < lines.Count ? last : lines.Count;
|
||||
for (int i = first; i < last; i++) {
|
||||
var line = GetLine (i);
|
||||
var tabSum = line.Sum (r => r == '\t' ? tabWidth - 1 : 0);
|
||||
var tabSum = line.Sum (r => r == '\t' ? Math.Max (tabWidth - 1, 0) : 0);
|
||||
var l = line.Count + tabSum;
|
||||
if (l > maxLength) {
|
||||
maxLength = l;
|
||||
@@ -230,7 +236,7 @@ namespace Terminal.Gui {
|
||||
for (int i = start; i < t.Count; i++) {
|
||||
var r = t [i];
|
||||
size += Rune.ColumnWidth (r);
|
||||
if (r == '\t' && tabWidth > 0) {
|
||||
if (r == '\t') {
|
||||
size += tabWidth + 1;
|
||||
}
|
||||
if (i == pX || (size > pX)) {
|
||||
@@ -255,7 +261,7 @@ namespace Terminal.Gui {
|
||||
var rune = t [i];
|
||||
size += Rune.ColumnWidth (rune);
|
||||
len += Rune.RuneLen (rune);
|
||||
if (rune == '\t' && tabWidth > 0) {
|
||||
if (rune == '\t') {
|
||||
size += tabWidth + 1;
|
||||
len += tabWidth - 1;
|
||||
}
|
||||
@@ -270,7 +276,7 @@ namespace Terminal.Gui {
|
||||
{
|
||||
s = Rune.ColumnWidth (r);
|
||||
l = Rune.RuneLen (r);
|
||||
if (r == '\t' && tWidth > 0) {
|
||||
if (r == '\t') {
|
||||
s += tWidth + 1;
|
||||
l += tWidth - 1;
|
||||
}
|
||||
@@ -1126,6 +1132,7 @@ namespace Terminal.Gui {
|
||||
Multiline = false;
|
||||
AllowsTab = false;
|
||||
}
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1143,12 +1150,10 @@ namespace Terminal.Gui {
|
||||
if (allowsTab && !multiline) {
|
||||
Multiline = true;
|
||||
}
|
||||
if (!allowsTab && multiline) {
|
||||
Multiline = false;
|
||||
}
|
||||
if (!allowsTab && tabWidth > 0) {
|
||||
tabWidth = 0;
|
||||
}
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1159,12 +1164,10 @@ namespace Terminal.Gui {
|
||||
get => tabWidth;
|
||||
set {
|
||||
tabWidth = Math.Max (value, 0);
|
||||
if (tabWidth == 0 && AllowsTab) {
|
||||
AllowsTab = false;
|
||||
}
|
||||
if (tabWidth > 0 && !AllowsTab) {
|
||||
AllowsTab = true;
|
||||
}
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1241,10 +1244,8 @@ namespace Terminal.Gui {
|
||||
/// <param name="path">Path to the file to load.</param>
|
||||
public bool LoadFile (string path)
|
||||
{
|
||||
if (path == null)
|
||||
throw new ArgumentNullException (nameof (path));
|
||||
ResetPosition ();
|
||||
var res = model.LoadFile (path);
|
||||
ResetPosition ();
|
||||
SetNeedsDisplay ();
|
||||
return res;
|
||||
}
|
||||
@@ -1256,10 +1257,8 @@ namespace Terminal.Gui {
|
||||
/// <param name="stream">Stream to load the contents from.</param>
|
||||
public void LoadStream (Stream stream)
|
||||
{
|
||||
if (stream == null)
|
||||
throw new ArgumentNullException (nameof (stream));
|
||||
ResetPosition ();
|
||||
model.LoadStream (stream);
|
||||
ResetPosition ();
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
|
||||
@@ -1269,8 +1268,8 @@ namespace Terminal.Gui {
|
||||
/// <returns><c>true</c>, if stream was closed, <c>false</c> otherwise.</returns>
|
||||
public bool CloseFile ()
|
||||
{
|
||||
ResetPosition ();
|
||||
var res = model.CloseFile ();
|
||||
ResetPosition ();
|
||||
SetNeedsDisplay ();
|
||||
return res;
|
||||
}
|
||||
@@ -1298,23 +1297,18 @@ namespace Terminal.Gui {
|
||||
SetNeedsDisplay (new Rect (0, minRow, Frame.Width, maxRow));
|
||||
}
|
||||
var line = model.GetLine (currentRow);
|
||||
var retreat = 0;
|
||||
var col = 0;
|
||||
if (line.Count > 0) {
|
||||
retreat = Math.Max (SpecialRune (line [Math.Min (Math.Max (currentColumn - leftColumn - 1, 0), line.Count - 1)])
|
||||
? 1 : 0, 0);
|
||||
|
||||
for (int idx = leftColumn; idx < line.Count; idx++) {
|
||||
if (idx >= currentColumn)
|
||||
break;
|
||||
var cols = Rune.ColumnWidth (line [idx]);
|
||||
if (line [idx] == '\t' && TabWidth > 0) {
|
||||
if (line [idx] == '\t') {
|
||||
cols += TabWidth + 1;
|
||||
}
|
||||
TextModel.SetCol (ref col, Frame.Width, cols);
|
||||
}
|
||||
}
|
||||
col += retreat;
|
||||
if ((col >= leftColumn || col < Frame.Width)
|
||||
&& topRow <= currentRow && currentRow - topRow + BottomOffset < Frame.Height) {
|
||||
ResetCursorVisibility ();
|
||||
@@ -1701,10 +1695,10 @@ namespace Terminal.Gui {
|
||||
&& HasFocus && idxCol < lineRuneCount) {
|
||||
ColorUsed (line, idxCol);
|
||||
} else {
|
||||
ColorNormal (line,idxCol);
|
||||
ColorNormal (line, idxCol);
|
||||
}
|
||||
|
||||
if (rune == '\t' && TabWidth > 0) {
|
||||
if (rune == '\t') {
|
||||
cols += TabWidth + 1;
|
||||
if (col + cols > right) {
|
||||
cols = right - col;
|
||||
@@ -1714,10 +1708,8 @@ namespace Terminal.Gui {
|
||||
AddRune (col + i, row, ' ');
|
||||
}
|
||||
}
|
||||
} else if (!SpecialRune (rune)) {
|
||||
AddRune (col, row, rune);
|
||||
} else {
|
||||
col++;
|
||||
AddRune (col, row, rune);
|
||||
}
|
||||
if (!TextModel.SetCol (ref col, bounds.Right, cols)) {
|
||||
break;
|
||||
@@ -1740,17 +1732,6 @@ namespace Terminal.Gui {
|
||||
PositionCursor ();
|
||||
}
|
||||
|
||||
bool SpecialRune (Rune rune)
|
||||
{
|
||||
switch (rune) {
|
||||
case (uint)Key.Enter:
|
||||
case 0xd:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
public override bool CanFocus {
|
||||
get => base.CanFocus;
|
||||
@@ -1974,7 +1955,7 @@ namespace Terminal.Gui {
|
||||
List<Rune> rest;
|
||||
|
||||
// if the user presses Left (without any control keys) and they are at the start of the text
|
||||
if(kb.Key == Key.CursorLeft && currentColumn == 0 && currentRow == 0) {
|
||||
if (kb.Key == Key.CursorLeft && currentColumn == 0 && currentRow == 0) {
|
||||
// do not respond (this lets the key press fall through to navigation system - which usually changes focus backward)
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace UICatalog {
|
||||
new MenuItem ("_Open", "", () => Open()),
|
||||
new MenuItem ("_Save", "", () => Save()),
|
||||
new MenuItem ("_Save As", "", () => SaveAs()),
|
||||
new MenuItem ("_Close", "", () => CloseFile()),
|
||||
null,
|
||||
new MenuItem ("_Quit", "", () => Quit()),
|
||||
}),
|
||||
@@ -67,7 +68,10 @@ namespace UICatalog {
|
||||
new MenuItem (" B_ox Fix", "", () => SetCursor(CursorVisibility.BoxFix)),
|
||||
new MenuItem (" U_nderline Fix","", () => SetCursor(CursorVisibility.UnderlineFix))
|
||||
}),
|
||||
new MenuBarItem ("Forma_t", CreateWrapChecked ())
|
||||
new MenuBarItem ("Forma_t", new MenuItem [] {
|
||||
CreateWrapChecked (),
|
||||
CreateAllowsTabChecked ()
|
||||
})
|
||||
});
|
||||
Top.Add (menu);
|
||||
|
||||
@@ -134,8 +138,11 @@ namespace UICatalog {
|
||||
|
||||
Win.KeyPress += (e) => {
|
||||
if (winDialog != null && (e.KeyEvent.Key == Key.Esc
|
||||
|| e.KeyEvent.Key.HasFlag (Key.Q | Key.CtrlMask))) {
|
||||
|| e.KeyEvent.Key == (Key.Q | Key.CtrlMask))) {
|
||||
DisposeWinDialog ();
|
||||
} else if (e.KeyEvent.Key == (Key.Q | Key.CtrlMask)) {
|
||||
Quit ();
|
||||
e.Handled = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -151,9 +158,9 @@ namespace UICatalog {
|
||||
{
|
||||
}
|
||||
|
||||
private void New ()
|
||||
private void New (bool checkChanges = true)
|
||||
{
|
||||
if (!CanCloseFile ()) {
|
||||
if (checkChanges && !CanCloseFile ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -166,9 +173,9 @@ namespace UICatalog {
|
||||
private void LoadFile ()
|
||||
{
|
||||
if (_fileName != null) {
|
||||
// BUGBUG: #452 TextView.LoadFile keeps file open and provides no way of closing it
|
||||
//_textView.LoadFile(_fileName);
|
||||
_textView.Text = System.IO.File.ReadAllText (_fileName);
|
||||
// FIXED: BUGBUG: #452 TextView.LoadFile keeps file open and provides no way of closing it
|
||||
_textView.LoadFile (_fileName);
|
||||
//_textView.Text = System.IO.File.ReadAllText (_fileName);
|
||||
_originalText = _textView.Text.ToByteArray ();
|
||||
Win.Title = _fileName;
|
||||
_saved = true;
|
||||
@@ -312,7 +319,7 @@ namespace UICatalog {
|
||||
var d = new OpenDialog ("Open", "Open a file") { AllowsMultipleSelection = false };
|
||||
Application.Run (d);
|
||||
|
||||
if (!d.Canceled) {
|
||||
if (!d.Canceled && d.FilePaths.Count > 0) {
|
||||
_fileName = d.FilePaths [0];
|
||||
LoadFile ();
|
||||
}
|
||||
@@ -321,7 +328,7 @@ namespace UICatalog {
|
||||
private bool Save ()
|
||||
{
|
||||
if (_fileName != null) {
|
||||
// BUGBUG: #279 TextView does not know how to deal with \r\n, only \r
|
||||
// FIXED: BUGBUG: #279 TextView does not know how to deal with \r\n, only \r
|
||||
// As a result files saved on Windows and then read back will show invalid chars.
|
||||
return SaveFile (Win.Title.ToString (), _fileName);
|
||||
} else {
|
||||
@@ -359,6 +366,7 @@ namespace UICatalog {
|
||||
Win.Title = title;
|
||||
_fileName = file;
|
||||
System.IO.File.WriteAllText (_fileName, _textView.Text.ToString ());
|
||||
_originalText = _textView.Text.ToByteArray ();
|
||||
_saved = true;
|
||||
MessageBox.Query ("Save File", "File was successfully saved.", "Ok");
|
||||
|
||||
@@ -370,15 +378,33 @@ namespace UICatalog {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void CloseFile ()
|
||||
{
|
||||
if (!CanCloseFile ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
_textView.CloseFile ();
|
||||
New (false);
|
||||
} catch (Exception ex) {
|
||||
MessageBox.ErrorQuery ("Error", ex.Message, "Ok");
|
||||
}
|
||||
}
|
||||
|
||||
private void Quit ()
|
||||
{
|
||||
if (!CanCloseFile ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Application.RequestStop ();
|
||||
}
|
||||
|
||||
private void CreateDemoFile (string fileName)
|
||||
{
|
||||
var sb = new StringBuilder ();
|
||||
// BUGBUG: #279 TextView does not know how to deal with \r\n, only \r
|
||||
// FIXED: BUGBUG: #279 TextView does not know how to deal with \r\n, only \r
|
||||
sb.Append ("Hello world.\n");
|
||||
sb.Append ("This is a test of the Emergency Broadcast System.\n");
|
||||
|
||||
@@ -401,10 +427,11 @@ namespace UICatalog {
|
||||
return new MenuItem [] { item };
|
||||
}
|
||||
|
||||
private MenuItem [] CreateWrapChecked ()
|
||||
private MenuItem CreateWrapChecked ()
|
||||
{
|
||||
var item = new MenuItem ();
|
||||
item.Title = "Word Wrap";
|
||||
var item = new MenuItem {
|
||||
Title = "Word Wrap"
|
||||
};
|
||||
item.CheckType |= MenuItemCheckStyle.Checked;
|
||||
item.Checked = false;
|
||||
item.Action += () => {
|
||||
@@ -419,7 +446,21 @@ namespace UICatalog {
|
||||
}
|
||||
};
|
||||
|
||||
return new MenuItem [] { item };
|
||||
return item;
|
||||
}
|
||||
|
||||
private MenuItem CreateAllowsTabChecked ()
|
||||
{
|
||||
var item = new MenuItem {
|
||||
Title = "Allows Tab"
|
||||
};
|
||||
item.CheckType |= MenuItemCheckStyle.Checked;
|
||||
item.Checked = true;
|
||||
item.Action += () => {
|
||||
_textView.AllowsTab = item.Checked = !item.Checked;
|
||||
};
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private void CreateFindReplace (bool isFind = true)
|
||||
@@ -674,10 +715,5 @@ namespace UICatalog {
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
public override void Run ()
|
||||
{
|
||||
base.Run ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Terminal.Gui.Views {
|
||||
public class TextViewTests {
|
||||
private static TextView _textView;
|
||||
readonly ITestOutputHelper output;
|
||||
|
||||
// This class enables test functions annoated with the [InitShutdown] attribute
|
||||
public TextViewTests (ITestOutputHelper output)
|
||||
{
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
// This class enables test functions annotated with the [InitShutdown] attribute
|
||||
// to have a function called before the test function is called and after.
|
||||
//
|
||||
// This is necessary because a) Application is a singleton and Init/Shutdown must be called
|
||||
@@ -42,7 +48,8 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Changing_Selection_Or_CursorPosition_Update_SelectedLength_And_SelectedText ()
|
||||
{
|
||||
_textView.SelectionStartColumn = 2;
|
||||
@@ -58,7 +65,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal ("B to jump between ", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Selection_With_Value_Less_Than_Zero_Changes_To_Zero ()
|
||||
{
|
||||
_textView.SelectionStartColumn = -2;
|
||||
@@ -69,7 +77,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Selection_With_Value_Greater_Than_Text_Length_Changes_To_Text_Length ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (2, 0);
|
||||
@@ -81,7 +90,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal ("B to jump between text fields.", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Selection_With_Empty_Text ()
|
||||
{
|
||||
_textView = new TextView ();
|
||||
@@ -94,7 +104,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Selection_And_CursorPosition_With_Value_Greater_Than_Text_Length_Changes_Both_To_Text_Length ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (33, 2);
|
||||
@@ -108,7 +119,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void CursorPosition_With_Value_Less_Than_Zero_Changes_To_Zero ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (-1, -1);
|
||||
@@ -118,7 +130,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void CursorPosition_With_Value_Greater_Than_Text_Length_Changes_To_Text_Length ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (33, 1);
|
||||
@@ -128,7 +141,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void WordForward_With_No_Selection ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (0, 0);
|
||||
@@ -190,7 +204,8 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void WordBackward_With_No_Selection ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (_textView.Text.Length, 0);
|
||||
@@ -252,7 +267,8 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void WordForward_With_Selection ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (0, 0);
|
||||
@@ -316,7 +332,8 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void WordBackward_With_Selection ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (_textView.Text.Length, 0);
|
||||
@@ -380,7 +397,8 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void WordForward_With_The_Same_Values_For_SelectedStart_And_CursorPosition_And_Not_Starting_At_Beginning_Of_The_Text ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (10, 0);
|
||||
@@ -428,7 +446,8 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void WordBackward_With_The_Same_Values_For_SelectedStart_And_CursorPosition_And_Not_Starting_At_Beginning_Of_The_Text ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (10, 0);
|
||||
@@ -468,7 +487,8 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void WordForward_With_No_Selection_And_With_More_Than_Only_One_Whitespace_And_With_Only_One_Letter ()
|
||||
{
|
||||
// 1 2 3 4 5
|
||||
@@ -565,7 +585,8 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void WordBackward_With_No_Selection_And_With_More_Than_Only_One_Whitespace_And_With_Only_One_Letter ()
|
||||
{
|
||||
// 1 2 3 4 5
|
||||
@@ -670,7 +691,8 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void WordBackward_Multiline_With_Selection ()
|
||||
{
|
||||
// 4 3 2 1
|
||||
@@ -784,7 +806,8 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void WordForward_Multiline_With_Selection ()
|
||||
{
|
||||
// 1 2 3 4
|
||||
@@ -897,7 +920,8 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Kill_To_End_Delete_Forwards_And_Copy_To_The_Clipboard ()
|
||||
{
|
||||
_textView.Text = "This is the first line.\nThis is the second line.";
|
||||
@@ -932,7 +956,8 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Kill_To_Start_Delete_Backwards_And_Copy_To_The_Clipboard ()
|
||||
{
|
||||
_textView.Text = "This is the first line.\nThis is the second line.";
|
||||
@@ -968,7 +993,8 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Kill_Delete_WordForward ()
|
||||
{
|
||||
_textView.Text = "This is the first line.";
|
||||
@@ -1011,7 +1037,8 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Kill_Delete_WordBackward ()
|
||||
{
|
||||
_textView.Text = "This is the first line.";
|
||||
@@ -1055,7 +1082,8 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Kill_Delete_WordForward_Multiline ()
|
||||
{
|
||||
_textView.Text = "This is the first line.\nThis is the second line.";
|
||||
@@ -1134,7 +1162,8 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Kill_Delete_WordBackward_Multiline ()
|
||||
{
|
||||
_textView.Text = "This is the first line.\nThis is the second line.";
|
||||
@@ -1213,7 +1242,8 @@ namespace Terminal.Gui.Views {
|
||||
}
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Copy_Or_Cut_Null_If_No_Selection ()
|
||||
{
|
||||
_textView.SelectionStartColumn = 0;
|
||||
@@ -1224,7 +1254,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Copy_Or_Cut_Not_Null_If_Has_Selection ()
|
||||
{
|
||||
_textView.SelectionStartColumn = 20;
|
||||
@@ -1236,7 +1267,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Copy_Or_Cut_And_Paste_With_Selection ()
|
||||
{
|
||||
_textView.SelectionStartColumn = 20;
|
||||
@@ -1254,7 +1286,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal ("TAB to jump between text fields.", _textView.Text);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Copy_Or_Cut_And_Paste_With_No_Selection ()
|
||||
{
|
||||
_textView.SelectionStartColumn = 20;
|
||||
@@ -1282,7 +1315,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal ("TAB to jump between texttext fields.", _textView.Text);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Cut_Not_Allowed_If_ReadOnly_Is_True ()
|
||||
{
|
||||
_textView.ReadOnly = true;
|
||||
@@ -1302,7 +1336,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Paste_Always_Clear_The_SelectedText ()
|
||||
{
|
||||
_textView.SelectionStartColumn = 20;
|
||||
@@ -1314,7 +1349,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void TextChanged_Event ()
|
||||
{
|
||||
_textView.TextChanged += () => {
|
||||
@@ -1328,7 +1364,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal ("changed", _textView.Text);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Used_Is_True_By_Default ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (10, 0);
|
||||
@@ -1343,7 +1380,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal ("TAB to jumusedp between text fields.", _textView.Text);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Used_Is_False ()
|
||||
{
|
||||
_textView.Used = false;
|
||||
@@ -1359,7 +1397,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal ("TAB to jumusedtween text fields.", _textView.Text);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Copy_Without_Selection ()
|
||||
{
|
||||
_textView.Text = "This is the first line.\nThis is the second line.\n";
|
||||
@@ -1377,8 +1416,9 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal (new Point (3, 3), _textView.CursorPosition);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
public void TabWidth_Setting_To_Zero_Changes_AllowsTab_To_False_If_True ()
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void TabWidth_Setting_To_Zero_Keeps_AllowsTab ()
|
||||
{
|
||||
Assert.Equal (4, _textView.TabWidth);
|
||||
Assert.True (_textView.AllowsTab);
|
||||
@@ -1386,23 +1426,24 @@ namespace Terminal.Gui.Views {
|
||||
Assert.True (_textView.Multiline);
|
||||
_textView.TabWidth = -1;
|
||||
Assert.Equal (0, _textView.TabWidth);
|
||||
Assert.False (_textView.AllowsTab);
|
||||
Assert.False (_textView.AllowsReturn);
|
||||
Assert.False (_textView.Multiline);
|
||||
Assert.True (_textView.AllowsTab);
|
||||
Assert.True (_textView.AllowsReturn);
|
||||
Assert.True (_textView.Multiline);
|
||||
_textView.ProcessKey (new KeyEvent (Key.Tab, new KeyModifiers ()));
|
||||
Assert.Equal ("TAB to jump between text fields.", _textView.Text);
|
||||
Assert.Equal ("\tTAB to jump between text fields.", _textView.Text);
|
||||
_textView.ProcessKey (new KeyEvent (Key.BackTab, new KeyModifiers ()));
|
||||
Assert.Equal ("TAB to jump between text fields.", _textView.Text);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void AllowsTab_Setting_To_True_Changes_TabWidth_To_Default_If_It_Is_Zero ()
|
||||
{
|
||||
_textView.TabWidth = 0;
|
||||
Assert.Equal (0, _textView.TabWidth);
|
||||
Assert.False (_textView.AllowsTab);
|
||||
Assert.False (_textView.AllowsReturn);
|
||||
Assert.False (_textView.Multiline);
|
||||
Assert.True (_textView.AllowsTab);
|
||||
Assert.True (_textView.AllowsReturn);
|
||||
Assert.True (_textView.Multiline);
|
||||
_textView.AllowsTab = true;
|
||||
Assert.True (_textView.AllowsTab);
|
||||
Assert.Equal (4, _textView.TabWidth);
|
||||
@@ -1410,7 +1451,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.True (_textView.Multiline);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void AllowsReturn_Setting_To_True_Changes_Multiline_To_True_If_It_Is_False ()
|
||||
{
|
||||
Assert.True (_textView.AllowsReturn);
|
||||
@@ -1431,7 +1473,8 @@ namespace Terminal.Gui.Views {
|
||||
"TAB to jump between text fields.", _textView.Text);
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Multiline_Setting_Changes_AllowsReturn_And_AllowsTab_And_Height ()
|
||||
{
|
||||
Assert.True (_textView.Multiline);
|
||||
@@ -1458,7 +1501,8 @@ namespace Terminal.Gui.Views {
|
||||
Assert.Equal ("Dim.Absolute(10)", _textView.Height.ToString ());
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Tab_Test_Follow_By_BackTab ()
|
||||
{
|
||||
Application.Top.Add (_textView);
|
||||
@@ -1493,7 +1537,8 @@ namespace Terminal.Gui.Views {
|
||||
Application.Run ();
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void BackTab_Test_Follow_By_Tab ()
|
||||
{
|
||||
Application.Top.Add (_textView);
|
||||
@@ -1535,7 +1580,8 @@ namespace Terminal.Gui.Views {
|
||||
Application.Run ();
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Tab_Test_Follow_By_CursorLeft_And_Then_Follow_By_CursorRight ()
|
||||
{
|
||||
Application.Top.Add (_textView);
|
||||
@@ -1577,7 +1623,8 @@ namespace Terminal.Gui.Views {
|
||||
Application.Run ();
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Tab_Test_Follow_By_BackTab_With_Text ()
|
||||
{
|
||||
Application.Top.Add (_textView);
|
||||
@@ -1612,7 +1659,8 @@ namespace Terminal.Gui.Views {
|
||||
Application.Run ();
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Tab_Test_Follow_By_Home_And_Then_Follow_By_End_And_Then_Follow_By_BackTab_With_Text ()
|
||||
{
|
||||
Application.Top.Add (_textView);
|
||||
@@ -1669,7 +1717,8 @@ namespace Terminal.Gui.Views {
|
||||
Application.Run ();
|
||||
}
|
||||
|
||||
[Fact][InitShutdown]
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void Tab_Test_Follow_By_CursorLeft_And_Then_Follow_By_CursorRight_With_Text ()
|
||||
{
|
||||
Application.Top.Add (_textView);
|
||||
@@ -1712,6 +1761,20 @@ namespace Terminal.Gui.Views {
|
||||
Application.Run ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TextView_MultiLine_But_Without_Tabs ()
|
||||
{
|
||||
var view = new TextView ();
|
||||
|
||||
// the default for TextView
|
||||
Assert.True (view.Multiline);
|
||||
|
||||
view.AllowsTab = false;
|
||||
Assert.False (view.AllowsTab);
|
||||
|
||||
Assert.True (view.Multiline);
|
||||
}
|
||||
|
||||
private int GetLeftCol (int start)
|
||||
{
|
||||
var lines = _textView.Text.Split (Environment.NewLine);
|
||||
@@ -1751,5 +1814,133 @@ namespace Terminal.Gui.Views {
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadFile_Throws_If_File_Is_Null ()
|
||||
{
|
||||
var tv = new TextView ();
|
||||
Assert.Throws<ArgumentNullException> (() => tv.LoadFile (null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadFile_Throws_If_File_Is_Empty ()
|
||||
{
|
||||
var tv = new TextView ();
|
||||
Assert.Throws<ArgumentException> (() => tv.LoadFile (""));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadFile_Throws_If_File_Not_Exist ()
|
||||
{
|
||||
var tv = new TextView ();
|
||||
Assert.Throws<System.IO.FileNotFoundException> (() => tv.LoadFile ("blabla"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadStream_Throws_If_Stream_Is_Null ()
|
||||
{
|
||||
var tv = new TextView ();
|
||||
Assert.Throws<ArgumentNullException> (() => tv.LoadStream (null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadStream_Stream_Is_Empty ()
|
||||
{
|
||||
var tv = new TextView ();
|
||||
tv.LoadStream (new System.IO.MemoryStream ());
|
||||
Assert.Equal ("", tv.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadStream_CRLF ()
|
||||
{
|
||||
var text = "This is the first line.\r\nThis is the second line.\r\n";
|
||||
var tv = new TextView ();
|
||||
tv.LoadStream (new System.IO.MemoryStream (System.Text.Encoding.ASCII.GetBytes (text)));
|
||||
Assert.Equal ($"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}", tv.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadStream_LF ()
|
||||
{
|
||||
var text = "This is the first line.\nThis is the second line.\n";
|
||||
var tv = new TextView ();
|
||||
tv.LoadStream (new System.IO.MemoryStream (System.Text.Encoding.ASCII.GetBytes (text)));
|
||||
Assert.Equal ($"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}", tv.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StringToRunes_Slipts_CRLF ()
|
||||
{
|
||||
var text = "This is the first line.\r\nThis is the second line.\r\n";
|
||||
var tv = new TextView ();
|
||||
tv.Text = text;
|
||||
Assert.Equal ($"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}", tv.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StringToRunes_Slipts_LF ()
|
||||
{
|
||||
var text = "This is the first line.\nThis is the second line.\n";
|
||||
var tv = new TextView ();
|
||||
tv.Text = text;
|
||||
Assert.Equal ($"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}", tv.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CloseFile_Throws_If_FilePath_Is_Null ()
|
||||
{
|
||||
var tv = new TextView ();
|
||||
Assert.Throws<ArgumentNullException> (() => tv.CloseFile ());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WordWrap_Gets_Sets ()
|
||||
{
|
||||
var tv = new TextView () { WordWrap = true };
|
||||
Assert.True (tv.WordWrap);
|
||||
tv.WordWrap = false;
|
||||
Assert.False (tv.WordWrap);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WordWrap_True_Text_Always_Returns_Unwrapped ()
|
||||
{
|
||||
var text = "This is the first line.\nThis is the second line.\n";
|
||||
var tv = new TextView () { Width = 10 };
|
||||
tv.Text = text;
|
||||
Assert.Equal ($"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}", tv.Text);
|
||||
tv.WordWrap = true;
|
||||
Assert.Equal ($"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}", tv.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[InitShutdown]
|
||||
public void WordWrap_WrapModel_Output ()
|
||||
{
|
||||
// 0123456789
|
||||
var text = "This is the first line.\nThis is the second line.\n";
|
||||
var tv = new TextView () { Width = 10, Height = 10 };
|
||||
tv.Text = text;
|
||||
Assert.Equal ($"This is the first line.{Environment.NewLine}This is the second line.{Environment.NewLine}", tv.Text);
|
||||
tv.WordWrap = true;
|
||||
|
||||
Application.Top.Add (tv);
|
||||
|
||||
tv.Redraw (tv.Bounds);
|
||||
|
||||
string expected = @"
|
||||
This is
|
||||
the
|
||||
first
|
||||
line.
|
||||
This is
|
||||
the
|
||||
second
|
||||
line.
|
||||
";
|
||||
|
||||
GraphViewTests.AssertDriverContentsAre (expected, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user