euporie 2.8.4__py3-none-any.whl → 2.8.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. euporie/console/_commands.py +143 -0
  2. euporie/console/_settings.py +58 -0
  3. euporie/console/app.py +25 -71
  4. euporie/console/tabs/console.py +58 -62
  5. euporie/core/__init__.py +1 -1
  6. euporie/core/__main__.py +28 -11
  7. euporie/core/_settings.py +109 -0
  8. euporie/core/app/__init__.py +3 -0
  9. euporie/core/app/_commands.py +95 -0
  10. euporie/core/app/_settings.py +457 -0
  11. euporie/core/{app.py → app/app.py} +212 -576
  12. euporie/core/app/base.py +51 -0
  13. euporie/core/{current.py → app/current.py} +13 -4
  14. euporie/core/app/cursor.py +35 -0
  15. euporie/core/app/dummy.py +12 -0
  16. euporie/core/app/launch.py +28 -0
  17. euporie/core/bars/__init__.py +11 -0
  18. euporie/core/bars/command.py +205 -0
  19. euporie/core/bars/menu.py +258 -0
  20. euporie/core/{widgets → bars}/search.py +20 -16
  21. euporie/core/{widgets → bars}/status.py +6 -23
  22. euporie/core/clipboard.py +19 -80
  23. euporie/core/comm/base.py +8 -6
  24. euporie/core/comm/ipywidgets.py +16 -7
  25. euporie/core/comm/registry.py +2 -1
  26. euporie/core/commands.py +10 -20
  27. euporie/core/completion.py +3 -2
  28. euporie/core/config.py +368 -341
  29. euporie/core/convert/__init__.py +0 -30
  30. euporie/core/convert/datum.py +116 -53
  31. euporie/core/convert/formats/__init__.py +31 -0
  32. euporie/core/convert/formats/ansi.py +9 -23
  33. euporie/core/convert/formats/common.py +11 -23
  34. euporie/core/convert/formats/html.py +45 -40
  35. euporie/core/convert/formats/pil.py +1 -1
  36. euporie/core/convert/formats/png.py +3 -5
  37. euporie/core/convert/formats/sixel.py +3 -3
  38. euporie/core/convert/registry.py +4 -6
  39. euporie/core/convert/utils.py +41 -4
  40. euporie/core/diagnostics.py +2 -2
  41. euporie/core/filters.py +98 -40
  42. euporie/core/format.py +2 -3
  43. euporie/core/ft/ansi.py +1 -1
  44. euporie/core/ft/html.py +12 -21
  45. euporie/core/ft/table.py +1 -3
  46. euporie/core/ft/utils.py +4 -1
  47. euporie/core/graphics.py +386 -133
  48. euporie/core/history.py +2 -2
  49. euporie/core/inspection.py +3 -2
  50. euporie/core/io.py +207 -28
  51. euporie/core/kernel/__init__.py +1 -0
  52. euporie/core/{kernel.py → kernel/client.py} +45 -108
  53. euporie/core/kernel/manager.py +114 -0
  54. euporie/core/key_binding/bindings/__init__.py +1 -8
  55. euporie/core/key_binding/bindings/basic.py +47 -7
  56. euporie/core/key_binding/bindings/completion.py +3 -8
  57. euporie/core/key_binding/bindings/micro.py +1 -6
  58. euporie/core/key_binding/bindings/mouse.py +2 -2
  59. euporie/core/key_binding/bindings/terminal.py +193 -0
  60. euporie/core/key_binding/key_processor.py +43 -2
  61. euporie/core/key_binding/registry.py +2 -0
  62. euporie/core/key_binding/utils.py +22 -2
  63. euporie/core/keys.py +7156 -93
  64. euporie/core/layout/cache.py +3 -3
  65. euporie/core/layout/containers.py +48 -4
  66. euporie/core/layout/decor.py +2 -2
  67. euporie/core/layout/mouse.py +1 -1
  68. euporie/core/layout/print.py +2 -1
  69. euporie/core/layout/scroll.py +39 -34
  70. euporie/core/log.py +76 -64
  71. euporie/core/lsp.py +118 -24
  72. euporie/core/margins.py +1 -1
  73. euporie/core/path.py +62 -13
  74. euporie/core/renderer.py +58 -17
  75. euporie/core/style.py +57 -39
  76. euporie/core/suggest.py +103 -85
  77. euporie/core/tabs/__init__.py +32 -0
  78. euporie/core/tabs/_settings.py +113 -0
  79. euporie/core/tabs/base.py +80 -470
  80. euporie/core/tabs/kernel.py +419 -0
  81. euporie/core/tabs/notebook.py +24 -101
  82. euporie/core/utils.py +92 -15
  83. euporie/core/validation.py +1 -1
  84. euporie/core/widgets/_settings.py +188 -0
  85. euporie/core/widgets/cell.py +19 -50
  86. euporie/core/widgets/cell_outputs.py +25 -36
  87. euporie/core/widgets/decor.py +11 -41
  88. euporie/core/widgets/dialog.py +62 -27
  89. euporie/core/widgets/display.py +12 -15
  90. euporie/core/widgets/file_browser.py +2 -23
  91. euporie/core/widgets/forms.py +8 -5
  92. euporie/core/widgets/inputs.py +13 -70
  93. euporie/core/widgets/layout.py +2 -1
  94. euporie/core/widgets/logo.py +49 -0
  95. euporie/core/widgets/menu.py +10 -8
  96. euporie/core/widgets/pager.py +6 -10
  97. euporie/core/widgets/palette.py +6 -6
  98. euporie/hub/app.py +52 -35
  99. euporie/notebook/_commands.py +24 -0
  100. euporie/notebook/_settings.py +107 -0
  101. euporie/notebook/app.py +49 -171
  102. euporie/notebook/filters.py +1 -1
  103. euporie/notebook/tabs/__init__.py +46 -7
  104. euporie/notebook/tabs/_commands.py +714 -0
  105. euporie/notebook/tabs/_settings.py +32 -0
  106. euporie/notebook/tabs/display.py +4 -4
  107. euporie/notebook/tabs/edit.py +11 -44
  108. euporie/notebook/tabs/json.py +5 -5
  109. euporie/notebook/tabs/log.py +1 -18
  110. euporie/notebook/tabs/notebook.py +11 -660
  111. euporie/notebook/widgets/_commands.py +11 -0
  112. euporie/notebook/widgets/_settings.py +19 -0
  113. euporie/notebook/widgets/side_bar.py +14 -34
  114. euporie/preview/_settings.py +104 -0
  115. euporie/preview/app.py +6 -31
  116. euporie/preview/tabs/notebook.py +6 -72
  117. euporie/web/__init__.py +1 -0
  118. euporie/web/tabs/__init__.py +14 -0
  119. euporie/web/tabs/web.py +11 -6
  120. euporie/web/widgets/__init__.py +1 -0
  121. euporie/web/widgets/webview.py +5 -15
  122. {euporie-2.8.4.dist-info → euporie-2.8.6.dist-info}/METADATA +10 -8
  123. euporie-2.8.6.dist-info/RECORD +175 -0
  124. {euporie-2.8.4.dist-info → euporie-2.8.6.dist-info}/WHEEL +1 -1
  125. {euporie-2.8.4.dist-info → euporie-2.8.6.dist-info}/entry_points.txt +2 -2
  126. {euporie-2.8.4.dist-info → euporie-2.8.6.dist-info}/licenses/LICENSE +1 -1
  127. euporie/core/launch.py +0 -64
  128. euporie/core/terminal.py +0 -522
  129. euporie-2.8.4.dist-info/RECORD +0 -147
  130. {euporie-2.8.4.data → euporie-2.8.6.data}/data/share/applications/euporie-console.desktop +0 -0
  131. {euporie-2.8.4.data → euporie-2.8.6.data}/data/share/applications/euporie-notebook.desktop +0 -0
