We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Populating a `ListView` via constructor vs via inherit and `compose`
There seems to be a subtle difference in the working of a `ListView` if you create one by passing the `ListItem`s to it, vs if you create a custom `ListView` by inheriting from it and using `compose` to populate it. Take the following example code, which places both approaches side-by-side:

```python
from textual.app        import App, ComposeResult
from textual.containers import Horizontal
from textual.widgets    import Header, Footer, ListView, ListItem, Label

class CustomListView( ListView ):

    def __init__( self, choices: list[ str ] ) -> None:
        super().__init__()
        self._choices = choices

    def compose( self ) -> ComposeResult:
        """Compose the child widgets."""
        for choice in self._choices:
            yield ListItem( Label( choice ) )

class ListViewMakerApp( App[ None ] ):

    CSS = """
    ListView {
        width: 1fr;
        height: 1fr;
        border: round red;
    }
    """

    OPTIONS = [ f"This is the nifty test option {n}" for n in range( 20 ) ]

    def compose( self ) -> ComposeResult:
        yield Header()
        yield Horizontal(
            ListView(
                *[ ListItem( Label( option ) ) for option in self.OPTIONS ]
            ),
            CustomListView( self.OPTIONS )
        )
        yield Footer()

if __name__ == "__main__":
    ListViewMakerApp().run()
```

I feel the `CustomListView` would not be an unusual approach for people to take; perhaps wanting to make their own commonly-used selection list of simple values (or even very complex child values that they want easily handled). Side-by-side the `ListView`s look the same to start with:

<img width="922" alt="Screenshot 2023-01-17 at 11 10 47" src="https://user-images.githubusercontent.com/28237/212884262-8d5252a8-3318-4f72-a3de-ae5f73b5a41c.png">

Note that the non-inherited `ListView` is to the left and that, even though it doesn't have focus, the first item is highlighted. If you <kbd>tab</kbd> into it you can cursor around, etc, just fine. On the other hand notice that the right `ListView` (which is a `CustomListView`) has no obvious highlighted item and if you tab into it nothing gets highlighted.

Further to this, if you (via keyboard) focus the inherited (right hand) `ListView` and then attempt to cursor down, the following exception will be raised:

