diff --git a/README.md b/README.md index 866cba6f9..a8dd8f1be 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ class ColorChanger(App): self.background = f"on color({event.key})" -ColorChanger.run(log="textual.log") +ColorChanger.run(log_path="textual.log") ``` You'll notice that the `on_key` method above contains an additional `event` parameter which wasn't present on the beeper example. If the `event` argument is present, Textual will call the handler with an event object. Every event has an associated handler object, in this case it is a KeyEvent which contains additional information regarding which key was pressed. @@ -114,7 +114,7 @@ class SimpleApp(App): await self.view.dock(Placeholder(), Placeholder(), edge="top") -SimpleApp.run(log="textual.log") +SimpleApp.run(log_path="textual.log") ``` This app contains a single event handler `on_mount`. The mount event is sent when the app or widget is ready to start processing events, and is typically used for initialization. You may have noticed that `on_mount` is an `async` function. Since Textual is an asynchronous framework we will need this if we need to call most other methods. @@ -137,7 +137,7 @@ await self.view.dock(Placeholder(), Placeholder(), edge="top") You will notice that this time we are docking _two_ Placeholder objects onto the `"top"` edge. We haven't set an explicit size this time so Textual will divide the remaining size amongst the two new widgets. -The last line calls the `run` class method in the usual way, but with an argument we haven't seen before: `log="textual.log"` tells Textual to write log information to the given file. You can tail textual.log to see events being processed and other debug information. +The last line calls the `run` class method in the usual way, but with an argument we haven't seen before: `log_path="textual.log"` tells Textual to write log information to the given file. You can tail textual.log to see events being processed and other debug information. If you run the above example, you will see something like the following: @@ -183,7 +183,7 @@ class HoverApp(App): await self.view.dock(*hovers, edge="top") -HoverApp.run(log="textual.log") +HoverApp.run(log_path="textual.log") ``` The `Hover` class is a custom widget which displays a panel containing the classic text "Hello World". The first line in the Hover class may seem a little mysterious at this point: diff --git a/docs/examples/messages_and_events/color_changer.py b/docs/examples/messages_and_events/color_changer.py index 7d43a65e7..58e19c9db 100644 --- a/docs/examples/messages_and_events/color_changer.py +++ b/docs/examples/messages_and_events/color_changer.py @@ -7,4 +7,4 @@ class ColorChanger(App): self.background = f"on color({event.key})" -ColorChanger.run(log="textual.log") +ColorChanger.run(log_path="textual.log") diff --git a/docs/examples/widgets/custom.py b/docs/examples/widgets/custom.py index f47d585cf..8fda42589 100644 --- a/docs/examples/widgets/custom.py +++ b/docs/examples/widgets/custom.py @@ -29,4 +29,4 @@ class HoverApp(App): await self.screen.dock(*hovers, edge="top") -HoverApp.run(log="textual.log") +HoverApp.run(log_path="textual.log") diff --git a/docs/examples/widgets/placeholders.py b/docs/examples/widgets/placeholders.py index 5e6dea609..9f7a96069 100644 --- a/docs/examples/widgets/placeholders.py +++ b/docs/examples/widgets/placeholders.py @@ -12,4 +12,4 @@ class SimpleApp(App): await self.screen.dock(Placeholder(), Placeholder(), edge="top") -SimpleApp.run(log="textual.log") +SimpleApp.run(log_path="textual.log") diff --git a/e2e_tests/test_apps/basic.py b/e2e_tests/test_apps/basic.py index ff0e0cd68..7a833d843 100644 --- a/e2e_tests/test_apps/basic.py +++ b/e2e_tests/test_apps/basic.py @@ -143,9 +143,9 @@ class BasicApp(App): sandbox_folder = Path(__file__).parent app = BasicApp( - css_file=sandbox_folder / "basic.css", + css_path=sandbox_folder / "basic.css", watch_css=True, - log=sandbox_folder / "textual.log", + log_path=sandbox_folder / "basic.log", log_verbosity=0, ) diff --git a/examples/animation.py b/examples/animation.py index 7e9206b7d..0a6efaf19 100644 --- a/examples/animation.py +++ b/examples/animation.py @@ -35,4 +35,4 @@ class SmoothApp(App): # self.set_timer(10, lambda: self.action("quit")) -SmoothApp.run(log="textual.log", log_verbosity=2) +SmoothApp.run(log_path="textual.log", log_verbosity=2) diff --git a/examples/big_table.py b/examples/big_table.py index 23a66d47d..7bfc428d7 100644 --- a/examples/big_table.py +++ b/examples/big_table.py @@ -30,4 +30,4 @@ class MyApp(App): await self.call_later(add_content) -MyApp.run(title="Simple App", log="textual.log") +MyApp.run(title="Simple App", log_path="textual.log") diff --git a/examples/borders.py b/examples/borders.py index 694c82717..36e0bae47 100644 --- a/examples/borders.py +++ b/examples/borders.py @@ -55,4 +55,4 @@ class BordersApp(App): self.mount(borders=borders_view) -BordersApp.run(css_file="borders.css", log="textual.log") +BordersApp.run(css_path="borders.css", log_path="textual.log") diff --git a/examples/calculator.py b/examples/calculator.py index 0353c5b60..bbc28badf 100644 --- a/examples/calculator.py +++ b/examples/calculator.py @@ -212,4 +212,4 @@ class CalculatorApp(App): await self.screen.dock(Calculator()) -CalculatorApp.run(title="Calculator Test", log="textual.log") +CalculatorApp.run(title="Calculator Test", log_path="textual.log") diff --git a/examples/code_viewer.py b/examples/code_viewer.py index 4b9def743..6c9e4ce91 100644 --- a/examples/code_viewer.py +++ b/examples/code_viewer.py @@ -67,4 +67,4 @@ class MyApp(App): # Run our app class -MyApp.run(title="Code Viewer", log="textual.log") +MyApp.run(title="Code Viewer", log_path="textual.log") diff --git a/examples/easing.py b/examples/easing.py index 339d414de..447f69e5f 100644 --- a/examples/easing.py +++ b/examples/easing.py @@ -42,4 +42,4 @@ class EasingApp(App): self.side = not self.side -EasingApp().run(log="textual.log") +EasingApp().run(log_path="textual.log") diff --git a/examples/grid.py b/examples/grid.py index 7afe5690b..23873c406 100644 --- a/examples/grid.py +++ b/examples/grid.py @@ -31,4 +31,4 @@ class GridTest(App): ) -GridTest.run(title="Grid Test", log="textual.log") +GridTest.run(title="Grid Test", log_path="textual.log") diff --git a/examples/grid_auto.py b/examples/grid_auto.py index dc811f599..7a738670a 100644 --- a/examples/grid_auto.py +++ b/examples/grid_auto.py @@ -19,4 +19,4 @@ class GridTest(App): grid.place(*placeholders, center=Placeholder()) -GridTest.run(title="Grid Test", log="textual.log") +GridTest.run(title="Grid Test", log_path="textual.log") diff --git a/examples/simple.py b/examples/simple.py index 016328d2c..0d75c5190 100644 --- a/examples/simple.py +++ b/examples/simple.py @@ -48,4 +48,4 @@ class MyApp(App): await self.call_later(get_markdown, "richreadme.md") -MyApp.run(title="Simple App", log="textual.log") +MyApp.run(title="Simple App", log_path="textual.log") diff --git a/sandbox/align.py b/sandbox/align.py index 59984b57e..19cd4a933 100644 --- a/sandbox/align.py +++ b/sandbox/align.py @@ -22,4 +22,4 @@ class AlignApp(App): self.log(self.screen.tree) -AlignApp.run(css_file="align.css", log="textual.log", watch_css=True) +AlignApp.run(css_path="align.css", log_path="textual.log", watch_css=True) diff --git a/sandbox/basic.py b/sandbox/basic.py index a9813f9d1..c56703c57 100644 --- a/sandbox/basic.py +++ b/sandbox/basic.py @@ -1,6 +1,3 @@ -from pathlib import Path - -from rich.align import Align from rich.console import RenderableType from rich.syntax import Syntax from rich.text import Text @@ -141,11 +138,10 @@ class BasicApp(App): self.panic(self.tree) -sandbox_folder = Path(__file__).parent app = BasicApp( - css_file=sandbox_folder / "basic.css", + css_path="basic.css", watch_css=True, - log=sandbox_folder / "textual.log", + log_path="textual.log", ) if __name__ == "__main__": diff --git a/sandbox/buttons.py b/sandbox/buttons.py index 149359573..e61a73baf 100644 --- a/sandbox/buttons.py +++ b/sandbox/buttons.py @@ -5,7 +5,6 @@ from textual import layout class ButtonsApp(App[str]): - def compose(self) -> ComposeResult: yield layout.Vertical( Button("foo", id="foo"), @@ -19,7 +18,7 @@ class ButtonsApp(App[str]): self.exit(event.button.id) -app = ButtonsApp(log="textual.log", log_verbosity=2) +app = ButtonsApp(log_path="textual.log", log_verbosity=2) if __name__ == "__main__": result = app.run() diff --git a/sandbox/dev_sandbox.py b/sandbox/dev_sandbox.py index ffbfcf8c2..0ead807d4 100644 --- a/sandbox/dev_sandbox.py +++ b/sandbox/dev_sandbox.py @@ -34,4 +34,4 @@ class BasicApp(App): self.panic(self.tree) -BasicApp.run(css_file="dev_sandbox.scss", watch_css=True, log="textual.log") +BasicApp.run(css_path="dev_sandbox.scss", watch_css=True, log_path="textual.log") diff --git a/sandbox/local_styles.py b/sandbox/local_styles.py index 17a25fcc3..63bfe9ac9 100644 --- a/sandbox/local_styles.py +++ b/sandbox/local_styles.py @@ -33,4 +33,4 @@ class BasicApp(App): self.log(header.styles) -BasicApp.run(css_file="local_styles.css", log="textual.log") +BasicApp.run(css_path="local_styles.css", log_path="textual.log") diff --git a/sandbox/tabs.py b/sandbox/tabs.py index 1ad1434ff..6bca6162e 100644 --- a/sandbox/tabs.py +++ b/sandbox/tabs.py @@ -144,4 +144,4 @@ class BasicApp(App): self.mount(example.widget) -BasicApp.run(css_file="tabs.scss", watch_css=True, log="textual.log") +BasicApp.run(css_path="tabs.scss", watch_css=True, log_path="textual.log") diff --git a/sandbox/uber.py b/sandbox/uber.py index 0eb90cdbd..09ecf768d 100644 --- a/sandbox/uber.py +++ b/sandbox/uber.py @@ -83,7 +83,7 @@ class BasicApp(App): self.focused.styles.border_top = ("solid", "invalid-color") -app = BasicApp(css_file="uber.css", log="textual.log", log_verbosity=1) +app = BasicApp(css_path="uber.css", log_path="textual.log", log_verbosity=1) if __name__ == "__main__": app.run() diff --git a/src/textual/app.py b/src/textual/app.py index 234893830..aaf200589 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -106,20 +106,20 @@ class App(Generic[ReturnType], DOMNode): def __init__( self, driver_class: Type[Driver] | None = None, - log: str | PurePath = "", + log_path: str | PurePath = "", log_verbosity: int = 1, title: str = "Textual Application", - css_file: str | PurePath | None = None, + css_path: str | PurePath | None = None, watch_css: bool = True, ): """Textual application base class Args: driver_class (Type[Driver] | None, optional): Driver class or ``None`` to auto-detect. Defaults to None. - log (str | PurePath, optional): Path to log file, or "" to disable. Defaults to "". + log_path (str | PurePath, optional): Path to log file, or "" to disable. Defaults to "". log_verbosity (int, optional): Log verbosity from 0-3. Defaults to 1. title (str, optional): Default title of the application. Defaults to "Textual Application". - css_file (str | PurePath | None, optional): Path to CSS or ``None`` for no CSS file. Defaults to None. + css_path (str | PurePath | None, optional): Path to CSS or ``None`` for no CSS file. Defaults to None. watch_css (bool, optional): Watch CSS for changes. Defaults to True. """ # N.B. This must be done *before* we call the parent constructor, because MessagePump's @@ -151,8 +151,8 @@ class App(Generic[ReturnType], DOMNode): self._log_console: Console | None = None self._log_file: TextIO | None = None - if log: - self._log_file = open(log, "wt") + if log_path: + self._log_file = open(log_path, "wt") self._log_console = Console( file=self._log_file, markup=False, @@ -171,10 +171,10 @@ class App(Generic[ReturnType], DOMNode): self.stylesheet = Stylesheet(variables=self.get_css_variables()) self._require_styles_update = False - self.css_file = css_file + self.css_path = css_path self.css_monitor = ( - FileMonitor(css_file, self._on_css_change) - if (watch_css and css_file) + FileMonitor(css_path, self._on_css_change) + if (watch_css and css_path) else None ) @@ -450,13 +450,13 @@ class App(Generic[ReturnType], DOMNode): async def _on_css_change(self) -> None: """Called when the CSS changes (if watch_css is True).""" - if self.css_file is not None: + if self.css_path is not None: try: time = perf_counter() - self.stylesheet.read(self.css_file) + self.stylesheet.read(self.css_path) elapsed = (perf_counter() - time) * 1000 - self.log(f"loaded {self.css_file} in {elapsed:.0f}ms") + self.log(f"loaded {self.css_path} in {elapsed:.0f}ms") except Exception as error: # TODO: Catch specific exceptions self.console.bell() @@ -647,8 +647,8 @@ class App(Generic[ReturnType], DOMNode): except DevtoolsConnectionError: self.log(f"Couldn't connect to devtools ({self.devtools.url})") try: - if self.css_file is not None: - self.stylesheet.read(self.css_file) + if self.css_path is not None: + self.stylesheet.read(self.css_path) if self.CSS is not None: self.stylesheet.add_source( self.CSS, path=f"<{self.__class__.__name__}>" diff --git a/src/textual/css/match.py b/src/textual/css/match.py index 28cb7e5a7..40c0d47ac 100644 --- a/src/textual/css/match.py +++ b/src/textual/css/match.py @@ -36,8 +36,8 @@ def _check_selectors(selectors: list[Selector], node: DOMNode) -> bool: DESCENDENT = CombinatorType.DESCENDENT - css_path = node.css_path - path_count = len(css_path) + css_path_nodes = node.css_path_nodes + path_count = len(css_path_nodes) selector_count = len(selectors) stack: list[tuple[int, int]] = [(0, 0)] @@ -51,7 +51,7 @@ def _check_selectors(selectors: list[Selector], node: DOMNode) -> bool: if selector_index == selector_count or node_index == path_count: pop() else: - path_node = css_path[node_index] + path_node = css_path_nodes[node_index] selector = selectors[selector_index] if selector.combinator == DESCENDENT: # Find a matching descendent diff --git a/src/textual/dom.py b/src/textual/dom.py index 144cca18d..86e0c3eb1 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -167,7 +167,7 @@ class DOMNode(MessagePump): return self.__class__.__name__.lower() @property - def css_path(self) -> list[DOMNode]: + def css_path_nodes(self) -> list[DOMNode]: """A list of nodes from the root to this node, forming a "path". Returns: diff --git a/src/textual/widgets/_directory_tree.py b/src/textual/widgets/_directory_tree.py index 2754a5f7b..0cb60243a 100644 --- a/src/textual/widgets/_directory_tree.py +++ b/src/textual/widgets/_directory_tree.py @@ -132,4 +132,4 @@ if __name__ == "__main__": async def on_mount(self, event: events.Mount) -> None: await self.screen.dock(DirectoryTree("/Users/willmcgugan/projects")) - TreeApp.run(log="textual.log") + TreeApp(log_path="textual.log").run() diff --git a/src/textual/widgets/_tree_control.py b/src/textual/widgets/_tree_control.py index 276386546..a76030077 100644 --- a/src/textual/widgets/_tree_control.py +++ b/src/textual/widgets/_tree_control.py @@ -328,4 +328,4 @@ if __name__ == "__main__": else: await message.node.toggle() - TreeApp.run(log="textual.log") + TreeApp(log_path="textual.log").run()