Package: sh40-slate
SlateA powerful terminal management library.pip install sh40-slatePurposeSlatehandles most of the interactions one might be expected to
do while writing a UI application for terminals (TUI). It does so
in a simple to understand, Pythonic manner, and uses a simple
synchronous API to allow for maximum compatibility with existing
codebases.Feature highlightsScreen APIUnder the hood,Slate's terminal objects each have aScreen.
This screen is used for creating fast diffs of the display state
between renders, allowing you to drawonlythe parts that changed.Anyone who's worked with terminals before knows their rendering
is almost always the primary bottleneck of any application. They
are surprisingly awful at rendering a full-screen's result,especiallywhen clearing the display beforehand. Many applications
result to hand-crafted update systems that only redraw the widgets
that change, but that can still be quite intensive based on the
size and content of each.Slatehandles cell-level diffing without you ever having to
think about it. You just draw content to the terminal, and we will
keep track of all the changes to display on the next draw, with
practically 0 performance hit.importtimefromrandomimportrandintfromslateimportterminal,Span,Color# Hide the terminal's cursorterminal.show_cursor(False)content=[Span("X"*terminal.width,bold=True,foreground=Color.black().lighten(2),background=Color.black(is_background=True).lighten(1),)for_inrange(terminal.height)]# Use an alt buffer to keep the pre-run terminal state intactwithterminal.alt_buffer():forlineincontent:terminal.write(content)terminal.draw()# Draw a '0' to a random spot on the screen, 60 times a second## This type of operation is really taxing on terminals (especially old ones,# like Terminal.app) as it generally is done by redrawing the entire screen.# That's no longer gonna be a problem for us.whileTrue:cursor=(randint(0,terminal.width-1),randint(0,terminal.height-1))# Make sure no more than 1 cell changes; a sanity check for the most part,# as this setup guarantees it.assertterminal.write("0",cursor=cursor)<=1terminal.draw()time.sleep(1/60)Terminal's smart cursorIf you paid attention, you might have noticed that we never moved the terminal's cursor
while drawing the initial lines of content. This is because the terminal will always track
and move its own cursor when written to, so it knows when it ran out of space and needs
to move to a new line.fromslateimportterminalprint(terminal.cursor)# (0, 0)terminal.write("1")print(terminal.cursor)# (1, 0)It will even wrap while writing!fromslateimportterminal,getch# It will even wrap while writing!terminal.write("#"*(terminal.width-5))terminal.write("This is long, but it will wrap around to the next line.")terminal.draw()getch()# Wait for input so the shell prompt doesn't slide things out of viewSophisticated color toolsYou might have noticed the usage of the lighten and darken API for colors above. These
are amongst the many tools we provide for working with colors, which also include blending,
generating W3C guidelines compliant contrast colors (white for dark colors, black for light
ones), generating entire 4-color palettes with multiple of the most commonly used strategies,
and more.Best part;it works everywhere. Colors get translated to the best approximation the current
terminal can display, so you don't have to worry about things looking completely wonky without
true color support. Most terminals (at least ones you should be using / targeting) have true
color support nowadays, but our approximations will begood enoughto use on older ones as
well.We also have advanced support for theNO_COLORinitiative, but instead
of completely stripping the semantic information colors can convey, we translate each color
to a greyscale value that matches with theperceivedlightness,
keeping the application informative.DocumentationOnce the library gets to a settled state (near 1.0), documentation will be hosted both online and as a celx
application. Until then peep theexamplesfolder, or check out some of the references by usingpython3 -m pydoc <name>.See alsoThis library is mostly supposed topowersome higher level tools, so using it raw might
not be ideal. Thankfully, we have two projects that can help with that:Zenith: A markup language with palette generation, built
onSlate'sSpanandColorprimitives.Celadon: A TUI library that usesSlate'sTerminalto
handleallterminal-interfacing.celx: A hypermedia-driven TUI framework built on top ofCeladon.