gitlabEdit

book-openInput Reader

May I read what you've written, please?

This functionality is an important part of any interactive console application, because it gives users a chance to input what they want to write to the console.

In case you want to listen to mouse events, you can consult the below page:

computer-mousePointer Eventschevron-right

In case you want to use something other than the reader, you can consult the other input tools defined in the below page:

penOther Inputchevron-right
circle-info

If you're making your own mod in Nitrocid KS, it's best to use its own Input class instead of Terminaux's TermReader, as the class there actually deals with the screensaver in most circumstances.


The Input Reader

You can easily use this feature in any interactive console application that uses Terminaux. Just use the Terminaux.Reader.TermReader class that contains the Read() functions and their overloaded versions.

circle-info

The reader not only provides the static text version for input prompts, but also the dynamic text version. Just create a simple function delegate that generates a string as the first argument, like this:

string input = TermReader.Read(() => $"{DateTime.Now} [{TermReaderState.CurrentState.CurrentTextPos}]\n> ", "Hello World!", false, false, false);
circle-info

Please note that they are interruptible by default. If you want the input to be non-interruptible, you can set the interruptible argument to false.

You can access the global reader settings by referencing the GlobalReaderSettings found in the TermReader class.

Read() and generic value types

You can use the Read() function with a generic type that resembles a simple type, such as integers, characters, and strings. This is to simplify type conversion that may be needed for certain inputs, such as entering a number or a fractional number.

The below example demonstrates how to use this feature:

circle-exclamation

Keybindings

Terminal reader offers a set of built-in keybindings, as well as custom keybindings.

chevron-rightBuilt-in bindingshashtag

The terminal reader contains main keybindings, as well as customizable keybindings that you can define to your accord.

Any key will append the selected characters to the current text input, and RETURN will accept the input. You can also override the keybindings of one of the below actions, as long as they're not listed in red. The below keybindings are available:

Keybinding
Action

ENTER

Accepts input

Ctrl+C

Cancels reading (if TreatCtrlCAsInput is enabled)

Ctrl+A / HOME

Beginning of line

Ctrl+E / END

End of line

Ctrl+B /

Backward one character

Ctrl+F /

Forward one character

BACKSPACE

Remove one character from the left

UP ARROW

Get the older input

DOWN ARROW

Get the newer input

DELETE

Remove one character in current position

ALT+B

One word backward

ALT+F

One word forward

TAB

Next auto-completion entry (if there is one)

Insert four spaces (if no autocompletions)

SHIFT+TAB

Previous auto-completion entry

CTRL+U

Cut to the start of the line

CTRL+K

Cut to the end of the line

CTRL+W

Cut to the end of the previous word

ALT+D

Cut to the end of the next word

CTRL+Y

Yank the cut content

Alt+L

Make word lowercase

Alt+U

Make word UPPERCASE

Ctrl+Alt+L

Make input lowercase

Ctrl+Alt+U

Make input UPPERCASE

Alt+C

Make character uppercase and move to the end of word

Alt+V

Make character lowercase and move to the end of word

Alt+S

Shows all suggestions in the style akin to the Bourne Again SHell (bash)

Alt+R

Refreshes the prompt, the text input, and the current cursor position.

Insert

Text append mode (Insert or append)

CTRL+L

Clears the screen and refreshes the prompt.

ALT+\

Cut the whitespaces before and after the character.

CTRL+T

Substitutes two characters

ALT+T

Substitutes two words

ALT+SHIFT+#

Makes your current input text a comment (visual only, but ignores your text on submit)

ALT+TAB / CTRL+I

Forces the tab character to be written. Writes as spaces.

ALT+SHIFT+C

Temporarily conceals or reveals the whole input in normal prompts.

ALT+SHIFT+<

Goes to the first history entry

ALT+SHIFT+>

Goes to the last history entry

CTRL+SHIFT+_

Undos a change

ALT+R

Undos all changes

ALT+0-9

Argument value

ALT+-

Argument negation

circle-exclamation
chevron-rightCustom bindingshashtag

The input reader supports custom bindings, which you can assign your BaseBinding class containing the following functions you must override:

Property/function
Description

BoundKeys

This holds all the keys to bind your custom action to.

DoAction()

This is the heart of your key binding. You can do anything with the text using the current terminal reader state.

You can also override these:

Property/function
Description

IsExit

If true, causes the reader to assume that the input is done after executing the action that this binding implements.

BindMatched()

Specify your own method on how to check to see if the input key matched all the bound keys (BoundKeys) in your custom key binding.

ResetSuggestionsTextPos

Specifies whether to reset the text position saved for the suggestions. This is usually enabled for custom bindings that have to do with the suggestions.

IsBindingOverridable

Specifies whether applications can override the keybinding with custom keybindings or not. You can call Override() and RemoveOverride() to perform this action.

AppendsChangesList

Specifies whether the keybinding appends the changes to the list of changes from the reader state.

ArgumentNumberIsRepetition

Specifies whether the argument number represents repeated action. If false, you must either handle the argument number using the ArgumentNumber property, or ignore the argument number.

chevron-rightPrinciples of custom bindingshashtag

Your keybinding must follow the below principles:

  • For text positioning, you must use any function in the PositioningTools class.

  • For manual console manipulation, you must use any function in the ConsoleWrapper class.

  • Your bound key must not be already bound to a key that was already bound by either a base or another custom binding, or two bindings execute at the same time, potentially causing conflict.

  • To manipulate with text, you must use the state.CurrentText property. You must refresh the prompt thereafter.

  • To refresh the prompt, you must use the TermReaderTools.Refresh() function.