```
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /Users/davep/develop/python/textual-sandbox/.venv/lib/python3.10/site-packages/textual/widgets/_ │
│ list_view.py:127 in action_cursor_down                                                           │
│                                                                                                  │
│   124 │   │   self.emit_no_wait(self.Selected(self, selected_child))                             │
│   125 │                                                                                          │
│   126 │   def action_cursor_down(self) -> None:                                                  │
│ ❱ 127 │   │   self.index += 1                                                                    │
│   128 │                                                                                          │
│   129 │   def action_cursor_up(self) -> None:                                                    │
│   130 │   │   self.index -= 1                                                                    │
│                                                                                                  │
│ ╭──────────────────────────── locals ─────────────────────────────╮                              │
│ │ self = CustomListView(pseudo_classes={'focus', 'focus-within'}) │                              │
│ ╰─────────────────────────────────────────────────────────────────╯                              │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
TypeError: unsupported operand type(s) for +=: 'NoneType' and 'int'
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/textual/widgets/_list_view.py`
Content:
```
1 from __future__ import annotations
2 
3 from textual import events
4 from textual.await_remove import AwaitRemove
5 from textual.binding import Binding
6 from textual.containers import Vertical
7 from textual.geometry import clamp
8 from textual.message import Message
9 from textual.reactive import reactive
10 from textual.widget import AwaitMount
11 from textual.widgets._list_item import ListItem
12 
13 
14 class ListView(Vertical, can_focus=True, can_focus_children=False):
15     """Displays a vertical list of `ListItem`s which can be highlighted
16     and selected using the mouse or keyboard.
17 
18     Attributes:
19         index: The index in the list that's currently highlighted.
20     """
21 
22     BINDINGS = [
23         Binding("enter", "select_cursor", "Select", show=False),
24         Binding("up", "cursor_up", "Cursor Up", show=False),
25         Binding("down", "cursor_down", "Cursor Down", show=False),
26     ]
27 
28     index = reactive(0, always_update=True)
29 
30     def __init__(
31         self,
32         *children: ListItem,
33         initial_index: int | None = 0,
34         name: str | None = None,
35         id: str | None = None,
36         classes: str | None = None,
37     ) -> None:
38         """
39         Args:
40             *children: The ListItems to display in the list.
41             initial_index: The index that should be highlighted when the list is first mounted.
42             name: The name of the widget.
43             id: The unique ID of the widget used in CSS/query selection.
44             classes: The CSS classes of the widget.
45         """
46         super().__init__(*children, name=name, id=id, classes=classes)
47         self.index = initial_index
48 
49     @property
50     def highlighted_child(self) -> ListItem | None:
51         """ListItem | None: The currently highlighted ListItem,
52         or None if nothing is highlighted.
53         """
54         if self.index is None:
55             return None
56         elif 0 <= self.index < len(self.children):
57             return self.children[self.index]
58 
59     def validate_index(self, index: int | None) -> int | None:
60         """Clamp the index to the valid range, or set to None if there's nothing to highlight."""
61         if not self.children or index is None:
62             return None
63         return self._clamp_index(index)
64 
65     def _clamp_index(self, index: int) -> int:
66         """Clamp the index to a valid value given the current list of children"""
67         last_index = max(len(self.children) - 1, 0)
68         return clamp(index, 0, last_index)
69 
70     def _is_valid_index(self, index: int | None) -> bool:
71         """Return True if the current index is valid given the current list of children"""
72         if index is None:
73             return False
74         return 0 <= index < len(self.children)
75 
76     def watch_index(self, old_index: int, new_index: int) -> None:
77         """Updates the highlighting when the index changes."""
78         if self._is_valid_index(old_index):
79             old_child = self.children[old_index]
80             old_child.highlighted = False
81         if self._is_valid_index(new_index):
82             new_child = self.children[new_index]
83             new_child.highlighted = True
84         else:
85             new_child = None
86 
87         self._scroll_highlighted_region()
88         self.emit_no_wait(self.Highlighted(self, new_child))
89 
90     def append(self, item: ListItem) -> AwaitMount:
91         """Append a new ListItem to the end of the ListView.
92 
93         Args:
94             item (ListItem): The ListItem to append.
95 
96         Returns:
97             AwaitMount: An awaitable that yields control to the event loop
98                 until the DOM has been updated with the new child item.
99         """
100         await_mount = self.mount(item)
101         if len(self) == 1:
102             self.index = 0
103         return await_mount
104 
105     def clear(self) -> AwaitRemove:
106         """Clear all items from the ListView.
107 
108         Returns:
109             AwaitRemove: An awaitable that yields control to the event loop until
110                 the DOM has been updated to reflect all children being removed.
111         """
112         await_remove = self.query("ListView > ListItem").remove()
113         self.index = None
114         return await_remove
115 
116     def action_select_cursor(self) -> None:
117         selected_child = self.highlighted_child
118         self.emit_no_wait(self.Selected(self, selected_child))
119 
120     def action_cursor_down(self) -> None:
121         self.index += 1
122 
123     def action_cursor_up(self) -> None:
124         self.index -= 1
125 
126     def on_list_item__child_clicked(self, event: ListItem._ChildClicked) -> None:
127         self.focus()
128         self.index = self.children.index(event.sender)
129         self.emit_no_wait(self.Selected(self, event.sender))
130 
131     def _scroll_highlighted_region(self) -> None:
132         """Used to keep the highlighted index within vision"""
133         if self.highlighted_child is not None:
134             self.scroll_to_widget(self.highlighted_child, animate=False)
135 
136     def __len__(self):
137         return len(self.children)
138 
139     class Highlighted(Message, bubble=True):
140         """Emitted when the highlighted item changes. Highlighted item is controlled using up/down keys.
141 
142         Attributes:
143             item (ListItem | None): The highlighted item, if there is one highlighted.
144         """
145 
146         def __init__(self, sender: ListView, item: ListItem | None) -> None:
147             super().__init__(sender)
148             self.item = item
149 
150     class Selected(Message, bubble=True):
151         """Emitted when a list item is selected, e.g. when you press the enter key on it
152 
153         Attributes:
154             item (ListItem): The selected item.
155         """
156 
157         def __init__(self, sender: ListView, item: ListItem) -> None:
158             super().__init__(sender)
159             self.item = item
160
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/textual/widgets/_list_view.py b/src/textual/widgets/_list_view.py
--- a/src/textual/widgets/_list_view.py
+++ b/src/textual/widgets/_list_view.py
@@ -50,7 +50,11 @@
             classes: The CSS classes of the widget.
         """
         super().__init__(*children, name=name, id=id, classes=classes)
-        self.index = initial_index
+        self._index = initial_index
+
+    def on_mount(self) -> None:
+        """Ensure the ListView is fully-settled after mounting."""
+        self.index = self._index
 
     @property
     def highlighted_child(self) -> ListItem | None:

{"golden_diff": "diff --git a/src/textual/widgets/_list_view.py b/src/textual/widgets/_list_view.py\n--- a/src/textual/widgets/_list_view.py\n+++ b/src/textual/widgets/_list_view.py\n@@ -50,7 +50,11 @@\n             classes: The CSS classes of the widget.\n         \"\"\"\n         super().__init__(*children, name=name, id=id, classes=classes)\n-        self.index = initial_index\n+        self._index = initial_index\n+\n+    def on_mount(self) -> None:\n+        \"\"\"Ensure the ListView is fully-settled after mounting.\"\"\"\n+        self.index = self._index\n \n     @property\n     def highlighted_child(self) -> ListItem | None:\n", "issue": "Populating a `ListView` via constructor vs via inherit and `compose`\nThere seems to be a subtle difference in the working of a `ListView` if you create one by passing the `ListItem`s to it, vs if you create a custom `ListView` by inheriting from it and using `compose` to populate it. Take the following example code, which places both approaches side-by-side:\r\n\r\n```python\r\nfrom textual.app        import App, ComposeResult\r\nfrom textual.containers import Horizontal\r\nfrom textual.widgets    import Header, Footer, ListView, ListItem, Label\r\n\r\nclass CustomListView( ListView ):\r\n\r\n    def __init__( self, choices: list[ str ] ) -> None:\r\n        super().__init__()\r\n        self._choices = choices\r\n\r\n    def compose( self ) -> ComposeResult:\r\n        \"\"\"Compose the child widgets.\"\"\"\r\n        for choice in self._choices:\r\n            yield ListItem( Label( choice ) )\r\n\r\nclass ListViewMakerApp( App[ None ] ):\r\n\r\n    CSS = \"\"\"\r\n    ListView {\r\n        width: 1fr;\r\n        height: 1fr;\r\n        border: round red;\r\n    }\r\n    \"\"\"\r\n\r\n    OPTIONS = [ f\"This is the nifty test option {n}\" for n in range( 20 ) ]\r\n\r\n    def compose( self ) -> ComposeResult:\r\n        yield Header()\r\n        yield Horizontal(\r\n            ListView(\r\n                *[ ListItem( Label( option ) ) for option in self.OPTIONS ]\r\n            ),\r\n            CustomListView( self.OPTIONS )\r\n        )\r\n        yield Footer()\r\n\r\nif __name__ == \"__main__\":\r\n    ListViewMakerApp().run()\r\n```\r\n\r\nI feel the `CustomListView` would not be an unusual approach for people to take; perhaps wanting to make their own commonly-used selection list of simple values (or even very complex child values that they want easily handled). Side-by-side the `ListView`s look the same to start with:\r\n\r\n<img width=\"922\" alt=\"Screenshot 2023-01-17 at 11 10 47\" src=\"https://user-images.githubusercontent.com/28237/212884262-8d5252a8-3318-4f72-a3de-ae5f73b5a41c.png\">\r\n\r\nNote that the non-inherited `ListView` is to the left and that, even though it doesn't have focus, the first item is highlighted. If you <kbd>tab</kbd> into it you can cursor around, etc, just fine. On the other hand notice that the right `ListView` (which is a `CustomListView`) has no obvious highlighted item and if you tab into it nothing gets highlighted.\r\n\r\nFurther to this, if you (via keyboard) focus the inherited (right hand) `ListView` and then attempt to cursor down, the following exception will be raised:\r\n\r\n```\r\n\u256d\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Traceback (most recent call last) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e\r\n\u2502 /Users/davep/develop/python/textual-sandbox/.venv/lib/python3.10/site-packages/textual/widgets/_ \u2502\r\n\u2502 list_view.py:127 in action_cursor_down                                                           \u2502\r\n\u2502                                                                                                  \u2502\r\n\u2502   124 \u2502   \u2502   self.emit_no_wait(self.Selected(self, selected_child))                             \u2502\r\n\u2502   125 \u2502                                                                                          \u2502\r\n\u2502   126 \u2502   def action_cursor_down(self) -> None:                                                  \u2502\r\n\u2502 \u2771 127 \u2502   \u2502   self.index += 1                                                                    \u2502\r\n\u2502   128 \u2502                                                                                          \u2502\r\n\u2502   129 \u2502   def action_cursor_up(self) -> None:                                                    \u2502\r\n\u2502   130 \u2502   \u2502   self.index -= 1                                                                    \u2502\r\n\u2502                                                                                                  \u2502\r\n\u2502 \u256d\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 locals \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256e                              \u2502\r\n\u2502 \u2502 self = CustomListView(pseudo_classes={'focus', 'focus-within'}) \u2502                              \u2502\r\n\u2502 \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f                              \u2502\r\n\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256f\r\nTypeError: unsupported operand type(s) for +=: 'NoneType' and 'int'\r\n```\n", "before_files": [{"content": "from __future__ import annotations\n\nfrom textual import events\nfrom textual.await_remove import AwaitRemove\nfrom textual.binding import Binding\nfrom textual.containers import Vertical\nfrom textual.geometry import clamp\nfrom textual.message import Message\nfrom textual.reactive import reactive\nfrom textual.widget import AwaitMount\nfrom textual.widgets._list_item import ListItem\n\n\nclass ListView(Vertical, can_focus=True, can_focus_children=False):\n    \"\"\"Displays a vertical list of `ListItem`s which can be highlighted\n    and selected using the mouse or keyboard.\n\n    Attributes:\n        index: The index in the list that's currently highlighted.\n    \"\"\"\n\n    BINDINGS = [\n        Binding(\"enter\", \"select_cursor\", \"Select\", show=False),\n        Binding(\"up\", \"cursor_up\", \"Cursor Up\", show=False),\n        Binding(\"down\", \"cursor_down\", \"Cursor Down\", show=False),\n    ]\n\n    index = reactive(0, always_update=True)\n\n    def __init__(\n        self,\n        *children: ListItem,\n        initial_index: int | None = 0,\n        name: str | None = None,\n        id: str | None = None,\n        classes: str | None = None,\n    ) -> None:\n        \"\"\"\n        Args:\n            *children: The ListItems to display in the list.\n            initial_index: The index that should be highlighted when the list is first mounted.\n            name: The name of the widget.\n            id: The unique ID of the widget used in CSS/query selection.\n            classes: The CSS classes of the widget.\n        \"\"\"\n        super().__init__(*children, name=name, id=id, classes=classes)\n        self.index = initial_index\n\n    @property\n    def highlighted_child(self) -> ListItem | None:\n        \"\"\"ListItem | None: The currently highlighted ListItem,\n        or None if nothing is highlighted.\n        \"\"\"\n        if self.index is None:\n            return None\n        elif 0 <= self.index < len(self.children):\n            return self.children[self.index]\n\n    def validate_index(self, index: int | None) -> int | None:\n        \"\"\"Clamp the index to the valid range, or set to None if there's nothing to highlight.\"\"\"\n        if not self.children or index is None:\n            return None\n        return self._clamp_index(index)\n\n    def _clamp_index(self, index: int) -> int:\n        \"\"\"Clamp the index to a valid value given the current list of children\"\"\"\n        last_index = max(len(self.children) - 1, 0)\n        return clamp(index, 0, last_index)\n\n    def _is_valid_index(self, index: int | None) -> bool:\n        \"\"\"Return True if the current index is valid given the current list of children\"\"\"\n        if index is None:\n            return False\n        return 0 <= index < len(self.children)\n\n    def watch_index(self, old_index: int, new_index: int) -> None:\n        \"\"\"Updates the highlighting when the index changes.\"\"\"\n        if self._is_valid_index(old_index):\n            old_child = self.children[old_index]\n            old_child.highlighted = False\n        if self._is_valid_index(new_index):\n            new_child = self.children[new_index]\n            new_child.highlighted = True\n        else:\n            new_child = None\n\n        self._scroll_highlighted_region()\n        self.emit_no_wait(self.Highlighted(self, new_child))\n\n    def append(self, item: ListItem) -> AwaitMount:\n        \"\"\"Append a new ListItem to the end of the ListView.\n\n        Args:\n            item (ListItem): The ListItem to append.\n\n        Returns:\n            AwaitMount: An awaitable that yields control to the event loop\n                until the DOM has been updated with the new child item.\n        \"\"\"\n        await_mount = self.mount(item)\n        if len(self) == 1:\n            self.index = 0\n        return await_mount\n\n    def clear(self) -> AwaitRemove:\n        \"\"\"Clear all items from the ListView.\n\n        Returns:\n            AwaitRemove: An awaitable that yields control to the event loop until\n                the DOM has been updated to reflect all children being removed.\n        \"\"\"\n        await_remove = self.query(\"ListView > ListItem\").remove()\n        self.index = None\n        return await_remove\n\n    def action_select_cursor(self) -> None:\n        selected_child = self.highlighted_child\n        self.emit_no_wait(self.Selected(self, selected_child))\n\n    def action_cursor_down(self) -> None:\n        self.index += 1\n\n    def action_cursor_up(self) -> None:\n        self.index -= 1\n\n    def on_list_item__child_clicked(self, event: ListItem._ChildClicked) -> None:\n        self.focus()\n        self.index = self.children.index(event.sender)\n        self.emit_no_wait(self.Selected(self, event.sender))\n\n    def _scroll_highlighted_region(self) -> None:\n        \"\"\"Used to keep the highlighted index within vision\"\"\"\n        if self.highlighted_child is not None:\n            self.scroll_to_widget(self.highlighted_child, animate=False)\n\n    def __len__(self):\n        return len(self.children)\n\n    class Highlighted(Message, bubble=True):\n        \"\"\"Emitted when the highlighted item changes. Highlighted item is controlled using up/down keys.\n\n        Attributes:\n            item (ListItem | None): The highlighted item, if there is one highlighted.\n        \"\"\"\n\n        def __init__(self, sender: ListView, item: ListItem | None) -> None:\n            super().__init__(sender)\n            self.item = item\n\n    class Selected(Message, bubble=True):\n        \"\"\"Emitted when a list item is selected, e.g. when you press the enter key on it\n\n        Attributes:\n            item (ListItem): The selected item.\n        \"\"\"\n\n        def __init__(self, sender: ListView, item: ListItem) -> None:\n            super().__init__(sender)\n            self.item = item\n", "path": "src/textual/widgets/_list_view.py"}], "after_files": [{"content": "from __future__ import annotations\n\nfrom textual import events\nfrom textual.await_remove import AwaitRemove\nfrom textual.binding import Binding\nfrom textual.containers import Vertical\nfrom textual.geometry import clamp\nfrom textual.message import Message\nfrom textual.reactive import reactive\nfrom textual.widget import AwaitMount\nfrom textual.widgets._list_item import ListItem\n\n\nclass ListView(Vertical, can_focus=True, can_focus_children=False):\n    \"\"\"Displays a vertical list of `ListItem`s which can be highlighted\n    and selected using the mouse or keyboard.\n\n    Attributes:\n        index: The index in the list that's currently highlighted.\n    \"\"\"\n\n    DEFAULT_CSS = \"\"\"\n    ListView {\n        scrollbar-size-vertical: 2;\n    }\n    \"\"\"\n\n    BINDINGS = [\n        Binding(\"down\", \"cursor_down\", \"Down\", show=False),\n        Binding(\"up\", \"cursor_up\", \"Up\", show=False),\n        Binding(\"enter\", \"select_cursor\", \"Select\", show=False),\n    ]\n\n    index = reactive(0, always_update=True)\n\n    def __init__(\n        self,\n        *children: ListItem,\n        initial_index: int | None = 0,\n        name: str | None = None,\n        id: str | None = None,\n        classes: str | None = None,\n    ) -> None:\n        \"\"\"\n        Args:\n            *children: The ListItems to display in the list.\n            initial_index: The index that should be highlighted when the list is first mounted.\n            name: The name of the widget.\n            id: The unique ID of the widget used in CSS/query selection.\n            classes: The CSS classes of the widget.\n        \"\"\"\n        super().__init__(*children, name=name, id=id, classes=classes)\n        self._index = initial_index\n\n    def on_mount(self) -> None:\n        \"\"\"Ensure the ListView is fully-settled after mounting.\"\"\"\n        self.index = self._index\n\n    @property\n    def highlighted_child(self) -> ListItem | None:\n        \"\"\"ListItem | None: The currently highlighted ListItem,\n        or None if nothing is highlighted.\n        \"\"\"\n        if self.index is None:\n            return None\n        elif 0 <= self.index < len(self.children):\n            return self.children[self.index]\n\n    def validate_index(self, index: int | None) -> int | None:\n        \"\"\"Clamp the index to the valid range, or set to None if there's nothing to highlight.\"\"\"\n        if not self.children or index is None:\n            return None\n        return self._clamp_index(index)\n\n    def _clamp_index(self, index: int) -> int:\n        \"\"\"Clamp the index to a valid value given the current list of children\"\"\"\n        last_index = max(len(self.children) - 1, 0)\n        return clamp(index, 0, last_index)\n\n    def _is_valid_index(self, index: int | None) -> bool:\n        \"\"\"Return True if the current index is valid given the current list of children\"\"\"\n        if index is None:\n            return False\n        return 0 <= index < len(self.children)\n\n    def watch_index(self, old_index: int, new_index: int) -> None:\n        \"\"\"Updates the highlighting when the index changes.\"\"\"\n        if self._is_valid_index(old_index):\n            old_child = self.children[old_index]\n            old_child.highlighted = False\n        if self._is_valid_index(new_index):\n            new_child = self.children[new_index]\n            new_child.highlighted = True\n        else:\n            new_child = None\n\n        self._scroll_highlighted_region()\n        self.emit_no_wait(self.Highlighted(self, new_child))\n\n    def append(self, item: ListItem) -> AwaitMount:\n        \"\"\"Append a new ListItem to the end of the ListView.\n\n        Args:\n            item (ListItem): The ListItem to append.\n\n        Returns:\n            AwaitMount: An awaitable that yields control to the event loop\n                until the DOM has been updated with the new child item.\n        \"\"\"\n        await_mount = self.mount(item)\n        if len(self) == 1:\n            self.index = 0\n        return await_mount\n\n    def clear(self) -> AwaitRemove:\n        \"\"\"Clear all items from the ListView.\n\n        Returns:\n            AwaitRemove: An awaitable that yields control to the event loop until\n                the DOM has been updated to reflect all children being removed.\n        \"\"\"\n        await_remove = self.query(\"ListView > ListItem\").remove()\n        self.index = None\n        return await_remove\n\n    def action_select_cursor(self) -> None:\n        selected_child = self.highlighted_child\n        self.emit_no_wait(self.Selected(self, selected_child))\n\n    def action_cursor_down(self) -> None:\n        self.index += 1\n\n    def action_cursor_up(self) -> None:\n        self.index -= 1\n\n    def on_list_item__child_clicked(self, event: ListItem._ChildClicked) -> None:\n        self.focus()\n        self.index = self.children.index(event.sender)\n        self.emit_no_wait(self.Selected(self, event.sender))\n\n    def _scroll_highlighted_region(self) -> None:\n        \"\"\"Used to keep the highlighted index within vision\"\"\"\n        if self.highlighted_child is not None:\n            self.scroll_to_widget(self.highlighted_child, animate=False)\n\n    def __len__(self):\n        return len(self.children)\n\n    class Highlighted(Message, bubble=True):\n        \"\"\"Emitted when the highlighted item changes. Highlighted item is controlled using up/down keys.\n\n        Attributes:\n            item (ListItem | None): The highlighted item, if there is one highlighted.\n        \"\"\"\n\n        def __init__(self, sender: ListView, item: ListItem | None) -> None:\n            super().__init__(sender)\n            self.item = item\n\n    class Selected(Message, bubble=True):\n        \"\"\"Emitted when a list item is selected, e.g. when you press the enter key on it\n\n        Attributes:\n            item (ListItem): The selected item.\n        \"\"\"\n\n        def __init__(self, sender: ListView, item: ListItem) -> None:\n            super().__init__(sender)\n            self.item = item\n", "path": "src/textual/widgets/_list_view.py"}]}