| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649 |
- using System.Globalization;
- namespace Terminal.Gui.Views;
- /// <summary>Core functionality - Fields, Constructor, and fundamental properties</summary>
- public partial class TextView
- {
- #region Fields
- private readonly HistoryText _historyText = new ();
- private bool _allowsReturn = true;
- private bool _allowsTab = true;
- private bool _clickWithSelecting;
- // The column we are tracking, or -1 if we are not tracking any column
- private int _columnTrack = -1;
- private bool _continuousFind;
- private bool _copyWithoutSelection;
- private string? _currentCaller;
- private CultureInfo? _currentCulture;
- private bool _isButtonShift;
- private bool _isButtonReleased;
- private bool _isDrawing;
- private bool _isReadOnly;
- private bool _lastWasKill;
- private int _leftColumn;
- private TextModel _model = new ();
- private bool _multiline = true;
- private Dim? _savedHeight;
- private int _selectionStartColumn, _selectionStartRow;
- private bool _shiftSelecting;
- private int _tabWidth = 4;
- private int _topRow;
- private bool _wordWrap;
- private WordWrapManager? _wrapManager;
- private bool _wrapNeeded;
- private string? _copiedText;
- private List<List<Cell>> _copiedCellsList = [];
- #endregion
- #region Constructor
- /// <summary>
- /// Initializes a <see cref="TextView"/> on the specified area, with dimensions controlled with the X, Y, Width
- /// and Height properties.
- /// </summary>
- public TextView ()
- {
- CanFocus = true;
- CursorVisibility = CursorVisibility.Default;
- Used = true;
- // By default, disable hotkeys (in case someone sets Title)
- base.HotKeySpecifier = new ('\xffff');
- _model.LinesLoaded += Model_LinesLoaded!;
- _historyText.ChangeText += HistoryText_ChangeText!;
- Initialized += TextView_Initialized!;
- SuperViewChanged += TextView_SuperViewChanged!;
- SubViewsLaidOut += TextView_LayoutComplete;
- // Things this view knows how to do
- // Note - NewLine is only bound to Enter if Multiline is true
- AddCommand (Command.NewLine, ctx => ProcessEnterKey (ctx));
- AddCommand (
- Command.PageDown,
- () =>
- {
- ProcessPageDown ();
- return true;
- }
- );
- AddCommand (
- Command.PageDownExtend,
- () =>
- {
- ProcessPageDownExtend ();
- return true;
- }
- );
- AddCommand (
- Command.PageUp,
- () =>
- {
- ProcessPageUp ();
- return true;
- }
- );
- AddCommand (
- Command.PageUpExtend,
- () =>
- {
- ProcessPageUpExtend ();
- return true;
- }
- );
- AddCommand (Command.Down, () => ProcessMoveDown ());
- AddCommand (
- Command.DownExtend,
- () =>
- {
- ProcessMoveDownExtend ();
- return true;
- }
- );
- AddCommand (Command.Up, () => ProcessMoveUp ());
- AddCommand (
- Command.UpExtend,
- () =>
- {
- ProcessMoveUpExtend ();
- return true;
- }
- );
- AddCommand (Command.Right, () => ProcessMoveRight ());
- AddCommand (
- Command.RightExtend,
- () =>
- {
- ProcessMoveRightExtend ();
- return true;
- }
- );
- AddCommand (Command.Left, () => ProcessMoveLeft ());
- AddCommand (
- Command.LeftExtend,
- () =>
- {
- ProcessMoveLeftExtend ();
- return true;
- }
- );
- AddCommand (
- Command.DeleteCharLeft,
- () =>
- {
- ProcessDeleteCharLeft ();
- return true;
- }
- );
- AddCommand (
- Command.LeftStart,
- () =>
- {
- ProcessMoveLeftStart ();
- return true;
- }
- );
- AddCommand (
- Command.LeftStartExtend,
- () =>
- {
- ProcessMoveLeftStartExtend ();
- return true;
- }
- );
- AddCommand (
- Command.DeleteCharRight,
- () =>
- {
- ProcessDeleteCharRight ();
- return true;
- }
- );
- AddCommand (
- Command.RightEnd,
- () =>
- {
- ProcessMoveEndOfLine ();
- return true;
- }
- );
- AddCommand (
- Command.RightEndExtend,
- () =>
- {
- ProcessMoveRightEndExtend ();
- return true;
- }
- );
- AddCommand (
- Command.CutToEndLine,
- () =>
- {
- KillToEndOfLine ();
- return true;
- }
- );
- AddCommand (
- Command.CutToStartLine,
- () =>
- {
- KillToLeftStart ();
- return true;
- }
- );
- AddCommand (
- Command.Paste,
- () =>
- {
- ProcessPaste ();
- return true;
- }
- );
- AddCommand (
- Command.ToggleExtend,
- () =>
- {
- ToggleSelecting ();
- return true;
- }
- );
- AddCommand (
- Command.Copy,
- () =>
- {
- ProcessCopy ();
- return true;
- }
- );
- AddCommand (
- Command.Cut,
- () =>
- {
- ProcessCut ();
- return true;
- }
- );
- AddCommand (
- Command.WordLeft,
- () =>
- {
- ProcessMoveWordBackward ();
- return true;
- }
- );
- AddCommand (
- Command.WordLeftExtend,
- () =>
- {
- ProcessMoveWordBackwardExtend ();
- return true;
- }
- );
- AddCommand (
- Command.WordRight,
- () =>
- {
- ProcessMoveWordForward ();
- return true;
- }
- );
- AddCommand (
- Command.WordRightExtend,
- () =>
- {
- ProcessMoveWordForwardExtend ();
- return true;
- }
- );
- AddCommand (
- Command.KillWordForwards,
- () =>
- {
- ProcessKillWordForward ();
- return true;
- }
- );
- AddCommand (
- Command.KillWordBackwards,
- () =>
- {
- ProcessKillWordBackward ();
- return true;
- }
- );
- AddCommand (
- Command.End,
- () =>
- {
- MoveBottomEnd ();
- return true;
- }
- );
- AddCommand (
- Command.EndExtend,
- () =>
- {
- MoveBottomEndExtend ();
- return true;
- }
- );
- AddCommand (
- Command.Start,
- () =>
- {
- MoveTopHome ();
- return true;
- }
- );
- AddCommand (
- Command.StartExtend,
- () =>
- {
- MoveTopHomeExtend ();
- return true;
- }
- );
- AddCommand (
- Command.SelectAll,
- () =>
- {
- ProcessSelectAll ();
- return true;
- }
- );
- AddCommand (
- Command.ToggleOverwrite,
- () =>
- {
- ProcessSetOverwrite ();
- return true;
- }
- );
- AddCommand (
- Command.EnableOverwrite,
- () =>
- {
- SetOverwrite (true);
- return true;
- }
- );
- AddCommand (
- Command.DisableOverwrite,
- () =>
- {
- SetOverwrite (false);
- return true;
- }
- );
- AddCommand (Command.Tab, () => ProcessTab ());
- AddCommand (Command.BackTab, () => ProcessBackTab ());
- AddCommand (
- Command.Undo,
- () =>
- {
- Undo ();
- return true;
- }
- );
- AddCommand (
- Command.Redo,
- () =>
- {
- Redo ();
- return true;
- }
- );
- AddCommand (
- Command.DeleteAll,
- () =>
- {
- DeleteAll ();
- return true;
- }
- );
- AddCommand (
- Command.Context,
- () =>
- {
- ShowContextMenu (null);
- return true;
- }
- );
- AddCommand (
- Command.Open,
- () =>
- {
- PromptForColors ();
- return true;
- });
- // Default keybindings for this view
- KeyBindings.Remove (Key.Space);
- KeyBindings.Remove (Key.Enter);
- KeyBindings.Add (Key.Enter, Multiline ? Command.NewLine : Command.Accept);
- KeyBindings.Add (Key.PageDown, Command.PageDown);
- KeyBindings.Add (Key.V.WithCtrl, Command.PageDown);
- KeyBindings.Add (Key.PageDown.WithShift, Command.PageDownExtend);
- KeyBindings.Add (Key.PageUp, Command.PageUp);
- KeyBindings.Add (Key.PageUp.WithShift, Command.PageUpExtend);
- KeyBindings.Add (Key.N.WithCtrl, Command.Down);
- KeyBindings.Add (Key.CursorDown, Command.Down);
- KeyBindings.Add (Key.CursorDown.WithShift, Command.DownExtend);
- KeyBindings.Add (Key.P.WithCtrl, Command.Up);
- KeyBindings.Add (Key.CursorUp, Command.Up);
- KeyBindings.Add (Key.CursorUp.WithShift, Command.UpExtend);
- KeyBindings.Add (Key.F.WithCtrl, Command.Right);
- KeyBindings.Add (Key.CursorRight, Command.Right);
- KeyBindings.Add (Key.CursorRight.WithShift, Command.RightExtend);
- KeyBindings.Add (Key.B.WithCtrl, Command.Left);
- KeyBindings.Add (Key.CursorLeft, Command.Left);
- KeyBindings.Add (Key.CursorLeft.WithShift, Command.LeftExtend);
- KeyBindings.Add (Key.Backspace, Command.DeleteCharLeft);
- KeyBindings.Add (Key.Home, Command.LeftStart);
- KeyBindings.Add (Key.Home.WithShift, Command.LeftStartExtend);
- KeyBindings.Add (Key.Delete, Command.DeleteCharRight);
- KeyBindings.Add (Key.D.WithCtrl, Command.DeleteCharRight);
- KeyBindings.Add (Key.End, Command.RightEnd);
- KeyBindings.Add (Key.E.WithCtrl, Command.RightEnd);
- KeyBindings.Add (Key.End.WithShift, Command.RightEndExtend);
- KeyBindings.Add (Key.K.WithCtrl, Command.CutToEndLine); // kill-to-end
- KeyBindings.Add (Key.Delete.WithCtrl.WithShift, Command.CutToEndLine); // kill-to-end
- KeyBindings.Add (Key.Backspace.WithCtrl.WithShift, Command.CutToStartLine); // kill-to-start
- KeyBindings.Add (Key.Y.WithCtrl, Command.Paste); // Control-y, yank
- KeyBindings.Add (Key.Space.WithCtrl, Command.ToggleExtend);
- KeyBindings.Add (Key.C.WithCtrl, Command.Copy);
- KeyBindings.Add (Key.W.WithCtrl, Command.Cut); // Move to Unix?
- KeyBindings.Add (Key.X.WithCtrl, Command.Cut);
- KeyBindings.Add (Key.CursorLeft.WithCtrl, Command.WordLeft);
- KeyBindings.Add (Key.CursorLeft.WithCtrl.WithShift, Command.WordLeftExtend);
- KeyBindings.Add (Key.CursorRight.WithCtrl, Command.WordRight);
- KeyBindings.Add (Key.CursorRight.WithCtrl.WithShift, Command.WordRightExtend);
- KeyBindings.Add (Key.Delete.WithCtrl, Command.KillWordForwards); // kill-word-forwards
- KeyBindings.Add (Key.Backspace.WithCtrl, Command.KillWordBackwards); // kill-word-backwards
- KeyBindings.Add (Key.End.WithCtrl, Command.End);
- KeyBindings.Add (Key.End.WithCtrl.WithShift, Command.EndExtend);
- KeyBindings.Add (Key.Home.WithCtrl, Command.Start);
- KeyBindings.Add (Key.Home.WithCtrl.WithShift, Command.StartExtend);
- KeyBindings.Add (Key.A.WithCtrl, Command.SelectAll);
- KeyBindings.Add (Key.InsertChar, Command.ToggleOverwrite);
- KeyBindings.Add (Key.Tab, Command.Tab);
- KeyBindings.Add (Key.Tab.WithShift, Command.BackTab);
- KeyBindings.Add (Key.Z.WithCtrl, Command.Undo);
- KeyBindings.Add (Key.R.WithCtrl, Command.Redo);
- KeyBindings.Add (Key.G.WithCtrl, Command.DeleteAll);
- KeyBindings.Add (Key.D.WithCtrl.WithShift, Command.DeleteAll);
- KeyBindings.Add (Key.L.WithCtrl, Command.Open);
- #if UNIX_KEY_BINDINGS
- KeyBindings.Add (Key.C.WithAlt, Command.Copy);
- KeyBindings.Add (Key.B.WithAlt, Command.WordLeft);
- KeyBindings.Add (Key.W.WithAlt, Command.Cut);
- KeyBindings.Add (Key.V.WithAlt, Command.PageUp);
- KeyBindings.Add (Key.F.WithAlt, Command.WordRight);
- KeyBindings.Add (Key.K.WithAlt, Command.CutToStartLine); // kill-to-start
- #endif
- _currentCulture = Thread.CurrentThread.CurrentUICulture;
- }
- #endregion
- #region Initialization and Configuration
- private void TextView_Initialized (object sender, EventArgs e)
- {
- if (Autocomplete.HostControl is null)
- {
- Autocomplete.HostControl = this;
- }
- ContextMenu = CreateContextMenu ();
- App?.Popover?.Register (ContextMenu);
- KeyBindings.Add (ContextMenu.Key, Command.Context);
- // Configure ScrollBars to use modern View scrolling infrastructure
- ConfigureLayout ();
- OnContentsChanged ();
- }
- private void TextView_SuperViewChanged (object sender, SuperViewChangedEventArgs e)
- {
- if (e.SuperView is { })
- {
- if (Autocomplete.HostControl is null)
- {
- Autocomplete.HostControl = this;
- }
- }
- else
- {
- Autocomplete.HostControl = null;
- }
- }
- private void Model_LinesLoaded (object sender, EventArgs e)
- {
- // This call is not needed. Model_LinesLoaded gets invoked when
- // model.LoadString (value) is called. LoadString is called from one place
- // (Text.set) and historyText.Clear() is called immediately after.
- // If this call happens, HistoryText_ChangeText will get called multiple times
- // when Text is set, which is wrong.
- //historyText.Clear (Text);
- if (!_multiline && !IsInitialized)
- {
- CurrentColumn = Text.GetRuneCount ();
- _leftColumn = CurrentColumn > Viewport.Width + 1 ? CurrentColumn - Viewport.Width + 1 : 0;
- }
- }
- #endregion
- /// <summary>
- /// INTERNAL: Determines if a redraw is needed based on selection state, word wrap needs, and Used flag.
- /// If a redraw is needed, calls <see cref="AdjustScrollPosition"/>; otherwise positions the cursor and updates
- /// the unwrapped cursor position.
- /// </summary>
- private void DoNeededAction ()
- {
- if (!NeedsDraw && (IsSelecting || _wrapNeeded || !Used))
- {
- SetNeedsDraw ();
- }
- if (NeedsDraw)
- {
- AdjustScrollPosition ();
- }
- else
- {
- PositionCursor ();
- OnUnwrappedCursorPosition ();
- }
- }
- }
|