Commit Graph

59 Commits

Author SHA1 Message Date
Dave Pearson
0bea8b250c HOWTO package a Textual application (#3977)
* Initial draft of the howto for packaging an application

There's a fair bit more I think needs adding, but this has the core concepts
within it. Things still to decide or do are:

- How much lead-in and hand-holding is needed for Hatch and Poetry

For example, should we walk the reader through the `init` process for Hatch
and Poetry, and then guide them to the correct directory in which to create
their application, etc?

- How to do the example repo

Should I do two repos, one for Hatch and one for Poetry? Or should I do one
repo with a Hatch and a Poetry example within sub-directories? In either
case having a tidy one-to-one relationship with what I talk about in the
text won't be quite right.

Mainly though I feel the core of what's needed is here (and it's not much,
but has taken some testing and checking and whittling down to get here).

* Title tweak

* Add a note about declaring Textual as a dependency

While this might seem obvious, and while some tools will, as a natural
consequence of using them, ensure that this happens, it's worth highlighting
this so that the reader is mindful of this.

Also, someone might be reading the HOWTO while considering how they to this
with their own build system.

* Break paragraphs down into different lines

Just an internal layout thing. Some folk seem to like this sort of thing.

* Add a summary

* Some rewording

* Link to the example repos

* Post-initial-proof-read

* Link to pip and pipx

* Don't repeat help in the same sentence

* Remove an actual needless word

* Remove the dual use of application in a sentence

* Link to TCSS files in case the reader needs a refresh

* Explain what the example repositories were built for/with

It should be obvious from the names; but it can't hurt to be *very* clear.

* Update docs/how-to/package-an-application.md

Co-authored-by: Will McGugan <willmcgugan@gmail.com>

* Changes in response to feedback

* Trim down the into a wee bit

* Trim down the into a wee bit more

---------

