Skip to content

Commit

Permalink
Merge branch 'main' into priority-footer
Browse files Browse the repository at this point in the history
  • Loading branch information
darrenburns authored Mar 26, 2024
2 parents 0db1b98 + 7556035 commit f81a308
Show file tree
Hide file tree
Showing 20 changed files with 242 additions and 95 deletions.
25 changes: 20 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,38 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Fixed

- Fix priority bindings not appearing in footer when key clashes with focused widget https://github.com/Textualize/textual/pull/4342

### Changed

- App.namespace_bindings renamed to App.active_bindings and now returns a list instead of a dict https://github.com/Textualize/textual/pull/4342

## [0.54.0] - 2024-03-26

### Fixed

- Fixed a crash in `TextArea` when undoing an edit to a selection the selection was made backwards https://github.com/Textualize/textual/issues/4301
- Fixed issue with flickering scrollbars https://github.com/Textualize/textual/pull/4315
- Fixed issue where narrow TextArea would repeatedly wrap due to scrollbar appearing/disappearing https://github.com/Textualize/textual/pull/4334
- Fix progress bar ETA not updating when setting `total` reactive https://github.com/Textualize/textual/pull/4316
- Fix priority bindings not appearing in footer when key clashes with focused widget https://github.com/Textualize/textual/pull/4342
- Exceptions inside `Widget.compose` or workers weren't bubbling up in tests https://github.com/Textualize/textual/issues/4282

### Changed
### Changed

- ProgressBar won't show ETA until there is at least one second of samples https://github.com/Textualize/textual/pull/4316
- App.namespace_bindings renamed to App.active_bindings and now returns a list instead of a dict https://github.com/Textualize/textual/pull/4342
- `Input` waits until an edit has been made, after entry to the widget, before offering a suggestion https://github.com/Textualize/textual/pull/4335

### Added

- Added `Document.start` and `end` location properties for convenience https://github.com/Textualize/textual/pull/4267

## [0.53.1] - 2023-03-18
## [0.53.1] - 2024-03-18

### Fixed

- Fixed issue with data binding https://github.com/Textualize/textual/pull/4308

## [0.53.0] - 2023-03-18
## [0.53.0] - 2024-03-18

### Added

Expand Down Expand Up @@ -1802,6 +1816,7 @@ https://textual.textualize.io/blog/2022/11/08/version-040/#version-040
- New handler system for messages that doesn't require inheritance
- Improved traceback handling

[0.54.0]: https://github.com/Textualize/textual/compare/v0.53.1...v0.54.0
[0.53.1]: https://github.com/Textualize/textual/compare/v0.53.0...v0.53.1
[0.53.0]: https://github.com/Textualize/textual/compare/v0.52.1...v0.53.0
[0.52.1]: https://github.com/Textualize/textual/compare/v0.52.0...v0.52.1
Expand Down
4 changes: 4 additions & 0 deletions docs/events/load.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
::: textual.events.Load
options:
heading_level: 1

## See also

- [Mount](mount.md)
5 changes: 5 additions & 0 deletions docs/events/mount.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
::: textual.events.Mount
options:
heading_level: 1

## See also

- [Load](load.md)
- [Unmount](unmount.md)
2 changes: 2 additions & 0 deletions docs/events/mouse_capture.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ title: MouseCapture

## See also

- [capture_mouse][textual.widget.Widget.capture_mouse]
- [release_mouse][textual.widget.Widget.release_mouse]
- [MouseRelease](mouse_release.md)
2 changes: 2 additions & 0 deletions docs/events/mouse_release.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ title: MouseRelease

## See also

- [capture_mouse][textual.widget.Widget.capture_mouse]
- [release_mouse][textual.widget.Widget.release_mouse]
- [MouseCapture](mouse_capture.md)
4 changes: 4 additions & 0 deletions docs/events/unmount.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
::: textual.events.Unmount
options:
heading_level: 1

## See also

- [Mount](mount.md)
4 changes: 4 additions & 0 deletions docs/widgets/text_area.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ This method is the programmatic equivalent of selecting some text and then pasti

Some other convenient methods are available, such as [`insert`][textual.widgets._text_area.TextArea.insert], [`delete`][textual.widgets._text_area.TextArea.delete], and [`clear`][textual.widgets._text_area.TextArea.clear].

!!! tip
The `TextArea.document.end` property returns the location at the end of the
document, which might be convenient when editing programmatically.

### Working with the cursor

