ReadLine - Line Editor with History

ReadLine ( Source | Full Release )

ReadLine 2.2 (C) Jon Ripley

Installation
============

To install the ReadLine library copy the files ReadLine.bbc and ReadLine.txt 
into the BBC BASIC for Windows LIB directory, this should be "C:\Program 
Files\BBC BASIC for Windows\LIB" if you have installed BBC BASIC for Windows 
in the default installation directory.  If you wish to remove this library 
you should delete these two files.

Usage
=====

To make use of the functions in this library in your own programs you should 
add the following line to the initialisation routine.

      INSTALL @lib$+"ReadLine.bbc"

To enable the ReadLine library you should replace instances of INPUT in your 
code with calls to the functions in the ReadLine library.

      Existing code:                   Replace with:
      INPUT text$                      PRINT "? ";
                                       text$ = FN_ReadLine

      INPUT number                     PRINT "? ";
                                       number = VAL FN_ReadLine

      INPUT ;text$                     text$ = FN_ReadLine

      INPUT ;number                    number = VAL FN_ReadLine

      INPUT "Prompt "text$             PRINT "Prompt ? ";
                                       text$ = FN_ReadLine

      INPUT "Prompt "number            PRINT "Prompt ? ";
                                       number = VAL FN_ReadLine

      INPUT "Prompt ";text$            text$ = FN_ReadLine

      INPUT "Prompt ";number           number = VAL FN_ReadLine
 

Your program now has a full line editor which remembers the last 256 lines 
of text entered.

Keyboard bindings
=================

When using the ReadLine library to read user input, twenty-seven keys have 
special meanings.

Miscellaneous:
    Insert     - Toggle Insert/Overwrite mode
    Enter      - End input
    Esc        - Terminate input, returns NUL string
    Ctrl+J     - As Enter but does not store in line history
    Ctrl+S     - Toggle case of current character
    Ctrl+T     - Transpose adjacent characters
    Ctrl+G     - Sound system bell

Movement:
    Left       - Move left one character
    Right      - Move right one character
    Ctrl+Left  - Move left one word
    Ctrl+Right - Move right one word
    Home       - Move to start
    End        - Move to end

Clipboard:
    Ctrl+C     - Copy line to clipboard
    Ctrl+X     - Cut line to clipboard
    Ctrl+V     - Paste text from clipboard

Deletion:
    BkSp       - Delete left one character
    Del        - Delete right one character
    Ctrl+U     - Clear input buffer
    Ctrl+Home  - Delete to start
    Ctrl+End   - Delete to end

History:
    Up         - Previous input
    Down       - Next input
    Ctrl+Up    - Select first input in buffer
    Ctrl+Down  - Select last input
    Shift+Up   - Skip back 16 inputs
    Shift+Down - Skip forward 16 inputs

The six keys related to the input history are only available if the history 
buffer has not been disabled.

You are free to reproduce the above keyboard bindings in the documentation 
for any software written using the ReadLine library.

Interface
=========

DEF FN_ReadLine
---------------
Read a line of text, characters 32 to 126 are permitted and the string can 
be a maximum of 65,535 characters in length.

Usage example:

      PRINT "What is your name? ";
      name$ = FN_ReadLine
      PRINT "Hello ";name$"."

FN_ReadLine is equivalent to:

      length% = 65536
      DIM buffer% LOCAL length%
      strlen% = FN_ReadLineF(buffer%, length%, "~", 1)
      REM The string can be accessed via $buffer%

DEF FN_ReadPassword
-------------------
Read a password, characters 32 to 126 are permitted, the string can be a 
maximum of 65,535 characters in length.  Full line editing functions are 
available with the exception of the line history which is disabled.  
Asterisks are displayed in place of any text the user inputs.

Usage example:

      PRINT "Please enter your pass phrase: ";
      passphrase$ = FN_ReadPassword

FN_ReadPassword is equivalent to:

      length% = 65536
      DIM buffer% LOCAL length%
      strlen% = FN_ReadLineF(buffer%, length%, "~", 2)
      REM The string can be accessed via $buffer%

DEF FN_ReadLineS(length%, valid$, flags%)
-----------------------------------------
This call is equivalent to FN_ReadLineF and returns the text entered by the 
user with the advantage that no buffer needs to be set up.  Refer to the 
documentation for FN_ReadLineF for the meaning of the parameters.

Usage Example:

      PRINT "What is your name? ";
      name$ = FN_ReadLineS(256, "~", 1)
      PRINT "How old are you? ";
      age% = VAL FN_ReadLineS(3, "0-9", 1)
      PRINT "Hello ";name$" you are ";age%;" years old."

DEF FN_ReadLineF(buffer%, length%, valid$, flags%)
--------------------------------------------------
FN_ReadLineF is the master input routine which provides the most flexible 
way of using the ReadLine library. called by FN_ReadLine, FN_ReadPassword, 
FN_ReadLineS and the line editor history routines.

    buffer% - Pointer to buffer to hold text
    length% - Size of buffer%
    valid$  - Validation string
    flags%  -
          Bits 0-7
              0  - No echo
              1  - Echo input
              2  - Echo '*'s (equivalent to 256 + 42)
              n  - Character to echo in range 32 to 126 (must set bit 8)
          Bit 8  - Echo character in bits 0-7 (add 256 to flags% to set this 
                   option)
          Bit 9  - Disable line history (add 512 to flags% to set this 
                   option)
          Bit 10 - Do not beep on full buffer (add 1024 to flags% to set 
                   this option)
          Bits 11 to 31 are reserved for internal use and must be set to zero

The function returns the number of characters read.  The string stored in 
buffer% can be accessed using $buffer%.