Co-authored-by: Will McGugan <willmcgugan@gmail.com>
2024-01-15 10:15:10 +00:00
Will McGugan
b61b878fda Make cache public (#3976)
* pulic cache

* changelog

* Apply suggestions from code review

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

---------

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>
2024-01-08 13:19:33 +00:00
Will McGugan
b8fccd494a lazy mount (#3936)
* lazy mount

* Lazy test

* doc

* Add to docs

* snapshot and changelog

* typing

* future

* less flaky

* comment
2024-01-01 15:54:55 +00:00
Will McGugan
bfbc6fb285 added howto (#3854)
* added howto

* don't need this

* don't need this

* move title

* docstring
2023-12-12 14:39:27 +00:00
Will McGugan
a2a6f56cec docs fix (#3841) 2023-12-09 12:12:46 +00:00
Rodrigo Girão Serrão
d993cce505 Rename link-hover-* rules to link-*-hover. (#3736)
Co-authored-by: Will McGugan <willmcgugan@gmail.com>
2023-11-29 14:09:58 +00:00
Rodrigo Girão Serrão
fe0892e0cf Merge pull request #3751 from Textualize/documentation-fixes
Documentation fixes.
2023-11-27 16:53:35 +00:00
Will McGugan
370f5f7214 Keyline rule (#3669)
* canvas

* imports

* more box drawing

* lines

* lines

* box drawing table

* fix box table

* tweak test

* canvas color

* simplify canvas

* optimization

* clipping

* render experiment

* keyline css

* tests

* don't draw around invisible widgets

* optimize

* snapshot test

* docs and examples

* tab size

* disclaimer

* docs

* changelog

* snapshots

* accidental add

* rename for consistency

* simplify color

* docstrings

* comment

* snapshots

* micro optimize

* micro-optimization

* typing

* set over list

* remove comment

* docstring

* punctuation

* Update docs/styles/keyline.md

Co-authored-by: Darren Burns <darrenburns@users.noreply.github.com>

---------

Co-authored-by: Darren Burns <darrenburns@users.noreply.github.com>
2023-11-27 11:54:53 +00:00
Rodrigo Girão Serrão
c19d54de67 Documentation fixes. 2023-11-27 10:31:33 +00:00
Rodrigo Girão Serrão
b902b1cae6 Improve documentation. 2023-11-22 15:51:19 +00:00
Darren Burns
bbde62fc57 Text area (#2931)
* Add docstring and switch to tree-sitter-languages wheels - although the wheels arent working

* Adding highlights files

* Fix index error on SyntaxAwareDocument

* Narrowing highlighting scope

* Adding basic highlights for Markdown

* Using utf-8 byte length instead of codepoint count in syntax aware doc

* Start creating an ABC defining functionality required by Document impls

* Simplify tree-sitter logic

* Extracting more ABC

* Fix width calculation, add SyntaxTheme

* Ensure the highlight line style goes right to the very end

* Updating a docstring

* Renaming, and adding document width guide

* Ensuring that line number column toggling refreshes virtual size

* Ensuring that line number column toggling refreshes virtual size

* Width guide

* Fix focus event stopping

* Use release_mouse

* Improving a docstring

* Remove bash

* TextArea language snapshot testing

* Updating snapshots for TextArea since we now highlight more nodes

* Typing fixes

* Testing

* Adding tests

* Fixing language selection

* Refresh size on indent width change

* Testing, renaming, fixing display of selection

* Fix multibyte highlight glitch

* Fix deleting right with selection at end of document in TextArea

* Fixing utf-8 multibyte character issues

* Default location of text insertion is cursor position, add cursor_location properties

* Removing some debugging code

* Cursor location tests

* Updating snapshots

* Cached utf8 encoding

* TextArea selection snapshot testing

* Tidying docstrings and queries

* Updating selection snapshot output

* Binding for ESC to shift focus

* Only build the tree-sitter query once!

* Expand cursor scroll horizontal leeway in TextArea

* Property setter for cursor_location in TextArea shouldnt return value

* Avoiding NamedTuple subclassing - using type aliasing instead

* Tidying API, docstrings etc.

* Tidying the API and docstrings

* TextArea additional cursor tests

* Testing pageup and pagedown in TextArea

* Fix a faulty test

* Docstring in a test for TextArea edit

* Stop using DEFAULT_SYNTAX_THEME

* Docstrings

* Change cursor_destination to move_cursor, add more tests

* Remove faulty assertion

* Tidying cursor movement

* Tidying up, adding docstrings for component classes

* Fix a broken selection test

* Remove some unused highlighting machinery

* Fix some Python highlighting issues

* Make HTML syntax highlight nicely

* Create tag name for mismatching HTML end tag

* Add styling for YAML, update boolean styling

* Stylising toml types

* Styling floats

* JSON syntax highlighting

* Updating snapshots

* Syntax highlighting datetimes in TOML

* Namespace TOML errors in highlighting

* Add a move_cursor_relative method

* Update TOML TextArea snapshot for datetime highlighting support

* Adjusting selections

* At TextArea widget level, delete_range is insert_range of empty string

* Refactoring

* Dunder all, docstring fix

* Fix XFAIL

* Remove unused import

* More tests, tidying up

* Cleaning the API

* Docstrings for TextArea

* A bunch of docstrings, delete unused code

* More tidying and docstrings

* Cursor origin on document load, correctly handle delete word left/right when selection is non-empty, fix delete_line when selection spans multiple lines and is in reverse direction

* Moving things around

* Fixing dunder all to export DocumentBase

* Add docstring

* Record cursor width on programmatic insert since it can result in the cursor moving

* Typing fixes

* Fixing remaining typing issues with TextArea

* Add tree-sitter-languages stubs and fix typing issues in documents

* Fixing remaining typing issues with document

* Updating Syntax themes

* Improve highlighting, add initial TextArea docs page

* Add TextArea indent note

* Start TextArea guide inside reference

* Add TextArea to widget gallery

* Fleshing out TextArea docs

* Add note

* Fix TextArea programmatic insert/cursor interaction

* Improve a test

* Testing replacement within selection

* Testing double-width character keyboard navigation and deletion keybinds with active selections

* Testing "delete to start of line" TextArea binding

* Testing TextArea delete line methods and delete to end of line

* Testing shift selecting using keyboard in vertical direction

* Expand tests for home and end keybinds in TextArea

* Renaming tests, testing empty replace and insert

* Testing delete word left via API

* Testing delete word left via API

* Testing delete_word_left with tabs, and delete_word_right

* Remove unused variables

* Remove debugging width guide

* Fix snapshot report path

* Deleting word left/right interaction with line ends fixes, ensure cursor width recorded on all edits

* Docstring fixes

* Unpin textual snapshot library dependency (issue is fixed)

* Docstring fixes

* Fix recording cursor width

* Fix a docstring

* Add select_all to TextArea

* Remove unused tree-sitter stuff from .gitignore

* Line select

* Make word pattern private in TextArea

* Add blinking cursor to TextArea

* Renaming, adding missing return typing

* Add selection bindings

* Moving cursor left/right by word while selecting

* Change escape keybind description, TextArea

* Stripping whitespace when going word left/right

* Add missing annotation

* Cursor word right and left parity with PyCharm

* Use repaint=False for cursor blink

* Improve focus/blur styling

* A whole bunch of TextArea testing

* Simplify delete_left and delete_right

* Testing hiding line numbers in snapshot

* Adding snapshot test for unfocus styling

* Create initial snapshot for text-area unfocused

* Support shift+home, shift+end

* Document shift+home, shift+end

* Add Dracula syntax highlighting theme

* Small change to delete_line behaviour when multiple lines selected to match vscode/pycharm behaviour

* Add test for new delete line logic

* Delete line improvement

* Add extra test for delete_line multiple selection

* Test cursor "smart" home behaviour

* Fix typo

* Highlight matching brackets

* Update snapshot

* Update snapshot

* Fix xfails

* Simplify delete_word_left

* Catch correct exception to ensure support for Python 3.7

* Add styling for Markdown

* Add styles for Dracula for Markdown

* Remove unused _fix_direction.py

* Add docstring to EditResult

* Use default=0 in max inside Document

* Remove redundant actions

* Use cell-width aware expand tabs implementation from @willmcgugan

* Construct strip with cell length

* Some TextArea keyword-only arguments

* Begin moving over to TextAreaTheme #skipci

* Prepare queries inside document #skip-ci

* Add comment

* Refactoring

* TextAreaTheme styling

* Setting width of blank selected lines

* Building the highlight map in the text area

* Remove unused default css from TextArea

* Moving highlighting stylize into widget

* Moving syntax highlighting into TextArea widget

* Remove unused code

* Optimise imports

* Fix highlighting when initial text supplied to TextArea

* Rebuild highlight map when the theme changes

* Extending

* Restore themes

* Remove old comment, fix docstring

* Fixing docstrings

* Fixing mypy

* Fixing mypy issues in document

* Tidying things

* Updating version

* Add theme

* Fix VSCode theme bracket matching

* Only match brackets when theres no selection

* Highlighting tidying

* Fix markdown header highlighting

* Setting theme correctly in background

* Tidying module interface

* Merging main

* Fixing a bunch of typing problems

* Fixing more typing problems

* Correctly setting theme object

* mypy

* Small fix to bracket matching

* Improve a docstring

* Fix docstring

* Testing builtin and custom languages

* Unit testing theme stuff

* Reworking themes

* Error handling

* Improve error message

* Testing new theme setting approach, error handling

* Improvements/tests for theme and language setting

* Remove unused TextArea unfocus snapshot

* Update snapshot file

* Adding theme snapshot tests

* Add `function.call` style binding in dark vscode theme

* Renaming a test file

* Making active line clearer on vscode theme

* Renaming tests

* A whole lot of docs for TextArea

* Update wording in docs

* A bit more docs

* Example on adding Java as a custom language

* More custom language docs

* Finishing up custom themeing/syntax highlighting guide for TextArea

* Add note on potential issue

* Fix wording

* Add note on Apple Silicon Python 3.7 fallback

* Add another note on Apple Silicon Python 3.7 fallback

* Fix class names in example files

* Add some documentation for useful TextArea APIs

* TextArea docs improvements

* TextArea docs typo fix

* Note about extending TextArea

* Tab-stop support when spaces used for indent

* Docs update

* Text area blog post (#3356)

* Start blog post

* Add demo script to blog post

* Continuing the blog post

* Yet more writing for TextArea blog post

* Working on closing section

* Finishing up

* Update docs/blog/posts/text-area-learnings.md

Co-authored-by: Dave Pearson <davep@davep.org>

* Update docs/blog/posts/text-area-learnings.md

Co-authored-by: Dave Pearson <davep@davep.org>

* Typo fix

* Update docs/blog/posts/text-area-learnings.md

Co-authored-by: Dave Pearson <davep@davep.org>

---------

Co-authored-by: Dave Pearson <davep@davep.org>

* Remove redundant pass

* Add docstring

* Docs fix

* Simplify docs

* Improve docstring

* Add links in docstrings

---------

Co-authored-by: Dave Pearson <davep@davep.org>
2023-09-21 11:10:14 +01:00
Will McGugan
f187a420ef welcome tweak 2023-09-19 12:46:43 +01:00
Will McGugan
b99da2d6b9 Testing guide (#3329)
* testing docs

* words

* words

* testing doc

* Apply suggestions from code review

Co-authored-by: Gobion <1312216+brokenshield@users.noreply.github.com>

---------

Co-authored-by: Gobion <1312216+brokenshield@users.noreply.github.com>
2023-09-17 10:34:32 +01:00
Will McGugan
1db9ecb302 Update Collapsible (#3305)
* Update Collapsible

* snapshot tests

* word

* Update docs/widgets/collapsible.md

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Update docs/widgets/collapsible.md

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* simplify render

---------

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>
2023-09-14 16:26:41 +01:00
Will McGugan
5d6a95dec5 Command Palette tweaks and docs (#3289)
* renames to command palette and docs

* docs

* simplifyt

* note

* docstring

* Update src/textual/command.py

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Update docs/examples/guide/command_palette/command01.py

Co-authored-by: Dave Pearson <davep@davep.org>

* populate text

* screen commands

* Update docs/guide/command_palette.md

Co-authored-by: Dave Pearson <davep@davep.org>

* Update docs/guide/command_palette.md

Co-authored-by: Dave Pearson <davep@davep.org>

---------

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>
Co-authored-by: Dave Pearson <davep@davep.org>
2023-09-13 15:03:25 +01:00
Dave Pearson
85a3af320a Merge branch 'main' into M-x 2023-09-06 14:46:33 +01:00
TomJGooding
06b6426750 feat: add rule widget (#3209)
* feat: add rule widget

* add star to init

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* remove unnecessary validations

* update rule styles

* add tests for invalid rules

* add minimum heights and widths

* tidy up examples

* remove old example

* move examples styling to tcss

* modify examples to fit docs screenshots

* add docs first draft

* add snapshot tests

* add rule to widget gallery

* make non-widget rule classes available

* tentatively update changelog

---------

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>
Co-authored-by: Will McGugan <willmcgugan@gmail.com>
2023-09-04 17:57:10 +01:00
Dave Pearson
64354a35fd Merge branch 'main' into M-x 2023-08-22 08:29:50 +01:00
Dave Pearson
bb20cdc2bf Move the Textual FAQ into the main docs
See #3068.
2023-08-21 14:41:07 +01:00
Dave Pearson
c1aba61349 Add the fuzzy matcher to the docs
While it isn't designed to be used directly, it is something a developer
will be exposed to via the command source for the command palette, so it
should appear in the docs so it can be linked to.
2023-08-17 15:33:31 +01:00
Dave Pearson
5fea151a7f Add the system command sources into the docs 2023-08-17 14:18:54 +01:00
Dave Pearson
7fc3604dfa Pull the command palette into the API docs 2023-08-17 11:21:29 +01:00
Will McGugan
49281b3f27 Digits (#3073)
* Digits

* digits widget

* update requires str

* digits docs

* simplify

* tweak docs

* snapshot test

* change name

* simplify

* docs

* Update _digits.py superfluous import

* Update _digits.py docstring

* address review

* formatting

* Update tests/snapshot_tests/snapshot_apps/digits.py

Co-authored-by: Dave Pearson <davep@davep.org>

---------

Co-authored-by: Dave Pearson <davep@davep.org>
2023-08-09 10:25:17 +01:00
Will McGugan
879c985296 Rich log (#3046)
* log

* tests

* snapshot tests

* change to richlog

* keep raw lines

* disable highlighting by default

* simplify

* superfluous test

* optimization

* update cell length

* add refresh

* write method

* version bump

* doc fix link

* makes lines private

* docstring

* relax dev dependancy

* remove superfluous code [skip ci]

* added FAQ [skipci]

* fix code in faq [skipci]

* fix typo

* max lines fix
2023-08-03 10:11:17 +01:00
Will McGugan
dbd3644577 center how to (#3031)
* center how to

* words

* words
2023-07-31 09:56:46 +01:00
Rodrigo Girão Serrão
62da06d1ee Tweak docs.
Removes 'API' entry from the API TOC and adds validation to the TOC.
2023-07-04 15:51:11 +01:00
Will McGugan
58a9cb1909 blog post new release (#2712)
* blog post new release

* update words

* Update docs/blog/posts/release0-27-0.md

Co-authored-by: Dave Pearson <davep@davep.org>

---------

Co-authored-by: Dave Pearson <davep@davep.org>
2023-06-01 11:33:54 +01:00
Rodrigo Girão Serrão
78db024c01 Add sparkline widget. (#2631)
* Sparkline widget proof of concept.

* Address review comment.

Related comments: https://github.com/Textualize/textual/pull/2631\#discussion_r1202894414

* Blend background colours.

* Add widget sparkline.

* Add snapshot tests.

* Add documentation.

* Update roadmap.

* Address review feedback.

Relevant comments: https://github.com/Textualize/textual/pull/2631\#discussion_r1210394532, https://github.com/Textualize/textual/pull/2631\#discussion_r1210442013

* Improve docs.

Relevant comments: https://github.com/Textualize/textual/pull/2631\#issuecomment-1568529074

* Update snapshot app titles.

* Don't init summary function with None

Related comments: https://github.com/Textualize/textual/pull/2631\#discussion_r1211666076

* Apply suggestions from code review

Co-authored-by: Dave Pearson <davep@davep.org>

* Improve wording.

* Improve wording.

* Simplify example.

---------

Co-authored-by: Dave Pearson <davep@davep.org>
2023-06-01 09:34:33 +01:00
darrenburns
ca17d8194e Add docs for Pretty, fix some reference issues in docs (#2678) 2023-05-29 17:11:39 +01:00
Dave Pearson
910c4782f1 Add the main framework for the OptionList documentation
Lots to flesh out here still, but this gets the core framework in place.
2023-05-24 15:05:10 +01:00
Will McGugan
f820598846 How to (#2592)
* words

* how to

* Apply suggestions from code review

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

---------

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>
2023-05-17 15:30:31 +01:00
Will McGugan
7db7139bb8 Select widget (#2501)
* overlay rule

* select WIP

* select control, made binding description optional

* changelog

* style tweak

* Added constrain

* changelog

* test fix

* drop markup, tidy

* tidy

* select namespace

* tests

* docs

* Added changed event

* changelog

* expanded

* tests and snapshits

* examples and docs

* simplify

* update reactive attributes

* type fix

* docstrings

* allow renderables

* superfluous init

* typing fix

* optimization

* revert optimizations

* fixed words

* changelog

* docstrings

* don't need this

* changelog

* comment

* Update docs/widgets/select.md

Co-authored-by: Dave Pearson <davep@davep.org>

* review changes

* review updates

---------

Co-authored-by: Dave Pearson <davep@davep.org>
2023-05-08 10:55:39 +01:00
Will McGugan
91a9d570a4 On decorator (#2453)
* Add on decorator

* decorator code

* docs for on decorator

* Examples

* test errors

* simplify listing

* words

* changelog

* Update docs/guide/events.md

Co-authored-by: Dave Pearson <davep@davep.org>

* Update docs/guide/events.md

Co-authored-by: Dave Pearson <davep@davep.org>

* Update docs/examples/events/on_decorator.css

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Update docs/guide/events.md

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* rewording

* comment

* clarification

* Added note

---------

Co-authored-by: Dave Pearson <davep@davep.org>
Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>
2023-05-02 16:17:40 +01:00
Rodrigo Girão Serrão
914e50a70f Export types & doc improvements (#2329)
* Export types used in app.py

* Export more linked types/errors/classes.

* Remove custom template.

* Address review comments.

We need to have explicit 'Returns:' sections in properties if we want to link to the return type while https://github.com/mkdocstrings/python/issues/65 is open.

* Improve docs.
2023-05-02 15:12:53 +01:00
Rodrigo Girão Serrão
4148b1d450 Implement a Progress Bar widget. (#2333)
* First prototype of PB.

* Repurpose UnderlineBar.

* Factor out 'Bar' widget.

* Revert "Factor out 'Bar' widget."

This reverts commit 0bb4871adf.

* Add Bar widget.

* Cap progress at 100%.

* Add skeleton for the ETA label.

[skip ci]

* Add ETA display.

* Improve docstrings.

* Directly compute percentage.

* Watch percentage changes directly.

[skip ci]

* Documentation.

* Make reactive percentage private.

Instead, we create a public read-only percentage property.

* Update griffe to fix documentation issue.

Related issues: #1572, https://github.com/mkdocstrings/griffe/issues/128.
Related PRs: https://github.com/mkdocstrings/griffe/pull/135.

* Add example and docs.

* Address review feedback.

[skip ci]

* More documentation.

* Add tests.

* Changelog.

* More tests.

* Fix/fake tests.

* Final tweaks.
2023-04-26 15:25:39 +01:00
Rodrigo Girão Serrão
01d67173e8 Don't expose snippets publically. (#2300) 2023-04-18 10:19:43 +01:00
Will McGugan
0509cf8948 Border style (#2292)
* border styles

* docs for border styles

* fix tests

* tests

* tests and docs

* changelog

* implement auto

* style information fix
2023-04-16 12:31:39 +01:00
Will McGugan
3c8f2ec4e9 map geometry 2023-04-10 21:57:20 +01:00
Will McGugan
2244b1161e api docs (#2240)
* api docs

* more docstrings

* logs

* docs shakeup

* fix notes, added intro to all apis

* Remove defaults to

* add note to events

* note

* use fira code
2023-04-08 15:35:49 +01:00
Will McGugan
380114489d docs fix 2023-04-04 15:43:10 +01:00
Will McGugan
b5689b1f69 Worker API (#2182)
* worker class

* worker API tests

* tidy

* Decorator and more tests

* type fix

* error order

* more tests

* remove active message

* move worker manager to app

* cancel nodes

* typing fix

* revert change

* typing fixes and cleanup

* revert typing

* test fix

* cancel group

* Added test for worker

* comment

* workers docs

* Added exit_on_error

* changelog

* svg

* refactor test

* remove debug tweaks

* docstrings

* worker test

* fix typing in run

* fix 3.7 tests

* blog post

* fix deadlock test

* words

* words

* words

* workers docs

* blog post

* Apply suggestions from code review

Co-authored-by: Dave Pearson <davep@davep.org>

* docstring

* fix and docstring

* Apply suggestions from code review

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Update src/textual/widgets/_markdown.py

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Update src/textual/worker.py

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Fix black

* docstring

* merge

* changelog

---------

Co-authored-by: Dave Pearson <davep@davep.org>
Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>
2023-04-04 13:12:51 +01:00
Dave Pearson
0be094cf4a Add OptionList widget (#2154)
* Menu skeleton

The vaguest of starts. Near the end of the day and I want to pick this up
later/tomorrow, so making sure it's on the forge before I go AFK.

* Initial design for populating the menu

One of the driving forces in the design here is that a menu option can have
a prompt that is more than one line in height; and different options can
have different height prompts. This has meant that I've had to finally get
to grips with Rich renderable types and related things.

The menu is going to lean heavily on the line API, and aims to be as
efficient as possible when it comes to having a very large menu. Large menus
are a bad idea! Nobody should be using large menus. On the other hand,
people will do it so let's allow for it.

Work in progress commit. Lots more to come.

* Add a reminder about width

* Make mypy and friend happy with OptionLineSpan.__contains__

* Fix typo

* Add a debug message

I'll remove this later, but I'd like to bubble up some debug stuff into my
own test app.

* Get scrolling working

After battling for ages to try and figure out why scrolling just wasn't
working at all, two things turned out to be at play:

1. If `overflow: hidden` you need force=True. Doh!
   - I should know that too as I added force. O_o
2. Even if you do the above, it doesn't work as you'd expect *if* animation
   is turned on. Turning that off made things work.

I've raised #2077 as a reminder to myself that I need to look into '2' some
more. The menus feel very snappy with animation off, but I suspect there
will be a call to allow animation during menu navigation so that'll need
sorting at some point I guess.

* Add support for home and end keys

Which, shockingly, go to the first and last items in the menu.

* Remind myself I need to remove the Debug message

Once I'm done with it.

* Make the MenuOption class a NamedTuple

There's no obvious benefit to it being a full class, but some benefits to it
being a NamedTuple.

* Add a Menu.OptionHighlighted message

* Add a missing argument to a docstring

* Fully type the option line segments list

I forgot to ensure that it was fully typed.

* Add a method for getting an option at a given position

* Better name for the location of the option

* Include the highlighted index in the OptionHighlighted message

* Add home and end to the binding docstring

* Add support for page up/down in a menu

* Rename OptionLineSegments to OptionLine

It's the details for a line of an option that hold the segments, amongst
other things. No point in repeating information here.

* Add support for a Menu.OptionSelected message

* Remove a TODO comment

It's not that it doesn't need doing yet; it's just that I've moved some TODO
stuff to a WIP document.

* Document the enter binding

* Add a reminder to myself about why animate is off

For a menu I feel that animate *should* be off, but if anyone is reading
this bit of code and feels it should be on, this will explain why it isn't.

* Explain OptionLineSpan a wee bit more

* Import Literal from typing_extensions rather than typing

This is needed for older Pythons.

* Move the prompt shapes calculation code into its own method

* Add a property for getting the option count of the menu

* Add a method of adding an option to the menu

* Highlight first option if no highlight and then movement

* Ensure the virtual height is recalculated on addition

* Remove the method for getting a specific option

There's little point in letting the user treat the menu as if it's an array;
they should know what they put into it and anything that happens *on* the
menu will result in a message which will point to the option anyway.

* Add a menu separator

This isn't the complete version of this; aside from the obvious fact that at
the moment it's just treated line an ordinary menu option (which we don't
want), the presence of a separator means the index of options will be thrown
off, from the user's point of view. The point being, a menu with 4 options
and a separator might look like this:

    Option 1
    Option 2
    --------
    Option 3
    Option 4

I think the index of "Option 3" above should likely be 2 (starting from 0,
of course), not 3. This means I need to tweak the internals of the menu code
to take this into account while also keeping things efficient.

That's next up; but I wanted to get the core of this change in first so I
can noodle away and get the best approach to this.

* Finish off support for menu separators

Here I sort of add support for a menu having both content *and* prompts.
Content is anything that goes in the menu and results in lines being
rendered. Prompts are things that the end user actually gets to select from.
A menu option will have a prompt that has one or more lines. A menu
separator isn't an option but takes up one line.

* Add (back) a method for getting a particular option

Now that the menu content and the menu options are different lists, it's
possible to allow this again. While it still follows that menus shouldn't
really be treated like lists, there's no harm in providing this facility.

* Allow styling separators

* Fix how we tell the Rule to have no style

* Add a documentation line for the separator component class

* Apply default styling to the non-special options

* Set the default color to $text

This isn't actually working, but if I set it to an actual colour, it does
work. Need to dig into this more.

* Remove a TODO warning that isn't valid any more

* Have the menu option messages get the option via Menu.option

It did, and still could, pull directly from the _option property but one
step of indirection means that I can be sure anything "external" is going
via the public interface (yes, I know the message isn't really "external"
but it feels correct to treat it as such because it's for public
consumption).

* Make OptionLine just a Line and drop magic numbers for separators

Rather than overload the option index of the option line class with a magic
number to say that something isn't really an option, here I make the class
just about being a line, I keep the option_index but make it optional (no
pun intended); so that if it's `None` that means "this isn't related to a
menu option".

* Drop the assert that non-option content is a separator

I can't see much benefit in doing this in what should be a fairly tight
loop. This code relates to data that's all under the hood so we shouldn't
need to be quite so defensive.

* Remove unused import of Final

* Add a clear method

* Add support for disabled menu options

At the moment this is done in a way that, as the user navigates, the
disabled options *aren't* skipped. I'm still undecided about this. Your
traditional dropdown menus sometimes do that, sometimes don't do that. And
to make things even more interesting this menu can really be used as a
large-data-friendly listbox and I'm not sure we'd want that there.

This may change.

Also, at this point, I'm also working to keep the MenuOption class a
NamedTuple, which means it's read-only (I don't want the user messing with
things outside of the menu), which means there's interface methods for
changing the disabled state that copy the option and change the disabled
state.

Again, I'll see if I carry on liking this or not. So far I'm okay with this.

* Dial in the styles some more

* Rename some methods that use index to say index in the name

I'm going to be adding support for an id for options too, and want the user
to be able to either access an option via index or via ID. This is the first
step to allowing that.

* Remove an unnecessary inherit

Looks like this was a hangover from an early version of the message classes
and I didn't clean up.

* Fix copy/paste-o

Now there is forever evidence as to where I stole my homework from.

* Add support for menu option IDs

The idea here is that they're purely from, and purely for, the developer who
is creating the menu. Internally I don't care about them and don't
personally use them. However, there is without a doubt a good case for
allowing the developer to specify IDs for options so here's optional support
for that.

* Add a method to get a menu option via an ID

* Reduce property access and list access calls

* Have the content-tracker code do a little less work

* Drop the menu option data attribute

It wasn't going to work well, was going to cause a bunch of problems with
typing, and really it's easier to do by the dev by having them inherit from
MenuOption. So let's do that.

* Remove unused imports

* Add a TODO reminder about subclasses menu optons

* Add an initial bit of unit testing

Just the most basic test so far; it's the end of the day but I want to start
here.

* Allow the caller to use None as an alias for MenuSeparator

In doing so, overhaul how I type candidate menu content vs actual menu
content, setting up a couple of type aliases and making it easier to
maintain.

* Rename the parameter for Menu.add to better match other changes

* Swap MenuOption over to being a standard class

It would have been nice to keep it as a named tuple, but I want the
developer to be able to subclass and add their own properties to the
option (think attaching some random data to a menu option). The problem is
you can't subclass a named tuple.

So... standard class it is, with some reasonably defensive work to
discourage the developer from changing the prompt and the ID on the fly.

For obvious reasons I need to let them change the disabled state on the fly,
and this is where things end up being a little iffy. The only way (right
now) the menu will refresh when the disabled state changes is if the
developer does so via one of the methods on Menu. If they go toggling the
state on the option itself and hope that the menu will reflect this... no,
that's not going to happen.

I *could* make it happen by somehow capturing a reference to the parent menu
inside the menu option, but then things get circular and I don't like that.

* Test using None as an alternative to MenuSeparator

* Flesh out the initial menu unit tests

* Add a module docstring to the core menu unit test

* Add some testing for using subclassed menu options

* Add a property for getting an iterator of the options

* Add unit tests for option enabled/disabled

* Rename Menu -> OptionList (and friends)

The great renaming! We sort of had decided this was coming, but kept going
back and forth on if we should, what it should be, etc. Decision made today.
While this is mostly everything you want from a menu, it is foundational
enough that it needs to really be something else so it's a list of options.
Options; in a list. An OptionList.

* Add a test for adding more items to an option list later on

* Remove the debug message

I think I'm at a stage where I don't need to use it any more.

* Start of OptionList movement tests

End of day commit; more to come.

* Update the pyi for the Menu -> OptionList rename

Missed this during the grand rename.

* Tidy up a test

* Export the DuplicateID exception

* Add a test for creating a duplicate ID

* Add some more OptionList movement tests

* Allow scrollbars by default

Until the great renaming, this code was all about being menus, which
normally don't have scrollbars, and so I made a point of not having them on.
Now that this code is more about it being a list of stuff, which can be the
foundation for a menu, we want the bars there by default and any derived
menu widget can turn them off.

So here we go.

This introduces some issues that now need to be addressed. For one thing no
thought has been given to horizontal scrolling in this code (easy enough to
solve).

Also, weirdly though, the vertical scrollbars aren't quite reaching the
bottom when we highlight the last item. Wasn't expecting that, although I'm
sure there's a simple cause for that.

* Remove hover component class

I do want this, but not yet, so don't have it kicking around until I'm
actually doing something with it.

* Add missing items to the component classes docstring.

* Crop the lines that we draw

This in turn adds support for horizontal scrolling. We're not actually going
to support horizontal scrolling; in conversation with Will we've decided
that it will be *only* a vertical scrolling list, so options will be
rendered within the confines of the width.

* Allow for scrollbars by default

* Make scrolling to a non-highlight a nop rather than an error

Being able to call scroll_to_highlight even if nothing is highlighted is
useful; throwing an error when something isn't, isn't helpful. So let's make
that a no-op.

* Make a note that option ID tracking could be changed

* Ensure highlight is pulled into view on resize

It's possible that a resize might cause a highlight to partially, or even
totally, go out of view. This commit ensures that after such an event this
will be handled.

* Save an attribute access

* Microoptimise _refresh_content_tracking some more

* Reintroduce animation

But only if the vertical scrollbar is visible (see #2077 for context).

* Force a refresh when doing a specific add

* Add support for a mouse hover effect

* Highlighted a clicked option (where appropriate)

* Improve the style of a focused highlighted hovered option

* Reduce the number of attribute lookups in the line drawing method

* Simplify the way we handle page up/down at the margins

Rather than wrap around when doing page up/down, have them work as home/end
when at the margins.

* Remove unnecessary import

* Add some more option list movement tests

* Add tests for moving around an empty list

* Remove the debug message (again)

* Test moving when there are items but no highlight

* Ensure the mouse over gets cleared on clear

* Remove mouse hover logging code

It was useful while adding mouse hover support, but it's not needed now.

* Force a refresh of content tracking when doing a clear

* Rename some methods to talk about options

I want to add a `remove` for options, but widgets already have a `remove`.
So I could call it `remove_option` but then that's an imbalance with `add`.
So this renames `add` to `add_option`, and also renames `clear` to
`clear_options`.

* Add support for removing an option

* Add highlight wrapping back

I made some recent changes to highlight validation where more sensible in
the general sense, but broke the wrapping when using cursor keys to move
around. This takes that into account.

* Add tests for removing options

* Reduce the number of attribute lookups for spans

* Swap to watching highlighted to handle movement

I'd started out with an explicit refresh of the highlighted option, while
working on other things, and forgot to swap over to using a watch method.
This commit fixes that.

* Make a mouse-clicked option select that option too

* Add unit tests for option list messages

* Add unit tests for mouse hover events

* Clarify the point of the mouse click test

* Add an option list message test for highlighting a disabled option

* Add tests for interacting with disabled OptionList options

* Typo fixing

Try and make the docstring sound something approaching English.

* Fix the OptionMessage.__init__ docstring

* Add the API documentation for the OptionList

* Update the OptionTest message tests for initial highlight

Having changed things around a little regarding initial highlight, the unit
tests needed updating.

* Start the reference for the OptionList

I feel this needs a bit more work, but this feels like the core of what we
want to be emphasising.

* Add the OptionList to the gallary

* Try some extra pauses in OptionList tests

While the tests are all passing just fine locally, I'm getting the whole
whack-a-mole thing in CI that is mostly down to subtle timing issues. This
is a test to see if these extra pauses let the test apps settle down before
starting the meat of the testing.

* Try pausing in tests without setting a time

* Add snapshot tests for the OptionList examples

* Sort the bindings

* Add a docstring to the default CSS

* Explain that mouse_hovering_over can be None

* Turn mouse_hovering_over into an internal property

There was a reason that I had it as a reactive, at one point, but looking at
the final form of this code I can't see a use for it any more. So bring it
internal and make it cheaper to update.

* Update the CHANGELOG

* Update the mouse hover test after the changes to the tracking variable

* Tweak the descriptions of the hover tests

Now that I've changed this away from being a reactive.

* Tweak the OptionList hover tests some more

* Rename the up/down actions to cursor_up/down

Re: https://github.com/Textualize/textual/pull/2154#discussion_r1151587080

* Don't kick off an idle check if the widget isn't running

Added at Will's suggestion. :-P

* Simplify how we watch the vertical scrollbar status

Re: https://github.com/Textualize/textual/pull/2154#discussion_r1151593625

* Change the hover highlight to $boost

Re: https://github.com/Textualize/textual/pull/2154#discussion_r1151628190

* Add a custom exception for when an option can't be found

Re:
74a2d079b3 (r1151632957)
and 74a2d079b3 (r1151631495)

* Update tests for the new option list exceptions

* Remove the options property

We've decided it has little utility given the rest of the interface of the
widget.

Re: https://github.com/Textualize/textual/pull/2154#discussion_r1151630437

* Remove import of iterator

It's no longer required.

* Fix some option list unit tests after removing options property

* Crate Line.segments as a strip

Rather than recreate the strip every time around, just create it as a Strip
to start with. Also, in doing so, add the option meta up front rather than
every time we draw the line.

Re: https://github.com/Textualize/textual/pull/2154#discussion_r1151600239

* Correct a comment typo

* Simplify the Separator docstring

* Docstring wording tweak

* Remove the import of Segment

It's not needed any more

* Flesh out the OptionList reference some more

Things like the component classes, bindings and messages had been left out.

* Update snapshot tests

Nothing of consequence has changed but it looked like the change to how the
lines are originally constructed has resulted in an under-the-hood change to
the data that goes into a snapshot.

* Add a missing word to a docstring

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Fix a typo

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Fix a typo

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Document some raises that were missing

* Turn off animation

---------

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>
2023-03-29 14:27:56 +01:00
Will McGugan
73f065bbbd Logging handler (#2151)
* logging handler

* changelog

* remove logging experiment

* handler

* fix

* docs for logging handler
2023-03-28 11:50:28 +01:00
Rodrigo Girão Serrão
2a810f8c87 Implement border (sub)title. (#2064)
* Add Widget.border_title and border_subtitle.

Related issues: #1864

* Test setting border_(sub)title.

* Add border (sub)title references to StylesCache.

These internal references will make it easier for the instance of 'StylesCache' to know which border (sub)title to use, if/when needed.

* Add method to render border label.

* Add styles to align border (sub)title.

* Render border labels.

* Update styles template.

* Make new 'render_row' parameters optional.

* Add (sub)title border snapshot tests.

* Document border (sub)title and styles.

* Pass (sub)title directly as arguments.

Get rid of the watchers to make data flow easier to follow.
Related comment: https://github.com/Textualize/textual/pull/2064/files\#r1137746697

* Tweak example.

* Fix render_border_label.

This was wrong because border labels can be composed of multiple segments if they contain multiple styles. Additionally, we want to render a single blank space of padding around the title.

* Ensure we get no label when there's no space.

* Add tests for border label rendering.

* 'render_border_label' now returns iterable of segments.

* Add label to render_row.

* Fix calling signature in tests.

* Add padding to snapshot tests.

* Fix changelog.

* Update snapshot tests.

* Update snapshot tests.

* Border labels expand if there's no corners.

* Update CHANGELOG.md

* Fix docs.

* Remove irrelevant line.

* Fix snapshot tests.

* Don't share Console among tests.

* Simplify example in styles guide.

* Avoid expensive function call when possible.

* rewording

* positive branch first

* remove wasteful indirection

* fix changelog

---------

Co-authored-by: Will McGugan <willmcgugan@gmail.com>
2023-03-22 11:07:38 +00:00
Will McGugan
f5e779c4c4 tabbed content widget (#2059)
* tabbed content widget

* TabbedContent widget and docs

* missing docs

* fix active

* doc fix

* test fix

* additional test

* test for render_str

* docstring

* changelog

* doc update

* changelog

* fix bad optimization

* Update docs/widgets/tabbed_content.md

Co-authored-by: Dave Pearson <davep@davep.org>

* fix for empty initial

* docstrings

* Update src/textual/widgets/_content_switcher.py

Co-authored-by: Dave Pearson <davep@davep.org>

* docstring

* remove log

* permit nested tabs

* renamed TabsCleared to Cleared

* added tests, fix types on click

* tests

* fix broken test

* fix for nested tabs

---------

Co-authored-by: Dave Pearson <davep@davep.org>
2023-03-18 10:38:41 +00:00
Will McGugan
b0f5c35782 tabs widget (#2020)
* tabs widget

* click underline

* color tweak

* docs

* docs update

* expose Tab

* added remove_tab and clear

* fix cycling

* add animation

* docs

* changelog

* remove recompose

* docstrings

* Update docs/guide/actions.md

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Rodrigoed the tabs

* Update docs/widgets/tabs.md

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Update docs/widgets/tabs.md

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* copy

* docstrings

* docstring

* docstring

* Apply suggestions from code review

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* stop click

* docstring

* auto assign consistent IDs

* Apply suggestions from code review

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Document bindings

* document bindings

* Apply suggestions from code review

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

---------

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>
2023-03-13 14:39:15 +00:00
Will McGugan
198190117d Loading indicator (#2018)
* loading indicator and tests

* docs

* snapshot

* remove snapshot

* remove debug main [skip ci]

* changelog [skip ci]

* make start time private
2023-03-11 08:36:13 +00:00
Dave Pearson
97a5478bd0 Add ContentSwitcher (#1983)
* Add the basic ContentSwitcher widget

* Docstring tidy

* Add a visible_content property to the ContentSwitcher

* Clarify that children of ContentSwitcher with no IDs get ignored

* Simplify setting the display value

* Add the start of an example ContentSwitcher for the docs

* Tweak the example layout to better fit in small spaces

* Add the content switcher to the API docs

* Add a guide entry for the ContentSwitcher

This one is a wee bit more involved than most other widget entries in the
guide in that it doesn't obviously do anything itself, but needs
developer-input to make it do something useful. As such the outline here
isn't as clean as it could be, but I think it conveys everything necessary
without getting too complicated.

* Add the reactive attribute table to the ContentSwitcher guide

* Update the README

* Add a refresh after everything has been flipped in the switcher

As noted in the code, this should not be necessary and I don't believe it
has anything to do with this code. I would suspect some lower-level issue
with flipping between different widgets within a container. I need to find a
way to make an isolated reproduction that isn't about this particular
widget. Meanwhile though this works with the refresh().

* Swap current from var to reactive

This solves the explicit refresh issue, but only because the refresh is
implied due to the use of a reactive over a var. As such this sort of
addresses #1979 by ignoring the issue rather than diving into it.

I still suspect that I shouldn't need to do this, and that perhaps there's a
refresh issue when you flip display. So I'll keep #1979 kicking around and
at some point see if I can recreate in isolation.

* Add unit tests for the content switcher

* Add snapshot tests for the ContentSwitcher

* Clarify that an exception can be thrown on a bad ID

* Try and help other Pythons

* Add a pause at the end of the second switcher snapshot test

I'm getting a lot of fails in CI; none of them are actual problems.
Hopefully this will cure it.

* Paaaaaaaaause

More of a test than anything else really. My particular snapshot test is
failing but kinda randomly in each environment each time -- sometimes
Windows, sometimes GNU/Linux, different Python versions.

So... yeah, let's try this and see if it makes it through; otherwise I may
need to rethink this.

* New pause

So it turns out that _ doesn't do anything any more; and instead there's a
"wait:<n>" syntax! So let's give that a try.

* Learning my alphabet...

* Fix a typo in the docs.

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Add missing full stop.

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Add a missing word

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>

* Try a longer wait on the switcher

I'm starting to suspect that this doesn't come down to a timing issue;
especially given that the snapshot report seems to be showing some oddity in
the length of the vertical scrollbar. But... I want to be as sure as
possible so let's double the length of the wait.

Bit a bit of me is starting to wonder if I've somehow managed to create the
perfect storm for scrollbars and you don't always get the same result every
time.

Seems unlikely, but if it's not timing it's that or lots of cosmic rays.

* Test a longer pause on the content switcher test

The idea here being that it takes 200ms for the button to pop again.

* Refresh the snapshots

This time. THIS TIME!

* Experiment: is the issue the same name for two tests?

* Experiment: drop the different source files, try terminal size

Having got over the issue of the button not ending up in the same state,
we're stuck with the scrollbar having different sizes. Having tried other
options let's go with tweaking the terminal size.

* Do a little less work when changing current

Rather than set everything invisible then the new one visible, every time
current is changed, instead just make sure everything is invisible up front
and then just swap the affected children each time.

This does mean that if someone messes with the children under the hood they
may see oddness happening, but less work while being less defensive seems
fair here.

---------

Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com>
2023-03-09 11:39:30 +00:00
Will McGugan
0f4eb2f1d5 Add widget gallery (#1960)
* Add widget gallery

* updated copy
2023-03-07 11:12:54 +00:00
Dave Pearson
ac35c1d1d5 Document TreeNode via Tree itself
There's a couple of other types in the public interface of Tree that should
be teased out, and it feels odd to have one type in one file and a bunch of
others in another. So this sets us up for having them all the same place.
This should make it easier for the reader to find related information.
2023-03-01 13:21:45 +00:00