@@ -0,0 +1,714 @@
1
+ """Defines tab commands."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from prompt_toolkit.filters import (
8
+ buffer_has_focus,
9
+ has_completions,
10
+ vi_mode,
11
+ vi_navigation_mode,
12
+ )
13
+
14
+ from euporie.core.app.current import get_app
15
+ from euporie.core.commands import add_cmd, get_cmd
16
+ from euporie.core.filters import (
17
+ cursor_on_first_line,
18
+ cursor_on_last_line,
19
+ display_has_focus,
20
+ kernel_tab_has_focus,
21
+ multiple_cells_selected,
22
+ )
23
+ from euporie.core.tabs.kernel import KernelTab
24
+ from euporie.notebook.filters import (
25
+ cell_has_focus,
26
+ code_cell_selected,
27
+ deleted_cells,
28
+ notebook_has_focus,
29
+ )
30
+
31
+ if TYPE_CHECKING:
32
+ from prompt_toolkit.key_binding.key_bindings import NotImplementedOrNone
33
+
34
+ # euporie.notebook.tabs.log
35
+
36
+
37
+ @add_cmd()
38
+ def _view_logs() -> None:
39
+ """Open the logs in a new tab."""
40
+ from euporie.notebook.tabs.log import LogView
41
+
42
+ app = get_app()
43
+ for tab in app.tabs:
44
+ if isinstance(tab, LogView):
45
+ break
46
+ else:
47
+ tab = LogView(app)
48
+ app.add_tab(tab)
49
+ tab.focus()
50
+
51
+
52
+ # euporie.notebook.tabs.notebook
53
+
54
+
55
+ @add_cmd(
56
+ filter=cell_has_focus & ~buffer_has_focus,
57
+ )
58
+ def _enter_cell_edit_mode() -> None:
59
+ """Enter cell edit mode."""
60
+ from euporie.notebook.tabs.notebook import Notebook
61
+
62
+ if isinstance(nb := get_app().tab, Notebook):
63
+ nb.enter_edit_mode()
64
+
65
+
66
+ @add_cmd(
67
+ filter=cell_has_focus
68
+ & buffer_has_focus
69
+ & (~vi_mode | (vi_mode & vi_navigation_mode)),
70
+ )
71
+ def _exit_edit_mode() -> None:
72
+ """Exit cell edit mode."""
73
+ from euporie.notebook.tabs.notebook import Notebook
74
+
75
+ if isinstance(nb := get_app().tab, Notebook):
76
+ nb.exit_edit_mode()
77
+
78
+
79
+ @add_cmd(
80
+ filter=cell_has_focus,
81
+ )
82
+ def _run_selected_cells() -> None:
83
+ """Run or render the current cells."""
84
+ from euporie.notebook.tabs.notebook import Notebook
85
+
86
+ if isinstance(nb := get_app().tab, Notebook):
87
+ nb.run_selected_cells()
88
+
89
+
90
+ @add_cmd(
91
+ title="Run selected cells and select next cell",
92
+ filter=cell_has_focus,
93
+ )
94
+ def _run_and_select_next() -> None:
95
+ """Run or render the current cells and select the next cell."""
96
+ from euporie.notebook.tabs.notebook import Notebook
97
+
98
+ if isinstance(nb := get_app().tab, Notebook):
99
+ nb.run_selected_cells(advance=True)
100
+
101
+
102
+ @add_cmd(
103
+ filter=cell_has_focus,
104
+ )
105
+ def _run_cell_and_insert_below() -> None:
106
+ """Run or render the current cells and insert a new cell below."""
107
+ from euporie.notebook.tabs.notebook import Notebook
108
+
109
+ if isinstance(nb := get_app().tab, Notebook):
110
+ nb.run_selected_cells(insert=True)
111
+
112
+
113
+ @add_cmd(
114
+ filter=notebook_has_focus,
115
+ )
116
+ def _run_all_cells() -> None:
117
+ """Run or render all the cells in the current notebook."""
118
+ from euporie.notebook.tabs.notebook import Notebook
119
+
120
+ if isinstance(nb := get_app().tab, Notebook):
121
+ nb.run_all()
122
+
123
+
124
+ @add_cmd(
125
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
126
+ )
127
+ def _add_cell_above() -> None:
128
+ """Add a new cell above the current."""
129
+ from euporie.notebook.tabs.notebook import Notebook
130
+
131
+ if isinstance(nb := get_app().tab, Notebook):
132
+ nb.add_cell_above()
133
+
134
+
135
+ @add_cmd(
136
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
137
+ )
138
+ def _add_cell_below() -> None:
139
+ """Add a new cell below the current."""
140
+ from euporie.notebook.tabs.notebook import Notebook
141
+
142
+ if isinstance(nb := get_app().tab, Notebook):
143
+ nb.add_cell_below()
144
+
145
+
146
+ @add_cmd(
147
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
148
+ )
149
+ def _delete_cells() -> None:
150
+ """Delete the current cells."""
151
+ from euporie.notebook.tabs.notebook import Notebook
152
+
153
+ if isinstance(nb := get_app().tab, Notebook):
154
+ nb.delete()
155
+
156
+
157
+ @add_cmd(
158
+ menu_title="Undo delete cell",
159
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus & deleted_cells,
160
+ )
161
+ def _undelete_cells() -> None:
162
+ """Undelete the last deleted cells."""
163
+ from euporie.notebook.tabs.notebook import Notebook
164
+
165
+ if isinstance(nb := get_app().tab, Notebook):
166
+ nb.undelete()
167
+
168
+
169
+ @add_cmd(
170
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
171
+ )
172
+ def _cut_cells() -> None:
173
+ """Cut the current cells."""
174
+ from euporie.notebook.tabs.notebook import Notebook
175
+
176
+ if isinstance(nb := get_app().tab, Notebook):
177
+ nb.cut()
178
+
179
+
180
+ @add_cmd(
181
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
182
+ )
183
+ def _copy_cells() -> None:
184
+ """Copy the current cells."""
185
+ from euporie.notebook.tabs.notebook import Notebook
186
+
187
+ if isinstance(nb := get_app().tab, Notebook):
188
+ nb.copy()
189
+
190
+
191
+ @add_cmd(
192
+ menu_title="Copy cell outputs",
193
+ filter=cell_has_focus & ~buffer_has_focus,
194
+ )
195
+ def _copy_outputs() -> None:
196
+ """Copy the cell's output to the clipboard."""
197
+ from euporie.notebook.tabs.notebook import Notebook
198
+
199
+ if isinstance(nb := get_app().tab, Notebook):
200
+ nb.copy_outputs()
201
+
202
+
203
+ @add_cmd(
204
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
205
+ )
206
+ def _paste_cells() -> None:
207
+ """Pate the previously copied cells."""
208
+ from euporie.notebook.tabs.notebook import Notebook
209
+
210
+ if isinstance(nb := get_app().tab, Notebook):
211
+ nb.paste()
212
+
213
+
214
+ @add_cmd(
215
+ filter=notebook_has_focus
216
+ & ~buffer_has_focus
217
+ & ~display_has_focus
218
+ & multiple_cells_selected,
219
+ )
220
+ def _merge_cells() -> None:
221
+ """Merge the selected cells."""
222
+ from euporie.notebook.tabs.notebook import Notebook
223
+
224
+ if isinstance(nb := get_app().tab, Notebook):
225
+ nb.merge()
226
+
227
+
228
+ @add_cmd(
229
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
230
+ )
231
+ @add_cmd(
232
+ filter=notebook_has_focus,
233
+ )
234
+ def _scroll_up() -> NotImplementedOrNone:
235
+ """Scroll the page up a line."""
236
+ from euporie.notebook.tabs.notebook import Notebook
237
+
238
+ if isinstance(nb := get_app().tab, Notebook):
239
+ return nb.page.scroll(1)
240
+ return None
241
+
242
+
243
+ @add_cmd(
244
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
245
+ )
246
+ @add_cmd(
247
+ filter=notebook_has_focus,
248
+ )
249
+ def _scroll_down() -> NotImplementedOrNone:
250
+ """Scroll the page down a line."""
251
+ from euporie.notebook.tabs.notebook import Notebook
252
+
253
+ if isinstance(nb := get_app().tab, Notebook):
254
+ return nb.page.scroll(-1)
255
+ return None
256
+
257
+
258
+ @add_cmd(
259
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
260
+ )
261
+ def _scroll_up_5_lines() -> None:
262
+ """Scroll the page up 5 lines."""
263
+ from euporie.notebook.tabs.notebook import Notebook
264
+
265
+ if isinstance(nb := get_app().tab, Notebook):
266
+ nb.page.scroll(5)
267
+
268
+
269
+ @add_cmd(
270
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
271
+ )
272
+ def _scroll_down_5_lines() -> None:
273
+ """Scroll the page down 5 lines."""
274
+ from euporie.notebook.tabs.notebook import Notebook
275
+
276
+ if isinstance(nb := get_app().tab, Notebook):
277
+ nb.page.scroll(-5)
278
+
279
+
280
+ @add_cmd(
281
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
282
+ )
283
+ def _select_first_cell() -> None:
284
+ """Select the first cell in the notebook."""
285
+ from euporie.notebook.tabs.notebook import Notebook
286
+
287
+ if isinstance(nb := get_app().tab, Notebook):
288
+ nb.select(0)
289
+
290
+
291
+ @add_cmd(
292
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
293
+ )
294
+ def _select_5th_previous_cell() -> None:
295
+ """Go up 5 cells."""
296
+ from euporie.notebook.tabs.notebook import Notebook
297
+
298
+ if isinstance(nb := get_app().tab, Notebook):
299
+ nb.select(nb.page.selected_slice.start - 5)
300
+
301
+
302
+ @add_cmd(
303
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
304
+ )
305
+ def _select_previous_cell() -> None:
306
+ """Go up one cell."""
307
+ from euporie.notebook.tabs.notebook import Notebook
308
+
309
+ if isinstance(nb := get_app().tab, Notebook):
310
+ nb.select(nb.page.selected_slice.start - 1)
311
+
312
+
313
+ @add_cmd(
314
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
315
+ )
316
+ def _select_next_cell() -> None:
317
+ """Select the next cell."""
318
+ from euporie.notebook.tabs.notebook import Notebook
319
+
320
+ if isinstance(nb := get_app().tab, Notebook):
321
+ nb.select(nb.page.selected_slice.start + 1)
322
+
323
+
324
+ @add_cmd(
325
+ filter=~buffer_has_focus,
326
+ )
327
+ def _select_5th_next_cell() -> None:
328
+ """Go down 5 cells."""
329
+ from euporie.notebook.tabs.notebook import Notebook
330
+
331
+ if isinstance(nb := get_app().tab, Notebook):
332
+ nb.select(nb.page.selected_slice.start + 5)
333
+
334
+
335
+ @add_cmd(
336
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
337
+ )
338
+ def _select_last_cell() -> None:
339
+ """Select the last cell in the notebook."""
340
+ from euporie.notebook.tabs.notebook import Notebook
341
+
342
+ if isinstance(nb := get_app().tab, Notebook):
343
+ nb.select(len(nb.page.all_children()) - 1)
344
+
345
+
346
+ @add_cmd(
347
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
348
+ )
349
+ def _select_all_cells() -> None:
350
+ """Select all cells in the notebook."""
351
+ from euporie.notebook.tabs.notebook import Notebook
352
+
353
+ if isinstance(nb := get_app().tab, Notebook):
354
+ nb.page.selected_slice = slice(
355
+ 0,
356
+ len(nb.page.all_children()) + 1,
357
+ )
358
+
359
+
360
+ @add_cmd(
361
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
362
+ )
363
+ def _extend_cell_selection_to_top() -> None:
364
+ """Extend the cell selection to the top of the notebook."""
365
+ from euporie.notebook.tabs.notebook import Notebook
366
+
367
+ if isinstance(nb := get_app().tab, Notebook):
368
+ nb.select(0, extend=True)
369
+
370
+
371
+ @add_cmd(
372
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
373
+ )
374
+ def _extend_cell_selection_up() -> None:
375
+ """Extend the cell selection up a cell."""
376
+ from euporie.notebook.tabs.notebook import Notebook
377
+
378
+ if isinstance(nb := get_app().tab, Notebook):
379
+ nb.select(nb.page._selected_slice.start - 1, extend=True)
380
+
381
+
382
+ @add_cmd(
383
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
384
+ )
385
+ def _extend_cell_selection_down() -> None:
386
+ """Extend the cell selection down a cell."""
387
+ from euporie.notebook.tabs.notebook import Notebook
388
+
389
+ if isinstance(nb := get_app().tab, Notebook):
390
+ nb.select(nb.page._selected_slice.start + 1, extend=True)
391
+
392
+
393
+ @add_cmd(
394
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
395
+ )
396
+ def _extend_cell_selection_to_bottom() -> None:
397
+ """Extend the cell selection to the bottom of the notebook."""
398
+ from euporie.notebook.tabs.notebook import Notebook
399
+
400
+ if isinstance(nb := get_app().tab, Notebook):
401
+ nb.select(len(nb.json["cells"]) - 1, extend=True)
402
+
403
+
404
+ @add_cmd(
405
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
406
+ )
407
+ def _move_cells_up() -> None:
408
+ """Move selected cells up."""
409
+ from euporie.notebook.tabs.notebook import Notebook
410
+
411
+ if isinstance(nb := get_app().tab, Notebook):
412
+ nb.move(-1)
413
+
414
+
415
+ @add_cmd(
416
+ filter=notebook_has_focus & ~buffer_has_focus & ~display_has_focus,
417
+ )
418
+ def _move_cells_down() -> None:
419
+ """Move selected cells down."""
420
+ from euporie.notebook.tabs.notebook import Notebook
421
+
422
+ if isinstance(nb := get_app().tab, Notebook):
423
+ nb.move(1)
424
+
425
+
426
+ @add_cmd(
427
+ filter=cell_has_focus & ~buffer_has_focus,
428
+ )
429
+ def _cells_to_markdown() -> None:
430
+ """Change selected cells to markdown cells."""
431
+ from euporie.notebook.tabs.notebook import Notebook
432
+
433
+ if isinstance(nb := get_app().tab, Notebook):
434
+ for cell in nb.cells:
435
+ cell.set_cell_type("markdown", clear=True)
436
+ # Remove unallowed additional properties
437
+ json = cell.json
438
+ json.pop("execution_count", None)
439
+ json.pop("outputs", None)
440
+ cell.run_or_render()
441
+
442
+
443
+ @add_cmd(
444
+ filter=cell_has_focus & ~buffer_has_focus,
445
+ )
446
+ def _cells_to_code() -> None:
447
+ """Change selected cells to code cells."""
448
+ from euporie.notebook.tabs.notebook import Notebook
449
+
450
+ if isinstance(nb := get_app().tab, Notebook):
451
+ for cell in nb.cells:
452
+ cell.set_cell_type("code", clear=False)
453
+
454
+
455
+ @add_cmd(
456
+ filter=cell_has_focus & ~buffer_has_focus,
457
+ )
458
+ def _cells_to_raw() -> None:
459
+ """Change selected cells to raw cells."""
460
+ from euporie.notebook.tabs.notebook import Notebook
461
+
462
+ if isinstance(nb := get_app().tab, Notebook):
463
+ for cell in nb.cells:
464
+ cell.set_cell_type("raw", clear=True)
465
+
466
+
467
+ @add_cmd(
468
+ filter=cell_has_focus & ~buffer_has_focus,
469
+ )
470
+ def _clear_cell_outputs() -> None:
471
+ """Clear the outputs of the selected cells."""
472
+ from euporie.notebook.tabs.notebook import Notebook
473
+
474
+ if isinstance(nb := get_app().tab, Notebook):
475
+ for cell in nb.cells:
476
+ cell.remove_outputs()
477
+
478
+
479
+ @add_cmd(
480
+ filter=cell_has_focus & ~buffer_has_focus,
481
+ )
482
+ def _clear_all_outputs() -> None:
483
+ """Clear the outputs of the selected cells."""
484
+ from euporie.notebook.tabs.notebook import Notebook
485
+
486
+ if isinstance(nb := get_app().tab, Notebook):
487
+ for cell in nb._rendered_cells.values():
488
+ cell.remove_outputs()
489
+
490
+
491
+ @add_cmd(
492
+ filter=cell_has_focus & ~buffer_has_focus,
493
+ title="Expand cell inputs",
494
+ )
495
+ def _show_cell_inputs() -> None:
496
+ """Expand the selected cells' inputs."""
497
+ from euporie.notebook.tabs.notebook import Notebook
498
+
499
+ if isinstance(nb := get_app().tab, Notebook):
500
+ for cell in nb.cells:
501
+ cell.show_input()
502
+
503
+
504
+ @add_cmd(
505
+ filter=cell_has_focus & ~buffer_has_focus,
506
+ title="Collapse cell inputs",
507
+ )
508
+ def _hide_cell_inputs() -> None:
509
+ """Collapse the selected cells' inputs."""
510
+ from euporie.notebook.tabs.notebook import Notebook
511
+
512
+ if isinstance(nb := get_app().tab, Notebook):
513
+ for cell in nb.cells:
514
+ cell.hide_input()
515
+
516
+
517
+ @add_cmd(
518
+ filter=cell_has_focus & ~buffer_has_focus,
519
+ )
520
+ def _toggle_cell_inputs() -> None:
521
+ """Toggle the visibility of the selected cells' inputs."""
522
+ from euporie.notebook.tabs.notebook import Notebook
523
+
524
+ if isinstance(nb := get_app().tab, Notebook):
525
+ for cell in nb.cells:
526
+ cell.toggle_input()
527
+
528
+
529
+ @add_cmd(
530
+ filter=cell_has_focus & ~buffer_has_focus,
531
+ title="Expand cell outputs",
532
+ )
533
+ def _show_cell_outputs() -> None:
534
+ """Expand the selected cells' outputs."""
535
+ from euporie.notebook.tabs.notebook import Notebook
536
+
537
+ if isinstance(nb := get_app().tab, Notebook):
538
+ for cell in nb.cells:
539
+ cell.show_output()
540
+
541
+
542
+ @add_cmd(
543
+ filter=cell_has_focus & ~buffer_has_focus,
544
+ title="Collapse cell outputs",
545
+ )
546
+ def _hide_cell_outputs() -> None:
547
+ """Collapse the selected cells' outputs."""
548
+ from euporie.notebook.tabs.notebook import Notebook
549
+
550
+ if isinstance(nb := get_app().tab, Notebook):
551
+ for cell in nb.cells:
552
+ cell.hide_output()
553
+
554
+
555
+ @add_cmd(
556
+ filter=cell_has_focus & ~buffer_has_focus,
557
+ )
558
+ def _toggle_cell_outputs() -> None:
559
+ """Toggle the visibility of the selected cells' outputs."""
560
+ from euporie.notebook.tabs.notebook import Notebook
561
+
562
+ if isinstance(nb := get_app().tab, Notebook):
563
+ for cell in nb.cells:
564
+ cell.toggle_output()
565
+
566
+
567
+ @add_cmd(
568
+ title="Reformat cells",
569
+ filter=code_cell_selected & cell_has_focus & ~buffer_has_focus & notebook_has_focus,
570
+ )
571
+ def _reformat_cells() -> None:
572
+ """Format the selected code cells."""
573
+ from euporie.notebook.tabs.notebook import Notebook
574
+
575
+ if isinstance(nb := get_app().tab, Notebook):
576
+ for cell in nb.cells:
577
+ if cell.cell_type == "code":
578
+ cell.input_box.reformat()
579
+
580
+
581
+ @add_cmd(aliases=["fmt"], filter=notebook_has_focus & ~buffer_has_focus)
582
+ def _reformat_notebook() -> None:
583
+ """Automatically reformat all code cells in the notebook."""
584
+ from euporie.notebook.tabs.notebook import Notebook
585
+
586
+ if isinstance(nb := get_app().tab, Notebook):
587
+ nb.reformat()
588
+
589
+
590
+ @add_cmd(
591
+ filter=cell_has_focus & ~buffer_has_focus,
592
+ )
593
+ async def _edit_in_external_editor() -> None:
594
+ """Edit cell in $EDITOR."""
595
+ from euporie.notebook.tabs.notebook import Notebook
596
+
597
+ if isinstance(nb := get_app().tab, Notebook):
598
+ await nb.cell.edit_in_editor()
599
+
600
+
601
+ @add_cmd(
602
+ filter=cell_has_focus & buffer_has_focus,
603
+ )
604
+ def _split_cell() -> None:
605
+ """Split the current cell at the cursor position."""
606
+ from euporie.notebook.tabs.notebook import Notebook
607
+
608
+ if isinstance(nb := get_app().tab, Notebook):
609
+ nb.split_cell()
610
+
611
+
612
+ @add_cmd(
613
+ name="edit-previous-cell-vi",
614
+ filter=cell_has_focus
615
+ & buffer_has_focus
616
+ & cursor_on_first_line
617
+ & ~has_completions
618
+ & vi_mode
619
+ & vi_navigation_mode,
620
+ )
621
+ @add_cmd(
622
+ filter=cell_has_focus & buffer_has_focus & cursor_on_first_line & ~has_completions
623
+ )
624
+ def _edit_previous_cell() -> None:
625
+ """Move the cursor up to the previous cell."""
626
+ from euporie.notebook.tabs.notebook import Notebook
627
+
628
+ if isinstance(nb := get_app().tab, Notebook):
629
+ new_index = nb.cell.index - 1
630
+ cells = nb.rendered_cells()
631
+ if 0 <= new_index < len(cells):
632
+ nb.select(index=new_index, position=-1, scroll=True)
633
+
634
+
635
+ @add_cmd(
636
+ name="edit-next-cell-vi",
637
+ filter=cell_has_focus
638
+ & buffer_has_focus
639
+ & cursor_on_last_line
640
+ & ~has_completions
641
+ & vi_mode
642
+ & vi_navigation_mode,
643
+ )
644
+ @add_cmd(
645
+ filter=cell_has_focus & buffer_has_focus & cursor_on_last_line & ~has_completions
646
+ )
647
+ def _edit_next_cell() -> None:
648
+ """Move the cursor down to the next cell."""
649
+ from euporie.notebook.tabs.notebook import Notebook
650
+
651
+ if isinstance(nb := get_app().tab, Notebook):
652
+ new_index = nb.cell.index + 1
653
+ cells = nb.rendered_cells()
654
+ if 0 <= new_index < len(cells):
655
+ nb.select(index=new_index, position=0, scroll=True)
656
+
657
+
658
+ @add_cmd(
659
+ filter=cell_has_focus & ~buffer_has_focus,
660
+ )
661
+ def _scroll_output_left() -> None:
662
+ """Scroll the cell output to the left."""
663
+ from euporie.notebook.tabs.notebook import Notebook
664
+
665
+ if isinstance(nb := get_app().tab, Notebook):
666
+ nb.cell.output_area.scroll_left()
667
+
668
+
669
+ @add_cmd(
670
+ filter=cell_has_focus & ~buffer_has_focus,
671
+ )
672
+ def _scroll_output_right() -> None:
673
+ """Scroll the cell output to the right."""
674
+ from euporie.notebook.tabs.notebook import Notebook
675
+
676
+ if isinstance(nb := get_app().tab, Notebook):
677
+ nb.cell.output_area.scroll_right()
678
+
679
+
680
+ @add_cmd(
681
+ filter=kernel_tab_has_focus & ~buffer_has_focus & ~display_has_focus,
682
+ )
683
+ def _interrupt_kernel() -> None:
684
+ """Interrupt the notebook's kernel."""
685
+ if isinstance(kt := get_app().tab, KernelTab):
686
+ kt.interrupt_kernel()
687
+
688
+
689
+ @add_cmd(
690
+ filter=kernel_tab_has_focus & ~buffer_has_focus & ~display_has_focus,
691
+ )
692
+ def _restart_kernel() -> None:
693
+ """Restart the notebook's kernel."""
694
+ if isinstance(kt := get_app().tab, KernelTab):
695
+ kt.restart_kernel()
696
+
697
+
698
+ @add_cmd(
699
+ filter=kernel_tab_has_focus & ~buffer_has_focus & ~display_has_focus,
700
+ )
701
+ def _restart_kernel_and_clear_all_outputs() -> None:
702
+ """Restart the notebook's kernel and clear all cell output."""
703
+ from euporie.notebook.tabs.notebook import Notebook
704
+
705
+ if isinstance(nb := get_app().tab, Notebook):
706
+ nb.restart_kernel(cb=_clear_all_outputs)
707
+
708
+
709
+ @add_cmd(
710
+ filter=~buffer_has_focus,
711
+ )
712
+ def _notebook_toggle_line_numbers() -> None:
713
+ """Toggle line numbers when a buffer does not have focus."""
714
+ get_cmd("toggle-line-numbers").run()