Skip to content

tui

tuprolog.tui

2ppy TUI: a terminal IDE for Prolog, built with Textual.

Run it with 2ppy-tui or python -m tuprolog.tui (--help lists the options: files to open, theory, query, standard input, and how solvers are built: dialect, libraries, dynamic knowledge base, unificator, flags, timeout; see parser). As 2P-Kt's Swing IDE, it shows pages (as tabs), each with a theory to edit, a query to solve against it (both colored by syntax), the timeout of its resolutions, and panels (as tabs, at the bottom) for the solutions, the standard input, output and error of the solver, its warnings, the problems found in the theory, and what the solver holds: operators (more can be added), flags (editable), libraries, static and dynamic knowledge bases (flags and libraries with their documentation, F1). Arrow keys move among controls, unless the focused one uses them (e.g. editors). Pages either have their own text (scratch pages, ctrl+t) or edit files (ctrl+n creates one, ctrl+o opens one, ctrl+s saves it). F5, F6 and F7 ask for 1, 10 and 100 solutions (the Solve all button, for all of them) (then for the next ones), F8 stops a resolution, F9 resets the solver, and ctrl+q quits (asking to confirm if files have unsaved changes).

The IDE holds no logic of its own: it renders the state of 2P-Kt's GUI application (see tuprolog.gui), sends it the actions of the user, and fulfils its effects (e.g. asking for a path, then writing the file). It talks to it through a GuiBridge: JvmGuiBridge runs 2P-Kt's, converting its JVM states into snapshots (Snapshot, Page, ...), and the IDE's actions (e.g. Solve) into JVM ones. ReloadDecision, Solution and Solve are importable by name, but left out of __all__, as other tuprolog modules export the same names.

Examples:

$ 2ppy-tui
See Also
  • tuprolog.gui, the GUI application the IDE renders.
  • tuprolog.repl, for a command-line shell.

PANELS module-attribute

PANELS: tuple[Panel, ...] = (
    "SOLUTIONS",
    "STDIN",
    "STDOUT",
    "STDERR",
    "WARNINGS",
    "DIAGNOSTICS",
    "OPERATORS",
    "FLAGS",
    "LIBRARIES",
    "STATIC_KB",
    "DYNAMIC_KB",
)

