Class REPLHelper

java.lang.Object
org.daiitech.naftah.utils.repl.REPLHelper

public final class REPLHelper extends Object
A utility class providing helper methods and constants used by the REPL (Read-Eval-Print Loop) in the Naftah programming environment. This includes prompt formatting, line reader configuration, terminal setup, history handling, and string/character constants for parsing and highlighting.

This class is non-instantiable and all members are static.

Author:
Chakib Daii
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final String
    Message displayed when the application is closed.
    private static final String
    Message displayed when text is successfully copied to the clipboard.
    private static final String
    Command name for copying the last printed output to the clipboard.
    private static final String
    Command name for copying text to the clipboard.
    static final char
    Default character that can be used to escape other characters.
    static final Set<Character>
    Set form of the escape characters for faster lookup.
    static final char[]
    Characters that can be used to escape other characters.
    static final String
    Regex pattern for matching escape characters or escape + newline.
    static final AtomicReference<String>
    Holds the last printed output as a thread-safe reference.
    static final com.vladsch.flexmark.parser.Parser
    A reusable instance of Parser from the Flexmark library used for parsing Markdown content into an abstract syntax tree (AST).
    static boolean
    Indicates if multiline mode is active in the REPL.
    private static final String
    Command name for pasting text from the clipboard.
    static final char[]
    Quotation characters allowed in the REPL.
    static final String
    Regex for matching command names.
    static final String
    Regex for matching variable names.
    static final String
    Public RTL multiline prompt with optional reshaping for display.
    private static final String
    Right-to-left multiline prompt marker value.
    static final String
    The formatted RTL pagination prompt displayed to the user.
    private static final String
    The raw prompt message (in Arabic) used during right-to-left (RTL) pagination.
    static final String
    Public RTL prompt with optional reshaping for display.
    private static final String
    Right-to-left prompt value.
    static boolean
    Indicates if a text was just pasted to the REPL.
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    private
    Private constructor to prevent instantiation.
  • Method Summary

    Modifier and Type
    Method
    Description
    static void
    Clears the console screen using ANSI escape codes.
    static void
    Copies the given text to the system clipboard.
    static String
    getHistoryContent(org.jline.reader.History history, Set<String> extraValidText, Instant startingFrom, Predicate<String> codeValidationPredicate)
    Retrieves the content of the REPL history as a string, filtered by timestamp and a validation predicate.
    static org.jline.reader.LineReader
    getLineReader(org.jline.terminal.Terminal terminal)
    Creates and returns a LineReader instance configured with custom parsing, syntax highlighting, and autocompletion designed for Arabic/Naftah syntax.
    static org.jline.reader.LineReader
    getLineReader(org.jline.terminal.Terminal terminal, Collection<String> completions)
    Creates and returns a LineReader instance configured with a custom set of completions and syntax highlighting tailored for Arabic/Naftah input.
    static String
    Parses a Markdown string using the MARKDOWN_PARSER and converts it into a plain-text formatted representation suitable for terminal output.
    static String
    getMarkdownNodeAsString(com.vladsch.flexmark.util.ast.Node node, int indent)
    Recursively processes and converts a Markdown AST Node from the Flexmark library into a formatted plain-text representation, preserving structure and indentation.
    static org.jline.terminal.Terminal
    Builds and returns a configured Terminal for use in the REPL.
    static String
    Retrieves text content from the system clipboard.
    static void
    print(org.jline.terminal.Terminal terminal, String str)
    Writes the given string to the terminal output without a newline.
    static void
    printFullHistory(org.jline.reader.History history, Set<String> extraValidText)
    Prints the full REPL history to the console using the default code validation.
    static void
    printHistory(org.jline.reader.History history, Set<String> extraValidText, Instant startingFrom)
    Prints the REPL history to the console, optionally filtering entries starting from a specific timestamp.
    static void
    println(org.jline.reader.LineReader reader)
    Prints a platform-dependent newline to the terminal.
    static void
    println(org.jline.reader.LineReader reader, String s)
    Prints the given string followed by a newline to the terminal via the line reader.
    static String
    Cleans and escapes the input string for proper handling in the REPL or syntax highlighting.
    static org.jline.utils.AttributedString
    rightAlign(org.jline.utils.AttributedString str, int width)
    Aligns the given attributed string to the right side of the terminal, applying appropriate spacing and appending the prompt.
    static void
    sanitizeHistory(org.jline.reader.History history, Set<String> extraValidText)
    Sanitizes the REPL history by removing invalid entries using the default code validation.
    static void
    sanitizeHistory(org.jline.reader.History history, Set<String> extraValidText, Predicate<String> codeValidationPredicate)
    Sanitizes the REPL history by removing invalid entries using a custom code validation predicate.
    static void
    saveHistorySnippet(org.jline.reader.History history, Instant startingFrom)
    Saves a snippet of the REPL history to a timestamped file using the default code validation.
    static void
    saveHistorySnippet(org.jline.reader.History history, Set<String> extraValidText, Instant startingFrom, Predicate<String> codeValidationPredicate)
    Saves a snippet of the REPL history to a timestamped file using a custom code validation predicate.
    static void
    setupHistoryConfig(org.jline.reader.LineReader reader, String historyPath)
    Configures history settings for the REPL, including history file path, size limits, and duplicate entry handling.
    static void
    setupKeyBindingsConfig(org.jline.reader.LineReader reader)
    Configures custom key bindings and clipboard-related widgets for a given LineReader.
    static void
    setupTerminalCapabilities(org.jline.terminal.Terminal terminal)
    Configures terminal capabilities, e.g., making the cursor invisible.
    static boolean
    shouldQuit(org.jline.reader.LineReader reader)
    Prompts the user with a localized RTL pagination message asking whether to continue or quit.
    static void
    waitForUserInterruption(org.jline.reader.LineReader reader)
    Blocks execution until the user interrupts with Ctrl+C, displaying a friendly message in Arabic.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • LAST_PRINTED

      public static final AtomicReference<String> LAST_PRINTED
      Holds the last printed output as a thread-safe reference.

      This can be used for operations such as copying the last output to the clipboard or accessing it programmatically. The use of AtomicReference ensures that updates to the last printed value are thread-safe.

    • MARKDOWN_PARSER

      public static final com.vladsch.flexmark.parser.Parser MARKDOWN_PARSER
      A reusable instance of Parser from the Flexmark library used for parsing Markdown content into an abstract syntax tree (AST).

      This parser can be used to convert raw Markdown strings into a structured Node tree that can be traversed or rendered.

      It is recommended to reuse this instance instead of creating new ones for performance.

    • REGEX_VARIABLE

      public static final String REGEX_VARIABLE
      Regex for matching variable names.
      See Also:
    • REGEX_COMMAND

      public static final String REGEX_COMMAND
      Regex for matching command names.
      See Also:
    • DEFAULT_ESCAPE_CHAR

      public static final char DEFAULT_ESCAPE_CHAR
      Default character that can be used to escape other characters.
      See Also:
    • ESCAPE_CHARS

      public static final char[] ESCAPE_CHARS
      Characters that can be used to escape other characters.
    • ESCAPE_CHAR_SET

      public static final Set<Character> ESCAPE_CHAR_SET
      Set form of the escape characters for faster lookup.
    • ESCAPE_CHARS_REGEX

      public static final String ESCAPE_CHARS_REGEX
      Regex pattern for matching escape characters or escape + newline.
    • QUOTE_CHARS

      public static final char[] QUOTE_CHARS
      Quotation characters allowed in the REPL.
    • RTL_PROMPT_VALUE

      private static final String RTL_PROMPT_VALUE
      Right-to-left prompt value.
      See Also:
    • RTL_PROMPT

      public static final String RTL_PROMPT
      Public RTL prompt with optional reshaping for display.
    • RTL_MULTILINE_PROMPT_VALUE

      private static final String RTL_MULTILINE_PROMPT_VALUE
      Right-to-left multiline prompt marker value.
      See Also:
    • RTL_MULTILINE_PROMPT

      public static final String RTL_MULTILINE_PROMPT
      Public RTL multiline prompt with optional reshaping for display.
    • RTL_PAGINATION_PROMPT_VALUE

      private static final String RTL_PAGINATION_PROMPT_VALUE
      The raw prompt message (in Arabic) used during right-to-left (RTL) pagination.

      This message is displayed to the user between paginated content chunks, instructing them to press Enter to continue or enter one of the exit commands ('q', 'quit', or 'خروج') to terminate navigation and return to the main program.

      See Also:
    • RTL_PAGINATION_PROMPT

      public static final String RTL_PAGINATION_PROMPT
      The formatted RTL pagination prompt displayed to the user.

      If Arabic text shaping is enabled (via shouldReshape()), this version uses a reshaped (visually adjusted) version of RTL_PAGINATION_PROMPT_VALUE. Otherwise, it falls back to the original raw form.

    • COPY_TO_CLIPBOARD_COMMAND

      private static final String COPY_TO_CLIPBOARD_COMMAND
      Command name for copying text to the clipboard.
      See Also:
    • COPIED_TO_CLIPBOARD_MSG

      private static final String COPIED_TO_CLIPBOARD_MSG
      Message displayed when text is successfully copied to the clipboard. Arabic: "[تم النسخ إلى ذاكرة النسخ بنجاح]"
      See Also:
    • COPY_LAST_PRINTED_TO_CLIPBOARD_COMMAND

      private static final String COPY_LAST_PRINTED_TO_CLIPBOARD_COMMAND
      Command name for copying the last printed output to the clipboard.
      See Also:
    • PASTE_FROM_CLIPBOARD_COMMAND

      private static final String PASTE_FROM_CLIPBOARD_COMMAND
      Command name for pasting text from the clipboard.
      See Also:
    • MULTILINE_IS_ACTIVE

      public static boolean MULTILINE_IS_ACTIVE
      Indicates if multiline mode is active in the REPL.
    • TEXT_PASTE_DETECTED

      public static boolean TEXT_PASTE_DETECTED
      Indicates if a text was just pasted to the REPL.
    • CLOSING_MSG

      public static final String CLOSING_MSG
      Message displayed when the application is closed.
      See Also:
  • Constructor Details

    • REPLHelper

      private REPLHelper()
      Private constructor to prevent instantiation. Always throws a NaftahBugError when called.
  • Method Details

    • getTerminal

      public static org.jline.terminal.Terminal getTerminal() throws IOException
      Builds and returns a configured Terminal for use in the REPL.
      Returns:
      a Terminal instance with UTF-8 encoding and color capabilities
      Throws:
      IOException - if terminal initialization fails
    • getLineReader

      public static org.jline.reader.LineReader getLineReader(org.jline.terminal.Terminal terminal)
      Creates and returns a LineReader instance configured with custom parsing, syntax highlighting, and autocompletion designed for Arabic/Naftah syntax.

      The returned LineReader supports:

      • Parsing with custom regex for variables and commands
      • Handling of escaped new lines and quoted strings
      • Syntax highlighting combining the original highlighter and Arabic/Naftah specific rules
      • Autocompletion with static and runtime completions including lexer literals
      Parameters:
      terminal - the Terminal instance to which the LineReader will be bound
      Returns:
      a configured LineReader supporting Arabic/Naftah input
    • getLineReader

      public static org.jline.reader.LineReader getLineReader(org.jline.terminal.Terminal terminal, Collection<String> completions)
      Creates and returns a LineReader instance configured with a custom set of completions and syntax highlighting tailored for Arabic/Naftah input.

      This method allows providing a specific collection of completion strings which will be used by the autocompleter.

      Parameters:
      terminal - the Terminal instance to which the LineReader will be bound
      completions - a Collection of completion strings for the autocompleter
      Returns:
      a configured LineReader with custom completions and Arabic-specific highlighting
    • setupTerminalCapabilities

      public static void setupTerminalCapabilities(org.jline.terminal.Terminal terminal)
      Configures terminal capabilities, e.g., making the cursor invisible.
      Parameters:
      terminal - the terminal to configure
    • setupHistoryConfig

      public static void setupHistoryConfig(org.jline.reader.LineReader reader, String historyPath)
      Configures history settings for the REPL, including history file path, size limits, and duplicate entry handling.
      Parameters:
      reader - the LineReader to configure
      historyPath - the path of history to use
    • setupKeyBindingsConfig

      public static void setupKeyBindingsConfig(org.jline.reader.LineReader reader)
      Configures custom key bindings and clipboard-related widgets for a given LineReader.

      This method performs the following actions:

      • Swaps the left and right arrow keys for cursor movement.
      • Adds widgets for clipboard operations:
        • copy-to-clipboard: Copies the current buffer to the clipboard.
        • copy-last-output: Copies the last printed output to the clipboard.
        • paste-from-clipboard: Pastes clipboard content into the current buffer at the cursor position.
      • Binds keyboard shortcuts for clipboard and text editing operations:
        • Alt+C = copy current buffer
        • Alt+L = copy last printed output
        • Alt+V = paste from clipboard
        • Alt+M = mark start
        • Alt+X = cut selected region
        • Alt+K = copy selected region
        • Alt+Y = paste (yank)
      Parameters:
      reader - the LineReader to configure with custom key bindings and clipboard widgets
    • processPastedText

      public static String processPastedText(String input)
      Cleans and escapes the input string for proper handling in the REPL or syntax highlighting.

      The method performs the following steps:

      • Removes block comments enclosed in ---* ... *---.
      • Removes single-line comments starting with ---.
      • Removes empty or whitespace-only lines.
      • Prepends each remaining line with a space followed by the default escape character and appends a newline character.
      This is useful to sanitize user input while preserving line separation and escaping for further processing, such as syntax highlighting or multi-line pasting.
      Parameters:
      input - the raw input string that may contain comments, empty lines, and unescaped characters
      Returns:
      a cleaned and escaped string where all comments and empty lines are removed, and remaining lines are prepended with the escape character and terminated with a newline
    • print

      public static void print(org.jline.terminal.Terminal terminal, String str)
      Writes the given string to the terminal output without a newline.
      Parameters:
      terminal - the terminal to write to
      str - the string to output
    • println

      public static void println(org.jline.reader.LineReader reader, String s)
      Prints the given string followed by a newline to the terminal via the line reader.
      Parameters:
      reader - the line reader bound to the terminal
      s - the string to print
    • println

      public static void println(org.jline.reader.LineReader reader)
      Prints a platform-dependent newline to the terminal. Also triggers a line redraw if using LineReaderImpl.
      Parameters:
      reader - the line reader
    • copyToClipboard

      public static void copyToClipboard(String text)
      Copies the given text to the system clipboard.
      Parameters:
      text - the text to copy
    • pasteFromClipboard

      public static String pasteFromClipboard()
      Retrieves text content from the system clipboard.

      If the clipboard does not contain a string or an error occurs, an empty string is returned.

      Returns:
      the text from the clipboard, or an empty string if unavailable
    • rightAlign

      public static org.jline.utils.AttributedString rightAlign(org.jline.utils.AttributedString str, int width)
      Aligns the given attributed string to the right side of the terminal, applying appropriate spacing and appending the prompt.
      Parameters:
      str - the input string to align
      width - the total width of the terminal line
      Returns:
      a right-aligned AttributedString
    • shouldQuit

      public static boolean shouldQuit(org.jline.reader.LineReader reader)
      Prompts the user with a localized RTL pagination message asking whether to continue or quit.

      Reads a line of input and checks if the user wants to quit based on recognized quit commands.

      Parameters:
      reader - the LineReader instance used to read user input
      Returns:
      true if the input matches "q", "quit", or "خروج" (case-insensitive), otherwise false
    • waitForUserInterruption

      public static void waitForUserInterruption(org.jline.reader.LineReader reader)
      Blocks execution until the user interrupts with Ctrl+C, displaying a friendly message in Arabic.

      This is useful at the end of scripts or sessions to prevent the terminal from closing immediately. The user sees the message and can exit gracefully using Ctrl+C.

      The method uses a LineReader from JLine to handle input and detect the interruption. All other key presses are ignored.

      Parameters:
      reader - the JLine LineReader used to read input and detect Ctrl+C
    • clearScreen

      public static void clearScreen()
      Clears the console screen using ANSI escape codes. Moves the cursor to the top-left corner.
    • getMarkdownNodeAsString

      public static String getMarkdownNodeAsString(com.vladsch.flexmark.util.ast.Node node, int indent)
      Recursively processes and converts a Markdown AST Node from the Flexmark library into a formatted plain-text representation, preserving structure and indentation.

      This method supports a wide variety of Markdown elements, including:

      • Heading
      • Paragraph
      • Text
      • SoftLineBreak / HardLineBreak
      • ThematicBreak
      • BulletList / OrderedList
      • ListItem
      • Emphasis / StrongEmphasis
      • Code / FencedCodeBlock
      • Link / Image
      • BlockQuote

      Any unknown or unsupported node types are recursively processed if they contain children.

      Parameters:
      node - the root Markdown Node to convert
      indent - the indentation level to apply (used for nested structures)
      Returns:
      a formatted string representation of the node and its children
    • getMarkdownAsString

      public static String getMarkdownAsString(String topicContent)
      Parses a Markdown string using the MARKDOWN_PARSER and converts it into a plain-text formatted representation suitable for terminal output.

      This is typically used to display user guides, help documentation, or any content written in Markdown in a readable form within a terminal interface.

      Parameters:
      topicContent - the raw Markdown input as a String
      Returns:
      the formatted plain-text representation of the Markdown content
    • saveHistorySnippet

      public static void saveHistorySnippet(org.jline.reader.History history, Instant startingFrom) throws IOException
      Saves a snippet of the REPL history to a timestamped file using the default code validation.
      Parameters:
      history - the REPL history to save
      startingFrom - only include entries after this timestamp, or all if null
      Throws:
      IOException - if an error occurs while writing the snippet file
    • saveHistorySnippet

      public static void saveHistorySnippet(org.jline.reader.History history, Set<String> extraValidText, Instant startingFrom, Predicate<String> codeValidationPredicate) throws IOException
      Saves a snippet of the REPL history to a timestamped file using a custom code validation predicate.
      Parameters:
      history - the REPL history to save
      extraValidText - additional lines that should always be considered valid
      startingFrom - only include entries after this timestamp, or all if null
      codeValidationPredicate - a predicate to determine if a line of code is valid and should be saved
      Throws:
      IOException - if an error occurs while writing the snippet file
    • printFullHistory

      public static void printFullHistory(org.jline.reader.History history, Set<String> extraValidText)
      Prints the full REPL history to the console using the default code validation.
      Parameters:
      history - the REPL history to print
      extraValidText - additional lines that should always be considered valid
    • printHistory

      public static void printHistory(org.jline.reader.History history, Set<String> extraValidText, Instant startingFrom)
      Prints the REPL history to the console, optionally filtering entries starting from a specific timestamp.
      Parameters:
      history - the REPL history to print
      extraValidText - additional lines that should always be considered valid
      startingFrom - only include entries after this timestamp, or all if null
    • getHistoryContent

      public static String getHistoryContent(org.jline.reader.History history, Set<String> extraValidText, Instant startingFrom, Predicate<String> codeValidationPredicate)
      Retrieves the content of the REPL history as a string, filtered by timestamp and a validation predicate.
      Parameters:
      history - the REPL history
      extraValidText - additional lines that should always be considered valid
      startingFrom - only include entries after this timestamp, or all if null
      codeValidationPredicate - a predicate to determine if a line of code is valid and should be included
      Returns:
      a string containing all valid history lines separated by line breaks
    • sanitizeHistory

      public static void sanitizeHistory(org.jline.reader.History history, Set<String> extraValidText) throws IOException
      Sanitizes the REPL history by removing invalid entries using the default code validation.

      Only entries that pass validation or are contained in extraValidText are preserved. The sanitized history replaces the original in memory and on disk.

      Parameters:
      history - the REPL history to sanitize
      extraValidText - additional lines that should always be considered valid
      Throws:
      IOException - if an error occurs while saving the sanitized history
    • sanitizeHistory

      public static void sanitizeHistory(org.jline.reader.History history, Set<String> extraValidText, Predicate<String> codeValidationPredicate) throws IOException
      Sanitizes the REPL history by removing invalid entries using a custom code validation predicate.

      Only entries that pass codeValidationPredicate or are contained in extraValidText are preserved. The sanitized history replaces the original in memory and on disk.

      Parameters:
      history - the REPL history to sanitize
      extraValidText - additional lines that should always be considered valid
      codeValidationPredicate - a predicate to determine if a line of code is valid and should be preserved
      Throws:
      IOException - if an error occurs while saving the sanitized history