The validation string valid$ allows a list of allowed or disallowed input 
characters to be specified. List individual characters as "0123456789" or 
ranges of characters like "0-9".  To disallow specific characters or a range 
of characters place them after a tilde "~" as shown below.  The characters "-
" (range), "~" disallow and '\' (escape) have special meanings, if you need 
to specify these characters as explicitly allowed or disallowed prefix them 
with a backslash "\".

Examples:

    0-9A-Z~Q  Allows 0..9, A..P, R..Z
    ~X        Allow all characters but X
    ~         Allow all characters
    \-\~\\    Allow characters -, ~ and \
    ~\~       Allow all characters except ~

Usage example:

      hex$ = FN_ReadLineF(buffer%, 64, "0-9A-F", 1)
      name$ = FN_ReadLineF(buffer%, 128, "A-Za-z ", 1)
      age% = VAL FN_ReadLine(buffer%, 3, "0-9", 1)
      secret$ = VAL FN_ReadLine(buffer%, 64, "~", 0)

Text pasted from the clipboard and text recalled from the line history is 
filtered to only allow valid characters.

Line Editor History
===================

DEF PROC_LoadHistory(file$)
---------------------------
Load line history from file$.

Usage example:

      PROC_LoadHistory(@dir$+"history.txt")

DEF PROC_SaveHistory(file$)
---------------------------
Save line history to file$

Usage example:

      PROC_SaveHistory(@dir$+"history.txt")

DEF PROC_ClearHistory
---------------------
Clear line history

Usage example:

      PROC_ClearHistory

DEF PROC_DumpHistory
--------------------
Dump line history

Usage example:

      PROC_DumpHistory

This routine is equivalent to:

      FOR i% = FN_EnumerateHistory TO 0 STEP -1
        PRINT RIGHT$("000"+STR$i%,3)":";FN_GetHistory(i%)
      NEXT i%

DEF FN_EnumerateHistory
-----------------------
Return the total number of items in history, or zero if the line history 
buffer is empty.

Usage example:

      lines% = FN_EnumerateHistory

DEF FN_GetHistoryItem(line%)
----------------------------
Return specified line from history, range is 0 to FNEnumerateHistory.
 
Usage example:

      PRINT "The first item in the line history is:"
      PRINT FN_GetHistory(0)

DEF PROC_SetHistory(lines%)
---------------------------
Set number of lines remembered in the history. Specify zero to disable the 
line history, the maximum permissible value is 16,777,215.  Use of this call 
to declare very small line history buffers is not recommended.

Usage example:

      INSTALL @lib$+"ReadLine.bbc"
      REM Reserve space for 16 lines of input history
      PROC_SetHistory(16)

NOTE: For this call to be successful PROC_SetHistory must be called before 
any other routine in the ReadLine library, if the call is unsuccessful this 
routine will exit without error.  The default history buffer will remember 
the last 255 lines of input.

Two lines of overhead are required by FN_ReadLineF; if you need a specific 
number of history lines add 2 to lines%.

DEF PROC_AddHistory(line$)
--------------------------
Append a line to the history buffer, as if it was the last line typed.

Usage example:

      PROC_AddHistory("Hello world!")

DEF PROC_RemoveHistoryItem(line%)
---------------------------------
Remove history item specified by its position from the history.

Usage example:

      PROC_RemoveHistoryItem(4)

DEF PROC_ReplaceHistoryItem(line%, line$)
-----------------------------------------
Replace history item specified by its position with the given line.

Usage example:

      PROC_ReplaceHistoryItem(4, "Hello world!")

Internal Calls
==============

The following routines are to perform various functions. Three routines 
which may be of general use are documented.

DEF FN_CursorIsEnabled
----------------------
Return TRUE if text cursor is enabled.

Usage example:

      IF FN_CursorIsEnabled THEN
        PRINT "Cursor is enabled."
      ELSE
        PRINT "Cursor is diabled."
      ENDIF

DEF FN_EscapeIsEnabled
----------------------
Return TRUE if Escape is enabled.

Usage example:

      IF FN_EscapeIsEnabled THEN
        PRINT "Escape is enabled."
      ELSE
        PRINT "Escape is diabled."
      ENDIF

DEF PROC_InvertVideo
--------------------
Switch foreground and background text colours.

Usage example:

      PRINT "This is an example of ";
      PROC_InvertVideo
      PRINT "inverted video";
      PROC_InvertVideo
      PRINT "."

DEF PROC_MoveCursor(offset%, flag%)
-----------------------------------
This call is for internal use only.

DEF PROC_WRCH(char%, flag%)
---------------------------
This call is for internal use only.

DEF PROC_WRSTR(string$, flag%)
------------------------------
This call is for internal use only.

Advanced Use
============

DEF FN_ReadLineF(buffer%, length%, valid$, flags%)
--------------------------------------------------
All the line history routines call FN_ReadLineF to perform the requested 
actions.

    buffer% - Pointer to buffer holding text
    length% - Size of buffer
    valid$  - Validation string (Ignored)
    flags%  -
          Bits  0 - 23 Line number
          Bits 24 - 31 Command

Commands:
    &01 - Load line history to file specified in $buffer%
    &02 - Save line history to file specified in $buffer%
    &03 - Clear line history
    &04 - Dump line history
    &05 - Return number of items in history
    &06 - Return specified line from history in $buffer%
    &07 - Set number of lines remembered in the history
    &08 - Append a line to the history buffer with the text in $buffer%
    &09 - Remove history item
    &0A - Replace history item with text in $buffer%

When used in this manner FN_ReadLineF returns zero if the operation was 
successful or non-zero if the operation failed.  When called with reason 
code &05 FN_ReadLineF returns the number of items in the line history.