At the end, your base class must look like this at minimum:

where:

  • ConsoleKey.Key

  • \0

    • A character that must match the corresponding ConsoleKey.Key.

circle-info

If you're assigning a key containing CTRL, you must assign a character number starting from 0x0. For example, CTRL+Y is \u0019.

chevron-rightHow to bind and unbind a custom bindinghashtag

Once you created a base class as mentioned above, you can finally use the BindingsTools class to call the Bind(BaseBinding) function to add your own binding to the custom binding store, like this:

circle-exclamation

To remove binding, you must use the Unbind(ConsoleKeyInfo) command.


History tools

Terminaux applications can access tools that are related to the shell history using the HistoryTools class found in the Terminaux.Reader.History namespace. It contains a variety of tools that are easy to use. This class contains functions that allow you to manipulate with the history.

chevron-rightLoading, saving, and unloadinghashtag

You can load the history instances using one of the following functions:

Function
Description

LoadFromFile()

This loads the histories from a JSON file

LoadFromJson()

This loads the histories from a JSON string

LoadFromInstance()

This loads the histories from a HistoryInfo instance

Once history instances get loaded, you can use the histories that may contain history entries for the terminal reader by setting the history name in the terminal reader settings using the following properties:

Property
Description

HistoryEnabled

Whether the history is enabled or not

HistoryName

Select what history to use


You can save the history instances to a JSON representation using one of the following functions:

Function
Description

SaveToString(string)

Saves the history instance to a JSON string using the history name

SaveToString(HistoryInfo)

Saves the history instance to a JSON string using the history info instance


Once you're done with those instances, you can unload them using one of the following functions:

Function
Description

Unload(string)

Removes the history instance from the list of registered instances using the history name

Unload(HistoryInfo)

Removes the history instance from the list of registered instances using the history info instance

chevron-rightHistoryInfo instancehashtag

The history info class can be constructed using a name and a list of history entries that will be pre-installed. This class contains the following properties:

Property
Description

HistoryName

Name of the history

HistoryEntries

A list of history entries

chevron-rightHistory entry manipulationhashtag

In addition to the above tools, you can also manipulate with the history entry list using one of the following functions and properties:

Property
Description

HistoryNames

Returns the name of all the history instances

GetHistoryEntries()

Gets an array of history entries that are added to the history instance

IsHistoryRegistered()

Checks to see whether a history instance is registered or not

Switch()

Replaces the list of history entries with a new set of entries

Append()

Appends a new history entry at the end of the list

Insert()

Inserts a new history entry somewhere in the list using a specified index

Remove()

Removes a history entry using a specified index

Clear()

Clears the list of history entries in a history instance

circle-info

The above functions require that a target history entry be registered, with the exception of HistoryNames and IsHistoryRegistered().


Extra functions

If you want to explore deeper than the surface, expand a section.

chevron-rightThe reader statehashtag

Each one of these functions creates a reader state, TermReaderState, that contains essential information about the current reader state, including, but not limited to:

  • Current text

  • Input prompt text

  • Current text position

  • Kill buffer

  • Reader settings

You can also check to see if the console reader facility is busy getting input or not. The property, Busy, indicates this by returning true if there is input to be entered by the user.

You can learn more about the reader state here:

Reader State

circle-info

The property, IsReaderBusy, only checks to see if the input reader is in use, while the Busy property checks to see if the code is waiting for input anywhere.

If you want to wait for user input to finish, you can call the WaitForInput() function in the TermReaderTools class.

chevron-rightPositioning toolshashtag

Your custom bindings can now change the cursor positioning when manipulating with text so that it becomes easier to make your custom bindings that use positioning tools.

Here are the functions you can use:

Function

GoLeftmost()

Changes the word position to the leftmost position, that is, the first letter.

GoRightmost()

Changes the word position to the rightmost position, that is, the last letter.

GoForward()

Changes the word position a step or a specified number of steps closer to the end of the text.

GoBack()

Changes the word position a step or a specified number of steps closer to the beginning of the text.

SeekTo()

Changes the word position to the selected zero-based position.

Once you're done changing positions, if you need to verify that you've changed the position to the correct position, you can use the Commit() function.

circle-info

It's not necessary to use the Commit() function at the end of each custom binding, because the reader uses this function automatically based on whether to update the position or not.

chevron-rightWriters and writinghashtag

You can use the text writers with the current reader settings by using TextWriterColor's WriteForReader() and its siblings, passing it the reader settings to take care of the margins.

Writing tools

You can also append or remove a string in the TermReaderTools class. This means that you can either append text to the end of the input, insert text to the current position, or remove text from either the current position or from a specific character index from the input string.

These are the functions that you can use:

Function
Description

GetMaximumInputLength()

Gets the maximum input length according to available space

InsertNewText()

Inserts a new text to the input

RemoveText()

Removes text from the input

chevron-rightConditionalshashtag

In addition to all the above features, you can also make your key binding beep under certain circumstances, such as if the current text position is at the start of the text and we're trying to move left, using one of the two conditional functions from the ConditionalTools class:

Function
Description

ShouldNot()

Specifies that the specified condition should not be true

Should()

Specifies that the specified condition should not be false

circle-info

If either of these functions' assertions have failed, either your computer or your speakers emits a beep sound upon going back to the input mode.

circle-info

In order to set OperationWasInvalid to true, you must put a conditional return by referring to the ConditionalTools and negating the ShouldNot condition like this:

Last updated