#### Moving the cursor
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "textual"
version = "0.53.1"
version = "0.54.0"
homepage = "https://github.com/Textualize/textual"
repository = "https://github.com/Textualize/textual"
documentation = "https://textual.textualize.io/"
Expand Down
9 changes: 8 additions & 1 deletion src/textual/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3006,11 +3006,18 @@ async def _broker_event(
return False
else:
event.stop()
if isinstance(action, (str, tuple)):
if isinstance(action, str) or (isinstance(action, tuple) and len(action) == 2):
await self.run_action(action, default_namespace=default_namespace) # type: ignore[arg-type]
elif callable(action):
await action()
else:
if isinstance(action, tuple) and self.debug:
# It's a tuple and made it this far, which means it'll be a
# malformed action. This is a no-op, but let's log that
# anyway.
log.warning(
f"Can't parse @{event_name} action from style meta; check your console markup syntax"
)
return False
return True

Expand Down
22 changes: 22 additions & 0 deletions src/textual/document/_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,17 @@ def prepare_query(self, query: str) -> Query | None:
def line_count(self) -> int:
"""Returns the number of lines in the document."""

@property
@abstractmethod
def start(self) -> Location:
"""Returns the location of the start of the document (0, 0)."""
return (0, 0)

@property
@abstractmethod
def end(self) -> Location:
"""Returns the location of the end of the document."""

@overload
def __getitem__(self, line_index: int) -> str: ...

Expand Down Expand Up @@ -331,6 +342,17 @@ def line_count(self) -> int:
"""Returns the number of lines in the document."""
return len(self._lines)

@property
def start(self) -> Location:
"""Returns the location of the start of the document (0, 0)."""
return super().start

@property
def end(self) -> Location:
"""Returns the location of the end of the document."""
last_line = self._lines[-1]
return (self.line_count, len(last_line))

def get_index_from_location(self, location: Location) -> int:
"""Given a location, returns the index from the document's text.
Expand Down
19 changes: 13 additions & 6 deletions src/textual/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class Load(Event, bubble=False):
"""
Sent when the App is running but *before* the terminal is in application mode.
Use this event to run any set up that doesn't require any visuals such as loading
Use this event to run any setup that doesn't require any visuals such as loading
configuration and binding keys.
- [ ] Bubbles
Expand Down Expand Up @@ -129,6 +129,9 @@ def __rich_repr__(self) -> rich.repr.Result:
class Compose(Event, bubble=False, verbose=True):
"""Sent to a widget to request it to compose and mount children.
This event is used internally by Textual.
You won't typically need to explicitly handle it,
- [ ] Bubbles
- [X] Verbose
"""
Expand All @@ -151,7 +154,7 @@ class Unmount(Event, bubble=False, verbose=False):


class Show(Event, bubble=False):
"""Sent when a widget has become visible.
"""Sent when a widget is first displayed.
- [ ] Bubbles
- [ ] Verbose
Expand All @@ -164,13 +167,17 @@ class Hide(Event, bubble=False):
- [ ] Bubbles
- [ ] Verbose
A widget may be hidden by setting its `visible` flag to `False`, if it is no longer in a layout,
or if it has been offset beyond the edges of the terminal.
Sent when any of the following conditions apply:
- The widget is removed from the DOM.
- The widget is no longer displayed because it has been scrolled or clipped from the terminal or its container.
- The widget has its `display` attribute set to `False`.
- The widget's `display` style is set to `"none"`.
"""


class Ready(Event, bubble=False):
"""Sent to the app when the DOM is ready.
"""Sent to the `App` when the DOM is ready and the first frame has been displayed.
- [ ] Bubbles
- [ ] Verbose
Expand Down Expand Up @@ -232,7 +239,7 @@ class Key(InputEvent):
Args:
key: The key that was pressed.
character: A printable character or ``None`` if it is not printable.
character: A printable character or `None` if it is not printable.
"""

__slots__ = ["key", "character", "aliases"]
Expand Down
6 changes: 2 additions & 4 deletions src/textual/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -3618,10 +3618,8 @@ async def _compose(self) -> None:
raise TypeError(
f"{self!r} compose() method returned an invalid result; {error}"
) from error
except Exception:
from rich.traceback import Traceback

self.app.panic(Traceback())
except Exception as error:
self.app._handle_exception(error)
else:
self._extend_compose(widgets)
await self.mount_composed_widgets(widgets)
Expand Down
1 change: 1 addition & 0 deletions src/textual/widgets/_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ def _on_focus(self, _: Focus) -> None:
if self.cursor_blink:
self._blink_timer.resume()
self.app.cursor_position = self.cursor_screen_offset
self._suggestion = ""

async def _on_key(self, event: events.Key) -> None:
self._cursor_visible = True
Expand Down
5 changes: 1 addition & 4 deletions src/textual/widgets/_text_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -2026,10 +2026,7 @@ def clear(self) -> EditResult:
Returns:
An EditResult relating to the deletion of all content.
"""
document = self.document
last_line = document[-1]
document_end = (document.line_count, len(last_line))
return self.delete((0, 0), document_end, maintain_selection_offset=False)
return self.delete((0, 0), self.document.end, maintain_selection_offset=False)

def _delete_via_keyboard(
self,
Expand Down
3 changes: 2 additions & 1 deletion src/textual/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,8 @@ async def _run(self, app: App) -> None:

app.log.worker(Traceback())
if self.exit_on_error:
app._fatal_error()
worker_failed = WorkerFailed(self._error)
app._handle_exception(worker_failed)
else:
self.state = WorkerState.SUCCESS
app.log.worker(self)
Expand Down
Loading

0 comments on commit f81a308

Please sign in to comment.