The panels the IDE shows, in order (as 2P-Kt's Swing IDE).

PrologTui

PrologTui(
    bridge: GuiBridge | None = None,
    startup: Startup | None = None,
)

Bases: App[None]

A terminal IDE for Prolog: pages of theories to edit and queries to solve against them.

It renders the state of 2P-Kt's GUI application, sends it actions, and fulfils its effects (file dialogs, reading and writing files, confirmations, clipboard), through a bridge.

Parameters:

Name Type Description Default
bridge GuiBridge | None

The bridge to the GUI application; by default, a JvmGuiBridge running 2P-Kt's.

None
startup Startup | None

What to open at startup; by default, a scratch page.

None

page property

page: Page | None

The page shown in the widgets, if any.

dispatch

dispatch(action: Action) -> None

Sends an action to the GUI application.

render_state async

render_state(message: StateChanged) -> None

Renders a new snapshot (on Textual's event loop).

source_changed

source_changed(event: Changed) -> None

Sends the edited theory to the model.

query_changed

query_changed(event: Changed) -> None

Sends the edited query to the model.

query_submitted

query_submitted() -> None

Solves (or continues) the query.

stdin_changed

stdin_changed(event: Changed) -> None

Sends the edited standard input to the model.

page_activated

page_activated(event: TabActivated) -> None

Selects the page of the activated tab.

panel_activated

panel_activated(event: TabActivated) -> None

Marks the activated panel as read.

diagnostic_selected

diagnostic_selected(event: OptionSelected) -> None

Moves the cursor of the editor where the selected diagnostic is.

flag_selected

flag_selected(event: RowSelected) -> None

Asks for a new value of the selected flag.

timeout_changed

timeout_changed(event: Submitted | Blurred) -> None

Sends the edited timeout to the model, if valid.

flag_highlighted

flag_highlighted() -> None

Previews the documentation of the highlighted flag.

library_symbol_highlighted

library_symbol_highlighted() -> None

Previews the documentation of the highlighted library, or symbol.

library_symbol_selected

library_symbol_selected(event: NodeSelected) -> None

Shows the documentation of the selected symbol (libraries expand, or collapse).

documentation_pressed

documentation_pressed(event: Pressed) -> None

Shows the documentation of what the panel of the button highlights.

action_documentation

action_documentation() -> None

Shows the documentation of what the flags or libraries panel highlights, if shown.

add_operator

add_operator() -> None

Asks for an operator, and declares it at the end of the theory (with op/3).

clear_solutions

clear_solutions() -> None

Forgets the concluded resolutions of the current page.

control_pressed

control_pressed(event: Pressed) -> None

Runs the command of a control button.

action_solve

action_solve(mode: Mode) -> None

Solves the query of the current page, or asks for more solutions.

action_stop

action_stop() -> None

Stops the resolution of the current page.

action_reset

action_reset() -> None

Resets the solver of the current page.

action_new_scratch_page

action_new_scratch_page() -> None

Creates a scratch page.

action_new_document_page

action_new_document_page() -> None

Creates a page editing a new file.

action_open_document

action_open_document() -> None

Opens a file in a new page.

action_save

action_save() -> None

Saves the file of the current page.

action_save_as

action_save_as() -> None

Saves the file of the current page elsewhere.

action_reload

action_reload() -> None

Reloads the file of the current page.

action_close_page

action_close_page() -> None

Closes the current page.

action_request_exit

action_request_exit() -> None

Asks to quit (confirming if files have unsaved changes).

report_error

report_error(message: BridgeError) -> None

Shows an error of the GUI application.

handle_effect

handle_effect(message: EffectRequested) -> None

Fulfils an effect (on Textual's event loop).

GuiBridge

Bases: Protocol

What the terminal IDE needs from a GUI application.

Callbacks may be called on any thread: the IDE forwards them to its own event loop.

start

start(
    on_state: Callable[[Snapshot], object],
    on_effect: Callable[[Effect], object],
    on_error: Callable[[str], object],
) -> None

Starts the application, which reports states, effects and errors to the callbacks.

dispatch

dispatch(action: Action) -> None

Enqueues an action: actions are applied in order.

close

close() -> None

Shuts the application down; idempotent.

is_timeout

is_timeout(text: str) -> bool

Whether text is a timeout (e.g. "2s 500ms", or "none"), for tuprolog.tui.ChangeTimeout.

analyze

analyze(
    source: str,
    operators: tuple[tuple[int, str, str], ...] = (),
) -> tuple[SyntaxToken, ...]

The tokens of Prolog text, given the (priority, specifier, name) of extra operators.

documentation_preview

documentation_preview(markdown: str) -> str

A short preview of the Markdown documentation of a symbol.

JvmGuiBridge

JvmGuiBridge(
    profiles: Iterable[SolverProfile] | None = None,
    timeout: float = 5.0,
    flags: Mapping[str, str | Term] | None = None,
    scheduling: Scheduling = "concurrent",
)

A GuiBridge running 2P-Kt's GUI application (a tuprolog.gui.GuiFacade), converting its JVM states and effects into tuprolog.tui snapshots and effects, and actions the other way round.

Parameters:

Name Type Description Default
profiles Iterable[SolverProfile] | None

The solver profiles (see tuprolog.gui.solver_profile); by default, Prolog's.

None
timeout float

The default timeout of resolutions, in seconds.

5.0
flags Mapping[str, str | Term] | None

The flags of every solver (names to values, as terms or their Prolog text).

None
scheduling Scheduling

Whether resolutions of different pages may run concurrently ("concurrent"), or starting one stops the others ("single").

'concurrent'

Resolution dataclass

Resolution(
    status: str = "IDLE",
    query: str | None = None,
    solutions: tuple[Solution, ...] = (),
    error: str | None = None,
    can_solve: bool = True,
    can_continue: bool = False,
    can_stop: bool = False,
)

The current resolution of a page, and the commands it allows.

HistoryEntry dataclass

HistoryEntry(
    query: str,
    solutions: tuple[Solution, ...],
    status: str,
    error: str | None = None,
)

A concluded resolution.

SyntaxToken dataclass

SyntaxToken(
    category: str,
    start: tuple[int, int],
    end: tuple[int, int],
)

A classified span of Prolog text, for syntax highlighting: category is the name of a tuprolog.gui.SemanticCategory, start and end (exclusive) are 0-based (line, column).

DiagnosticEntry dataclass

DiagnosticEntry(
    message: str,
    line: int | None = None,
    column: int | None = None,
)

A problem found in the theory, at a 0-based line and column if known.

LibraryEntry dataclass

LibraryEntry(
    alias: str,
    predicates: tuple[str, ...] = (),
    operators: tuple[str, ...] = (),
    functions: tuple[str, ...] = (),
    help: str = "",
    documentation: tuple[tuple[str, str], ...] = (),
)

A library of a solver: its alias, the predicates, operators and functions it defines, its help, and the documentation of its symbols (as pairs of a symbol, as listed, and its help). Helps are in Markdown.

Inspection dataclass

Inspection(
    operators: tuple[tuple[int, str, str], ...] = (),
    flags: tuple[tuple[str, str, str], ...] = (),
    libraries: tuple[LibraryEntry, ...] = (),
    static_kb: str = "",
    dynamic_kb: str = "",
)

What the solver of a page holds: its operators (as (priority, specifier, name)), flags (as (name, value, help), with help in Markdown), libraries, and static and dynamic knowledge bases (as Prolog text).

Page dataclass

Page(
    id: str,
    title: str,
    source: str = "",
    document_id: str | None = None,
    dirty: bool = False,
    query: str = "",
    resolution: Resolution = Resolution(),
    history: tuple[HistoryEntry, ...] = (),
    stdin: str = "",
    timeout: str = "5s",
    stdout: str = "",
    stderr: str = "",
    warnings: tuple[str, ...] = (),
    diagnostics: tuple[DiagnosticEntry, ...] = (),
    inspection: Inspection = Inspection(),
    unread: frozenset[Panel] = frozenset(),
)

A page: its source (from its scratch text or its document), query, resolution and panels.

Snapshot dataclass

Snapshot(
    started: bool = False,
    pages: tuple[Page, ...] = (),
    selected_page_id: str | None = None,
)

The state of the GUI application, as far as the IDE renders it.

selected_page property

selected_page: Page | None

The selected page, if any.

page

page(page_id: str | None) -> Page | None

The page with the given id, if any.

Startup dataclass

Startup(
    documents: tuple[tuple[Path, str], ...] = (),
    theory: str | None = None,
    query: str | None = None,
    stdin: str | None = None,
    solve: Mode | None = None,
)

What the IDE opens at startup (e.g. as asked on the command line).

It opens a page per document (a path, and its text: empty if the file does not exist yet), then a scratch page with theory if given, or if no documents are; it gives each of these pages query and stdin, if given, and finally solves the query of the selected page (the last one) with solve, if given.

page_count property

page_count: int

How many pages the startup opens.

Action dataclass

Action()

Something the IDE asks the GUI application to do.

RequestExit dataclass

RequestExit()

Bases: Action

The user asked to quit.

ExitConfirmed dataclass

ExitConfirmed()

Bases: Action

The user confirmed quitting despite unsaved changes.

ExitCancelled dataclass

ExitCancelled()

Bases: Action

The user backed out of quitting.

NewScratchPage dataclass

NewScratchPage(title: str | None = None, text: str = '')

Bases: Action

Creates a page with its own text.

NewDocumentPage dataclass

NewDocumentPage(name: str | None = None, text: str = '')

Bases: Action

Creates a page editing a new, unsaved document.

SelectPage dataclass

SelectPage(page_id: str)

Bases: Action

Selects a page.

RequestOpenDocument dataclass

RequestOpenDocument()

Bases: Action

The user asked to open a file.

OpenDocumentLoaded dataclass

OpenDocumentLoaded(path: Path, text: str)

Bases: Action

A file was read, and becomes a new page.

RequestClosePage dataclass

RequestClosePage(page_id: str)

Bases: Action

The user asked to close a page.

ClosePageDecision dataclass

ClosePageDecision(
    page_id: str,
    decision: Literal["SAVE", "DISCARD", "CANCEL"],
)

Bases: Action

The user decided how to close a page with unsaved changes.

ChangeScratchText dataclass

ChangeScratchText(page_id: str, text: str)

Bases: Action

The text of a scratch page was edited.

ChangeDocumentText dataclass

ChangeDocumentText(document_id: str, text: str)

Bases: Action

The text of a document was edited.

ChangeQuery dataclass

ChangeQuery(page_id: str, query: str)

Bases: Action

The query of a page was edited.

ChangeStdin dataclass

ChangeStdin(page_id: str, stdin: str)

Bases: Action

The standard input of a page was edited.

ChangeTimeout dataclass

ChangeTimeout(page_id: str, timeout: str)

Bases: Action

The timeout of the resolutions of a page was edited (e.g. "2s 500ms", or "none").

Next dataclass

Next(page_id: str, mode: Mode = 'ONE')

Bases: Action

Asks for more solutions of the current resolution of a page.

Stop dataclass

Stop(page_id: str)

Bases: Action

Stops the current resolution of a page.

Reset dataclass

Reset(page_id: str)

Bases: Action

Resets the solver of a page.

ClearHistory dataclass

ClearHistory(page_id: str)

Bases: Action

Forgets the concluded resolutions of a page.

ChangeFlag dataclass

ChangeFlag(page_id: str, name: str, value: str)

Bases: Action

Sets a flag of the solvers of a page to a value (a Prolog term).

MarkPanelRead dataclass

MarkPanelRead(page_id: str, panel: Panel)

Bases: Action

The user looked at a panel of a page.

RequestSave dataclass

RequestSave(document_id: str, save_as: bool = False)

Bases: Action

The user asked to save a document (choosing where, if save_as).

SaveDestinationSelected dataclass

SaveDestinationSelected(document_id: str, path: Path)

Bases: Action

The user chose where to save a document.

SaveCancelled dataclass

SaveCancelled(document_id: str)

Bases: Action

The user backed out of choosing where to save a document.

SaveSucceeded dataclass

SaveSucceeded(document_id: str, path: Path, revision: int)

Bases: Action

A document was written.

SaveFailed dataclass

SaveFailed(document_id: str, message: str)

Bases: Action

Writing a document failed.

RequestReload dataclass

RequestReload(document_id: str)

Bases: Action

The user asked to reload a document from its file.

ReloadSucceeded dataclass

ReloadSucceeded(document_id: str, text: str)

Bases: Action

A document was read again.

ReloadFailed dataclass

ReloadFailed(document_id: str, message: str)

Bases: Action

Reading a document again failed.

Effect dataclass

Effect(id: str)

Something the GUI application asks the IDE to do.

PickOpenDocument dataclass

PickOpenDocument(id: str)

Bases: Effect

Ask for a file to open.

PickSaveDestination dataclass

PickSaveDestination(
    id: str, document_id: str, suggested_name: str
)

Bases: Effect

Ask where to save a document.

WriteDocument dataclass

WriteDocument(
    id: str,
    document_id: str,
    path: Path | None,
    text: str,
    revision: int,
)

Bases: Effect

Write a document (path is None if its origin is not a file).

ReadDocument dataclass

ReadDocument(id: str, document_id: str, path: Path | None)

Bases: Effect

Read a document again (path is None if its origin is not a file).

ConfirmCloseDirtyPage dataclass

ConfirmCloseDirtyPage(
    id: str,
    page_id: str,
    document_id: str,
    display_name: str,
)

Bases: Effect

Ask how to close a page with unsaved changes.

ConfirmReloadDirtyDocument dataclass

ConfirmReloadDirtyDocument(
    id: str, document_id: str, display_name: str
)

Bases: Effect

Ask whether to reload a document with unsaved changes.

ConfirmExitWithDirtyDocuments dataclass

ConfirmExitWithDirtyDocuments(
    id: str, document_ids: tuple[str, ...]
)

Bases: Effect

Ask whether to quit despite unsaved changes.

CopyToClipboard dataclass

CopyToClipboard(id: str, text: str)

Bases: Effect

Copy a text to the clipboard.

ExitApplication dataclass

ExitApplication(id: str)

Bases: Effect

Quit.

main

main(argv: Sequence[str] | None = None) -> None

Runs the terminal IDE, as asked by the command-line arguments (see parser).

parse_command_line

parse_command_line(
    argv: Sequence[str] | None = None,
    environ: Mapping[str, str] | None = None,
) -> tuple[JvmGuiBridge, Startup]

Parses the command-line arguments into a bridge to the GUI application, and a startup.

Parameters:

Name Type Description Default
argv Sequence[str] | None

The arguments; by default, those of the process.

None
environ Mapping[str, str] | None

The environment variables standing for arguments, before them (see environment_arguments); by default, those of the process.

None

Returns:

Type Description
JvmGuiBridge

The bridge (with the solver profile, flags, timeout and scheduling asked for) and the

Startup

startup (the pages, query and standard input asked for).

Raises:

Type Description
SystemExit

If the arguments are invalid (after printing why), or after printing the help or the version.

parser

parser() -> ArgumentParser

The parser of the command-line arguments.